Code cleaning and better comments.

Gebview: fix issue in export to pcbnew (Track arc shapes are now exported, approximated by segments)
This commit is contained in:
jean-pierre charras 2012-01-13 19:35:46 +01:00
parent 5a9fcf6f11
commit 3383d6c8a5
4 changed files with 69 additions and 96 deletions

View File

@ -326,35 +326,35 @@ void GBR_TO_PCB_EXPORTER::export_segline_copper_item( GERBER_DRAW_ITEM* aGbrItem
void GBR_TO_PCB_EXPORTER::export_segarc_copper_item( GERBER_DRAW_ITEM* aGbrItem, int aLayer ) void GBR_TO_PCB_EXPORTER::export_segarc_copper_item( GERBER_DRAW_ITEM* aGbrItem, int aLayer )
{ {
#if 0 // TODO: does not work in all cases, so needs some work
double a = atan2( (double)( aGbrItem->m_Start.y - aGbrItem->m_ArcCentre.y ), double a = atan2( (double)( aGbrItem->m_Start.y - aGbrItem->m_ArcCentre.y ),
(double)( aGbrItem->m_Start.x - aGbrItem->m_ArcCentre.x ) ); (double)( aGbrItem->m_Start.x - aGbrItem->m_ArcCentre.x ) );
double b = atan2( (double)( aGbrItem->m_End.y - aGbrItem->m_ArcCentre.y ), double b = atan2( (double)( aGbrItem->m_End.y - aGbrItem->m_ArcCentre.y ),
(double)( aGbrItem->m_End.x - aGbrItem->m_ArcCentre.x ) ); (double)( aGbrItem->m_End.x - aGbrItem->m_ArcCentre.x ) );
int arc_angle = wxRound( ( (a - b) / M_PI * 1800.0 ) );
wxPoint start = aGbrItem->m_Start; wxPoint start = aGbrItem->m_Start;
wxPoint end = aGbrItem->m_End; wxPoint end = aGbrItem->m_End;
/* Because Pcbnew does not know arcs in tracks, /* Because Pcbnew does not know arcs in tracks,
* approximate arc by segments (16 segment per 360 deg) * approximate arc by segments (SEG_COUNT__CIRCLE segment per 360 deg)
* The arc is drawn in an anticlockwise direction from the start point to the end point.
*/ */
#define DELTA 3600/16 #define SEG_COUNT_CIRCLE 16
#define DELTA_ANGLE 2*M_PI/SEG_COUNT_CIRCLE
if( arc_angle < 0 ) // calculate the number of segments from a to b.
{ // we want CNT_PER_360 segments fo a circle
NEGATE( arc_angle ); if( a > b )
EXCHG( start, end ); b += 2*M_PI;
}
wxPoint curr_start = start; wxPoint curr_start = start;
for( int rot = DELTA; rot < (arc_angle - DELTA); rot += DELTA ) int ii = 1;
for( double rot = a; rot < (b - DELTA_ANGLE); rot += DELTA_ANGLE, ii++ )
{ {
TRACK * newtrack = new TRACK( m_pcb ); TRACK * newtrack = new TRACK( m_pcb );
newtrack->SetLayer( aLayer ); newtrack->SetLayer( aLayer );
newtrack->m_Start = curr_start; newtrack->m_Start = curr_start;
wxPoint curr_end = start; wxPoint curr_end = start;
RotatePoint( &curr_end, aGbrItem->m_ArcCentre, rot ); RotatePoint( &curr_end, aGbrItem->m_ArcCentre, -(int)(DELTA_ANGLE * ii * 1800 / M_PI) );
newtrack->m_End = curr_end; newtrack->m_End = curr_end;
newtrack->m_Width = aGbrItem->m_Size.x; newtrack->m_Width = aGbrItem->m_Size.x;
// Reverse Y axis: // Reverse Y axis:
@ -376,7 +376,6 @@ void GBR_TO_PCB_EXPORTER::export_segarc_copper_item( GERBER_DRAW_ITEM* aGbrItem,
NEGATE( newtrack->m_End.y ); NEGATE( newtrack->m_End.y );
m_pcb->Add( newtrack ); m_pcb->Add( newtrack );
} }
#endif
} }

View File

@ -320,7 +320,7 @@ int BOARD::ClipAreaPolygon( PICKED_ITEMS_LIST * aNewZonesList,
//** if( test == 1 ) //** if( test == 1 )
{ {
std::vector<CPolyLine*>* pa = new std::vector<CPolyLine*>; std::vector<CPolyLine*>* pa = new std::vector<CPolyLine*>;
curr_polygon->Undraw(); curr_polygon->UnHatch();
int n_poly = aCurrArea->m_Poly->NormalizeAreaOutlines( pa, bRetainArcs ); int n_poly = aCurrArea->m_Poly->NormalizeAreaOutlines( pa, bRetainArcs );
// i.e if clipping has created some polygons, we must add these new copper areas. // i.e if clipping has created some polygons, we must add these new copper areas.
@ -339,12 +339,12 @@ int BOARD::ClipAreaPolygon( PICKED_ITEMS_LIST * aNewZonesList,
// and replace it with a poly from NormalizeAreaOutlines // and replace it with a poly from NormalizeAreaOutlines
delete NewArea->m_Poly; delete NewArea->m_Poly;
NewArea->m_Poly = new_p; NewArea->m_Poly = new_p;
NewArea->m_Poly->Draw(); NewArea->m_Poly->Hatch();
NewArea->utility = 1; NewArea->utility = 1;
} }
} }
curr_polygon->Draw(); curr_polygon->Hatch();
delete pa; delete pa;
} }
@ -901,7 +901,7 @@ int BOARD::CombineAreas( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_r
area_ref->utility = 1; area_ref->utility = 1;
area_ref->m_Poly->RestoreArcs( &arc_array1 ); area_ref->m_Poly->RestoreArcs( &arc_array1 );
area_ref->m_Poly->RestoreArcs( &arc_array2 ); area_ref->m_Poly->RestoreArcs( &arc_array2 );
area_ref->m_Poly->Draw(); area_ref->m_Poly->Hatch();
delete booleng; delete booleng;
return 1; return 1;
} }

View File

@ -5,12 +5,12 @@
// //
#include <math.h> #include <math.h>
#include <vector> #include <vector>
#include <algorithm>
#include "fctsys.h" #include "fctsys.h"
#include "config.h" #include "config.h" // to define KICAD_NANOMETRE
#include "PolyLine.h" #include "PolyLine.h"
#include "gr_basic.h"
#include "bezier_curves.h" #include "bezier_curves.h"
#include "polygon_test_point_inside.h" #include "polygon_test_point_inside.h"
@ -44,7 +44,7 @@ CPolyLine::CPolyLine()
// //
CPolyLine::~CPolyLine() CPolyLine::~CPolyLine()
{ {
Undraw(); UnHatch();
if( m_Kbool_Poly_Engine ) if( m_Kbool_Poly_Engine )
delete m_Kbool_Poly_Engine; delete m_Kbool_Poly_Engine;
} }
@ -81,7 +81,7 @@ int CPolyLine::NormalizeWithKbool( std::vector<CPolyLine*> * aExtraPolyList, boo
else else
MakeKboolPoly( -1, -1, NULL ); MakeKboolPoly( -1, -1, NULL );
Undraw(); UnHatch();
/* now, recreate polys /* now, recreate polys
* if more than one outside contour are found, extra CPolyLines will be created * if more than one outside contour are found, extra CPolyLines will be created
@ -649,7 +649,7 @@ int CPolyLine::RestoreArcs( std::vector<CArc> * arc_array, std::vector<CPolyLine
poly = this; poly = this;
else else
poly = (*pa)[ip - 1]; poly = (*pa)[ip - 1];
poly->Undraw(); poly->UnHatch();
for( int ic = 0; ic<poly->GetNumCorners(); ic++ ) for( int ic = 0; ic<poly->GetNumCorners(); ic++ )
poly->SetUtility( ic, 0 ); poly->SetUtility( ic, 0 );
@ -805,7 +805,7 @@ void CPolyLine::Start( int layer, int x, int y, int hatch )
// //
void CPolyLine::AppendCorner( int x, int y, int style, bool bDraw ) void CPolyLine::AppendCorner( int x, int y, int style, bool bDraw )
{ {
Undraw(); UnHatch();
CPolyPt poly_pt( x, y ); CPolyPt poly_pt( x, y );
poly_pt.end_contour = FALSE; poly_pt.end_contour = FALSE;
@ -815,7 +815,7 @@ void CPolyLine::AppendCorner( int x, int y, int style, bool bDraw )
if( corner.size() > 0 && !corner[corner.size() - 1].end_contour ) if( corner.size() > 0 && !corner[corner.size() - 1].end_contour )
side_style[corner.size() - 1] = style; side_style[corner.size() - 1] = style;
if( bDraw ) if( bDraw )
Draw(); Hatch();
} }
@ -827,11 +827,11 @@ void CPolyLine::Close( int style, bool bDraw )
{ {
wxASSERT( 0 ); wxASSERT( 0 );
} }
Undraw(); UnHatch();
side_style[corner.size() - 1] = style; side_style[corner.size() - 1] = style;
corner[corner.size() - 1].end_contour = TRUE; corner[corner.size() - 1].end_contour = TRUE;
if( bDraw ) if( bDraw )
Draw(); Hatch();
} }
@ -839,10 +839,10 @@ void CPolyLine::Close( int style, bool bDraw )
// //
void CPolyLine::MoveCorner( int ic, int x, int y ) void CPolyLine::MoveCorner( int ic, int x, int y )
{ {
Undraw(); UnHatch();
corner[ic].x = x; corner[ic].x = x;
corner[ic].y = y; corner[ic].y = y;
Draw(); Hatch();
} }
@ -850,7 +850,7 @@ void CPolyLine::MoveCorner( int ic, int x, int y )
// //
void CPolyLine::DeleteCorner( int ic, bool bDraw ) void CPolyLine::DeleteCorner( int ic, bool bDraw )
{ {
Undraw(); UnHatch();
int icont = GetContour( ic ); int icont = GetContour( ic );
int istart = GetContourStart( icont ); int istart = GetContourStart( icont );
int iend = GetContourEnd( icont ); int iend = GetContourEnd( icont );
@ -878,7 +878,7 @@ void CPolyLine::DeleteCorner( int ic, bool bDraw )
RemoveContour( icont ); RemoveContour( icont );
} }
if( bDraw ) if( bDraw )
Draw(); Hatch();
} }
@ -892,7 +892,7 @@ void CPolyLine::RemoveContour( int icont )
* remove a contour only if there is more than 1 contour * remove a contour only if there is more than 1 contour
*/ */
{ {
Undraw(); UnHatch();
int istart = GetContourStart( icont ); int istart = GetContourStart( icont );
int iend = GetContourEnd( icont ); int iend = GetContourEnd( icont );
@ -916,7 +916,7 @@ void CPolyLine::RemoveContour( int icont )
side_style.erase( side_style.begin() + ic ); side_style.erase( side_style.begin() + ic );
} }
} }
Draw(); Hatch();
} }
@ -1140,7 +1140,7 @@ void CPolyLine::RemoveAllContours( void )
*/ */
void CPolyLine::InsertCorner( int ic, int x, int y ) void CPolyLine::InsertCorner( int ic, int x, int y )
{ {
Undraw(); UnHatch();
if( (unsigned) (ic) >= corner.size() ) if( (unsigned) (ic) >= corner.size() )
{ {
corner.push_back( CPolyPt( x, y ) ); corner.push_back( CPolyPt( x, y ) );
@ -1160,31 +1160,15 @@ void CPolyLine::InsertCorner( int ic, int x, int y )
corner[ic].end_contour = FALSE; corner[ic].end_contour = FALSE;
} }
} }
Draw(); Hatch();
} }
// undraw polyline by removing all graphic elements from display list // undraw polyline by removing all graphic elements from display list
// //
void CPolyLine::Undraw() void CPolyLine::UnHatch()
{ {
m_HatchLines.clear(); m_HatchLines.clear();
bDrawn = FALSE;
}
// draw polyline by adding all graphics to display list
// if side style is ARC_CW or ARC_CCW but endpoints are not angled,
// convert to STRAIGHT
//
void CPolyLine::Draw()
{
// first, undraw if necessary
if( bDrawn )
Undraw();
Hatch();
bDrawn = TRUE;
} }
@ -1226,10 +1210,10 @@ CRect CPolyLine::GetCornerBounds()
r.right = r.top = INT_MIN; r.right = r.top = INT_MIN;
for( unsigned i = 0; i<corner.size(); i++ ) for( unsigned i = 0; i<corner.size(); i++ )
{ {
r.left = MIN( r.left, corner[i].x ); r.left = min( r.left, corner[i].x );
r.right = MAX( r.right, corner[i].x ); r.right = max( r.right, corner[i].x );
r.bottom = MIN( r.bottom, corner[i].y ); r.bottom = min( r.bottom, corner[i].y );
r.top = MAX( r.top, corner[i].y ); r.top = max( r.top, corner[i].y );
} }
return r; return r;
@ -1355,7 +1339,7 @@ int CPolyLine::GetContourSize( int icont )
void CPolyLine::SetSideStyle( int is, int style ) void CPolyLine::SetSideStyle( int is, int style )
{ {
Undraw(); UnHatch();
CPoint p1, p2; CPoint p1, p2;
if( is == (int) (corner.size() - 1) ) if( is == (int) (corner.size() - 1) )
{ {
@ -1375,7 +1359,7 @@ void CPolyLine::SetSideStyle( int is, int style )
side_style[is] = STRAIGHT; side_style[is] = STRAIGHT;
else else
side_style[is] = style; side_style[is] = style;
Draw(); Hatch();
} }
@ -1394,8 +1378,13 @@ int CPolyLine::GetClosed()
} }
// draw hatch lines // Creates hatch lines inside the outline of the complex polygon
// //
// sort function used in ::Hatch to sort points by descending CPoint.x values
bool sort_ends_by_descending_X( const CPoint& ref, const CPoint& tst )
{
return tst.x < ref.x;
}
void CPolyLine::Hatch() void CPolyLine::Hatch()
{ {
m_HatchLines.clear(); m_HatchLines.clear();
@ -1468,7 +1457,8 @@ void CPolyLine::Hatch()
// get intersection points for this hatch line // get intersection points for this hatch line
// Note: because we should have an even number of intersections with the // Note: because we should have an even number of intersections with the
// current hatch line and the zone outline, if we have an odd count if found // current hatch line and the zone outline (a closed polygon,
// or a set of closed polygons), if an odd count is found
// we skip this line (should not occur) // we skip this line (should not occur)
pointbuffer.clear(); pointbuffer.clear();
int i_start_contour = 0; int i_start_contour = 0;
@ -1512,34 +1502,19 @@ void CPolyLine::Hatch()
} }
// ensure we have found an even intersection points count // ensure we have found an even intersection points count
// because a segment has 2 points. // because intersections are the ends of segments
// inside the polygon(s) and a segment has 2 ends.
// if not, this is a strange case (a bug ?) so skip this hatch // if not, this is a strange case (a bug ?) so skip this hatch
if( pointbuffer.size() % 2 != 0 ) if( pointbuffer.size() % 2 != 0 )
continue; continue;
// sort points in order of descending x (if more than 2) // sort points in order of descending x (if more than 2) to
// ensure the starting point and the ending point of the same segment
// are stored one just after the other.
if( pointbuffer.size() > 2 ) if( pointbuffer.size() > 2 )
{ sort( pointbuffer.begin(), pointbuffer.end(), sort_ends_by_descending_X );
for( unsigned istart = 0; istart < (pointbuffer.size() - 1); istart++ )
{
int max_x = INT_MIN;
int imax = INT_MIN;
for( unsigned i = istart; i < pointbuffer.size(); i++ )
{
if( pointbuffer[i].x > max_x )
{
max_x = pointbuffer[i].x;
imax = i;
}
}
CPoint temp = pointbuffer[istart]; // creates lines or short segments inside the complex polygon
pointbuffer[istart] = pointbuffer[imax];
pointbuffer[imax] = temp;
}
}
// creates lines
for( unsigned ip = 0; ip < pointbuffer.size(); ip += 2 ) for( unsigned ip = 0; ip < pointbuffer.size(); ip += 2 )
{ {
double dx = pointbuffer[ip + 1].x - pointbuffer[ip].x; double dx = pointbuffer[ip + 1].x - pointbuffer[ip].x;
@ -1609,7 +1584,7 @@ bool CPolyLine::TestPointInside( int px, int py )
// //
void CPolyLine::Copy( CPolyLine* src ) void CPolyLine::Copy( CPolyLine* src )
{ {
Undraw(); UnHatch();
m_HatchStyle = src->m_HatchStyle; m_HatchStyle = src->m_HatchStyle;
// copy corners, using vector copy // copy corners, using vector copy
corner = src->corner; corner = src->corner;
@ -1636,19 +1611,19 @@ bool CPolyLine::IsCutoutContour( int icont )
void CPolyLine::MoveOrigin( int x_off, int y_off ) void CPolyLine::MoveOrigin( int x_off, int y_off )
{ {
Undraw(); UnHatch();
for( int ic = 0; ic < GetNumCorners(); ic++ ) for( int ic = 0; ic < GetNumCorners(); ic++ )
{ {
SetX( ic, GetX( ic ) + x_off ); SetX( ic, GetX( ic ) + x_off );
SetY( ic, GetY( ic ) + y_off ); SetY( ic, GetY( ic ) + y_off );
} }
Draw(); Hatch();
} }
// Set various parameters: // Set various parameters:
// the calling function should Undraw() before calling them, // the calling function should UnHatch() before calling them,
// and Draw() after // and Draw() after
// //
void CPolyLine::SetX( int ic, int x ) void CPolyLine::SetX( int ic, int x )

View File

@ -140,10 +140,11 @@ public:
void RemoveAllContours( void ); void RemoveAllContours( void );
// drawing functions // Remove or create hatch
void Undraw(); void UnHatch();
void Draw();
void Hatch(); void Hatch();
// Transform functions
void MoveOrigin( int x_off, int y_off ); void MoveOrigin( int x_off, int y_off );
// misc. functions // misc. functions
@ -174,7 +175,7 @@ public:
int GetSideStyle( int is ); int GetSideStyle( int is );
int GetHatchStyle() { return m_HatchStyle; } int GetHatchStyle() { return m_HatchStyle; }
void SetHatch( int hatch ) { Undraw(); m_HatchStyle = hatch; Draw(); }; void SetHatch( int hatch ) { m_HatchStyle = hatch; Hatch(); };
void SetX( int ic, int x ); void SetX( int ic, int x );
void SetY( int ic, int y ); void SetY( int ic, int y );
void SetEndContour( int ic, bool end_contour ); void SetEndContour( int ic, bool end_contour );
@ -246,24 +247,22 @@ public:
*/ */
void FreeKboolEngine( ) { delete m_Kbool_Poly_Engine; m_Kbool_Poly_Engine = NULL; } void FreeKboolEngine( ) { delete m_Kbool_Poly_Engine; m_Kbool_Poly_Engine = NULL; }
// Bezier Support
void AppendBezier(int x1, int y1, int x2, int y2, int x3, int y3);
void AppendBezier(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4);
private: private:
int m_layer; // layer to draw on int m_layer; // layer to draw on
int m_Width; // lines width when drawing. Provided but not really used int m_Width; // lines width when drawing. Provided but not really used
int utility; int utility;
Bool_Engine* m_Kbool_Poly_Engine; // polygons set in kbool engine data
public: public:
std::vector <CPolyPt> corner; // array of points for corners std::vector <CPolyPt> corner; // array of points for corners
std::vector <int> side_style; // array of styles for sides std::vector <int> side_style; // array of styles for sides
int m_HatchStyle; // hatch style, see enum above int m_HatchStyle; // hatch style, see enum above
std::vector <CSegment> m_HatchLines; // hatch lines std::vector <CSegment> m_HatchLines; // hatch lines
private:
Bool_Engine* m_Kbool_Poly_Engine; // polygons set in kbool engine data
bool bDrawn;
// Bezier Support
public:
void AppendBezier(int x1, int y1, int x2, int y2, int x3, int y3);
void AppendBezier(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4);
}; };
#endif // #ifndef POLYLINE_H #endif // #ifndef POLYLINE_H