From ef5f1b9e6b4786424ff132cbd5d011e21c7ce24e Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Wed, 25 Jul 2012 09:36:56 +0200 Subject: [PATCH] Start work on a better support of polygons in Kicad (code cleaning). Some coding style policy fix. --- 3d-viewer/3d_draw.cpp | 4 +- pcb_calculator/bitmaps/Thumbs.db | Bin 36864 -> 0 bytes ...board_items_to_polygon_shape_transform.cpp | 12 +- pcbnew/class_zone.cpp | 50 +-- pcbnew/kicad_plugin.cpp | 2 +- pcbnew/legacy_plugin.cpp | 6 +- pcbnew/polygons_defs.h | 51 ++- pcbnew/specctra_export.cpp | 28 +- pcbnew/zone_filling_algorithm.cpp | 2 +- ...nvert_brd_items_to_polygons_with_Boost.cpp | 83 +++-- pcbnew/zones_functions_for_undo_redo.cpp | 2 +- pcbnew/zones_test_and_combine_areas.cpp | 221 +++++++------ polygon/PolyLine.cpp | 306 +++++++++--------- polygon/PolyLine.h | 44 +-- 14 files changed, 423 insertions(+), 388 deletions(-) delete mode 100644 pcb_calculator/bitmaps/Thumbs.db diff --git a/3d-viewer/3d_draw.cpp b/3d-viewer/3d_draw.cpp index 0c0a6b05d8..36e2bcea1c 100644 --- a/3d-viewer/3d_draw.cpp +++ b/3d-viewer/3d_draw.cpp @@ -305,7 +305,7 @@ GLuint EDA_3D_CANVAS::CreateDrawGL_List() { CPolyPt* endcorner = &polysList[ic]; - if( begincorner->utility == 0 ) + if( begincorner->m_utility == 0 ) { // Draw only basic outlines, not extra segments dummysegment.m_Start.x = begincorner->x; @@ -318,7 +318,7 @@ GLuint EDA_3D_CANVAS::CreateDrawGL_List() if( (endcorner->end_contour) || (ic == imax) ) { // the last corner of a filled area is found: draw it - if( endcorner->utility == 0 ) + if( endcorner->m_utility == 0 ) { // Draw only basic outlines, not extra segments dummysegment.m_Start.x = endcorner->x; diff --git a/pcb_calculator/bitmaps/Thumbs.db b/pcb_calculator/bitmaps/Thumbs.db deleted file mode 100644 index a26a0e272b0bc90cae3713fe050031b9552c1d2e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36864 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 diff --git a/pcbnew/board_items_to_polygon_shape_transform.cpp b/pcbnew/board_items_to_polygon_shape_transform.cpp index 10d03071a3..47a8bbd736 100644 --- a/pcbnew/board_items_to_polygon_shape_transform.cpp +++ b/pcbnew/board_items_to_polygon_shape_transform.cpp @@ -167,19 +167,19 @@ void ZONE_CONTAINER::TransformShapeWithClearanceToPolygon( std::vector // Calculate the polygon with clearance and holes // holes are linked to the main outline, so only one polygon should be created. - KPolygonSet polyset_zone_solid_areas; - std::vector cornerslist; + KI_POLYGON_SET polyset_zone_solid_areas; + std::vector cornerslist; unsigned ic = 0; unsigned corners_count = zoneOutines.size(); while( ic < corners_count ) { cornerslist.clear(); - KPolygon poly; + KI_POLYGON poly; { for( ; ic < corners_count; ic++ ) { CPolyPt* corner = &zoneOutines[ic]; - cornerslist.push_back( KPolyPoint( corner->x, corner->y ) ); + cornerslist.push_back( KI_POLY_POINT( corner->x, corner->y ) ); if( corner->end_contour ) { ic++; @@ -197,12 +197,12 @@ void ZONE_CONTAINER::TransformShapeWithClearanceToPolygon( std::vector // Put the resultng polygon in buffer for( unsigned ii = 0; ii < polyset_zone_solid_areas.size(); ii++ ) { - KPolygon& poly = polyset_zone_solid_areas[ii]; + KI_POLYGON& poly = polyset_zone_solid_areas[ii]; CPolyPt corner( 0, 0, false ); for( unsigned jj = 0; jj < poly.size(); jj++ ) { - KPolyPoint point = *(poly.begin() + jj); + KI_POLY_POINT point = *(poly.begin() + jj); corner.x = point.x(); corner.y = point.y(); corner.end_contour = false; diff --git a/pcbnew/class_zone.cpp b/pcbnew/class_zone.cpp index d67142aaa8..d79c1e4ffc 100644 --- a/pcbnew/class_zone.cpp +++ b/pcbnew/class_zone.cpp @@ -210,7 +210,7 @@ void ZONE_CONTAINER::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, int aDrawMode, const { seg_start = GetCornerPosition( ic ) + offset; - if( m_Poly->corner[ic].end_contour == false && ic < GetNumCorners() - 1 ) + if( m_Poly->m_CornersList[ic].end_contour == false && ic < GetNumCorners() - 1 ) { seg_end = GetCornerPosition( ic + 1 ) + offset; } @@ -306,7 +306,7 @@ void ZONE_CONTAINER::DrawFilledArea( EDA_DRAW_PANEL* panel, CornersBuffer.push_back( coord ); - CornersTypeBuffer.push_back( (char) corner->utility ); + CornersTypeBuffer.push_back( (char) corner->m_utility ); if( (corner->end_contour) || (ic == imax) ) // the last corner of a filled area is found: draw it { @@ -432,13 +432,13 @@ void ZONE_CONTAINER::DrawWhileCreateOutline( EDA_DRAW_PANEL* panel, wxDC* DC, in int yi = GetCornerPosition( ic ).y; int xf, yf; - if( m_Poly->corner[ic].end_contour == false && ic < icmax ) + if( m_Poly->m_CornersList[ic].end_contour == false && ic < icmax ) { is_close_segment = false; xf = GetCornerPosition( ic + 1 ).x; yf = GetCornerPosition( ic + 1 ).y; - if( (m_Poly->corner[ic + 1].end_contour) || (ic == icmax - 1) ) + if( (m_Poly->m_CornersList[ic + 1].end_contour) || (ic == icmax - 1) ) current_gr_mode = GR_XOR; else current_gr_mode = draw_mode; @@ -507,12 +507,12 @@ bool ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos ) int min_dist = MIN_DIST_IN_MILS*IU_PER_MILS; wxPoint delta; - unsigned lim = m_Poly->corner.size(); + unsigned lim = m_Poly->m_CornersList.size(); for( unsigned item_pos = 0; item_pos < lim; item_pos++ ) { - delta.x = refPos.x - m_Poly->corner[item_pos].x; - delta.y = refPos.y - m_Poly->corner[item_pos].y; + delta.x = refPos.x - m_Poly->m_CornersList[item_pos].x; + delta.y = refPos.y - m_Poly->m_CornersList[item_pos].y; // Calculate a distance: int dist = MAX( abs( delta.x ), abs( delta.y ) ); @@ -530,7 +530,7 @@ bool ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos ) bool ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos ) { - unsigned lim = m_Poly->corner.size(); + unsigned lim = m_Poly->m_CornersList.size(); m_CornerSelection = -1; // Set to not found @@ -547,7 +547,7 @@ bool ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos ) * the last segment of the current outline starts at current corner, and ends * at the first corner of the outline */ - if( m_Poly->corner[item_pos].end_contour || end_segm >= lim ) + if( m_Poly->m_CornersList[item_pos].end_contour || end_segm >= lim ) { unsigned tmp = first_corner_pos; first_corner_pos = end_segm; // first_corner_pos is now the beginning of the next outline @@ -557,10 +557,10 @@ bool ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos ) /* test the dist between segment and ref point */ int dist = (int) GetPointToLineSegmentDistance( refPos.x, refPos.y, - m_Poly->corner[item_pos].x, - m_Poly->corner[item_pos].y, - m_Poly->corner[end_segm].x, - m_Poly->corner[end_segm].y ); + m_Poly->m_CornersList[item_pos].x, + m_Poly->m_CornersList[item_pos].y, + m_Poly->m_CornersList[end_segm].x, + m_Poly->m_CornersList[end_segm].y ); if( dist < min_dist ) { @@ -703,7 +703,7 @@ void ZONE_CONTAINER::DisplayInfo( EDA_DRAW_FRAME* frame ) msg = board->GetLayerName( m_Layer ); frame->AppendMsgPanel( _( "Layer" ), msg, BROWN ); - msg.Printf( wxT( "%d" ), (int) m_Poly->corner.size() ); + msg.Printf( wxT( "%d" ), (int) m_Poly->m_CornersList.size() ); frame->AppendMsgPanel( _( "Corners" ), msg, BLUE ); if( m_FillMode ) @@ -730,7 +730,7 @@ void ZONE_CONTAINER::DisplayInfo( EDA_DRAW_FRAME* frame ) void ZONE_CONTAINER::Move( const wxPoint& offset ) { /* move outlines */ - for( unsigned ii = 0; ii < m_Poly->corner.size(); ii++ ) + for( unsigned ii = 0; ii < m_Poly->m_CornersList.size(); ii++ ) { SetCornerPosition( ii, GetCornerPosition( ii ) + offset ); } @@ -761,7 +761,7 @@ void ZONE_CONTAINER::MoveEdge( const wxPoint& offset ) SetCornerPosition( ii, GetCornerPosition( ii ) + offset ); // Move the end point of the selected edge: - if( m_Poly->corner[ii].end_contour || ii == GetNumCorners() - 1 ) + if( m_Poly->m_CornersList[ii].end_contour || ii == GetNumCorners() - 1 ) { int icont = m_Poly->GetContour( ii ); ii = m_Poly->GetContourStart( icont ); @@ -781,13 +781,13 @@ void ZONE_CONTAINER::Rotate( const wxPoint& centre, double angle ) { wxPoint pos; - for( unsigned ii = 0; ii < m_Poly->corner.size(); ii++ ) + for( unsigned ii = 0; ii < m_Poly->m_CornersList.size(); ii++ ) { - pos.x = m_Poly->corner[ii].x; - pos.y = m_Poly->corner[ii].y; + pos.x = m_Poly->m_CornersList[ii].x; + pos.y = m_Poly->m_CornersList[ii].y; RotatePoint( &pos, centre, angle ); - m_Poly->corner[ii].x = pos.x; - m_Poly->corner[ii].y = pos.y; + m_Poly->m_CornersList[ii].x = pos.x; + m_Poly->m_CornersList[ii].y = pos.y; } m_Poly->Hatch(); @@ -820,11 +820,11 @@ void ZONE_CONTAINER::Flip( const wxPoint& aCentre ) void ZONE_CONTAINER::Mirror( const wxPoint& mirror_ref ) { - for( unsigned ii = 0; ii < m_Poly->corner.size(); ii++ ) + for( unsigned ii = 0; ii < m_Poly->m_CornersList.size(); ii++ ) { - m_Poly->corner[ii].y -= mirror_ref.y; - NEGATE( m_Poly->corner[ii].y ); - m_Poly->corner[ii].y += mirror_ref.y; + m_Poly->m_CornersList[ii].y -= mirror_ref.y; + NEGATE( m_Poly->m_CornersList[ii].y ); + m_Poly->m_CornersList[ii].y += mirror_ref.y; } m_Poly->Hatch(); diff --git a/pcbnew/kicad_plugin.cpp b/pcbnew/kicad_plugin.cpp index 9387c24cc3..0c14255698 100644 --- a/pcbnew/kicad_plugin.cpp +++ b/pcbnew/kicad_plugin.cpp @@ -1059,7 +1059,7 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const m_out->Print( 0, ")\n" ); - const std::vector< CPolyPt >& cv = aZone->m_Poly->corner; + const std::vector< CPolyPt >& cv = aZone->m_Poly->m_CornersList; int newLine = 0; if( cv.size() ) diff --git a/pcbnew/legacy_plugin.cpp b/pcbnew/legacy_plugin.cpp index 028b2f9248..77618154a4 100644 --- a/pcbnew/legacy_plugin.cpp +++ b/pcbnew/legacy_plugin.cpp @@ -3609,7 +3609,7 @@ void LEGACY_PLUGIN::saveZONE_CONTAINER( const ZONE_CONTAINER* me ) const typedef std::vector< CPolyPt > CPOLY_PTS; // Save the corner list - const CPOLY_PTS& cv = me->m_Poly->corner; + const CPOLY_PTS& cv = me->m_Poly->m_CornersList; for( CPOLY_PTS::const_iterator it = cv.begin(); it != cv.end(); ++it ) { fprintf( m_fp, "ZCorner %s %d\n", @@ -3623,12 +3623,12 @@ void LEGACY_PLUGIN::saveZONE_CONTAINER( const ZONE_CONTAINER* me ) const { fprintf( m_fp, "$POLYSCORNERS\n" ); - for( CPOLY_PTS::const_iterator it = fv.begin(); it != fv.end(); ++it ) + for( CPOLY_PTS::const_iterator it = fv.begin(); it != fv.end(); ++it ) { fprintf( m_fp, "%s %d %d\n", fmtBIUPair( it->x, it->y ).c_str(), it->end_contour, - it->utility ); + it->m_utility ); } fprintf( m_fp, "$endPOLYSCORNERS\n" ); diff --git a/pcbnew/polygons_defs.h b/pcbnew/polygons_defs.h index 3d7640c8d8..f9055c1cc6 100644 --- a/pcbnew/polygons_defs.h +++ b/pcbnew/polygons_defs.h @@ -12,10 +12,55 @@ namespace bpl = boost::polygon; // bpl = boost polygon library using namespace bpl::operators; // +, -, =, ... +// Definitions needed by boost::polygon typedef int coordinate_type; -typedef bpl::polygon_data KPolygon; -typedef std::vector KPolygonSet; +/** + * KI_POLYGON defines a single polygon ( boost::polygon_data type. + * When holes are created in a KPolygon, they are + * linked to main outline by overlapping segments, + * so there is always one polygon and one list of corners + * coordinates are int + */ +typedef bpl::polygon_data KI_POLYGON; + +/** + * KI_POLYGON_SET defines a set of single KI_POLYGON. + * A KI_POLYGON_SET is used to store a set of polygons + * when performing operations between 2 polygons + * or 2 sets of polygons + * The result of operations like and, xor... between 2 polygons + * is always stored in a KI_POLYGON_SET, because these operations + * can create many polygons + */ +typedef std::vector KI_POLYGON_SET; + +/** + * KI_POLY_POINT defines a point for boost::polygon. + * KI_POLY_POINT store x and y coordinates (int) + */ +typedef bpl::point_data KI_POLY_POINT; + +/** + * KI_POLYGON_WITH_HOLES defines a single polygon with holes + * When holes are created in a KI_POLYGON_WITH_HOLES, they are + * stored as separate single polygons, + * KI_POLYGON_WITH_HOLES store always one polygon for the external outline + * and one list of polygons (holes) which can be empty + */ +typedef bpl::polygon_with_holes_data KI_POLYGON_WITH_HOLES; + +/** + * KI_POLYGON_WITH_HOLES_SET defines a set of KI_POLYGON_WITH_HOLES. + * A KI_POLYGON_WITH_HOLES_SET is used to store a set of polygons with holes + * when performing operations between 2 polygons + * or 2 sets of polygons with holes + * The result of operations like and, xor... between 2 polygons with holes + * is always stored in a KI_POLYGON_WITH_HOLES_SET, because these operations + * can create many separate polygons with holespolygons + */ + +typedef std::vector KI_POLYGON_WITH_HOLES_SET; + -typedef bpl::point_data KPolyPoint; #endif // #ifndef _POLYGONS_DEFS_H_ diff --git a/pcbnew/specctra_export.cpp b/pcbnew/specctra_export.cpp index be1a66e462..1a51b76aca 100644 --- a/pcbnew/specctra_export.cpp +++ b/pcbnew/specctra_export.cpp @@ -1178,16 +1178,16 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR ) mainPolygon->layer_id = layerIds[ kicadLayer2pcb[ item->GetLayer() ] ]; - int count = item->m_Poly->corner.size(); + int count = item->m_Poly->m_CornersList.size(); int ndx = 0; // used in 2 for() loops below for( ; ndxm_Poly->corner[ndx].x, - item->m_Poly->corner[ndx].y ); + wxPoint point( item->m_Poly->m_CornersList[ndx].x, + item->m_Poly->m_CornersList[ndx].y ); mainPolygon->AppendPoint( mapPt(point) ); // this was the end of the main polygon - if( item->m_Poly->corner[ndx].end_contour ) + if( item->m_Poly->m_CornersList[ndx].end_contour ) break; } @@ -1197,7 +1197,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR ) // handle the cutouts for( ++ndx; ndxm_Poly->corner[ndx-1].end_contour ) + if( item->m_Poly->m_CornersList[ndx-1].end_contour ) { window = new WINDOW( plane ); plane->AddWindow( window ); @@ -1211,8 +1211,8 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR ) wxASSERT( window ); wxASSERT( cutout ); - wxPoint point(item->m_Poly->corner[ndx].x, - item->m_Poly->corner[ndx].y ); + wxPoint point(item->m_Poly->m_CornersList[ndx].x, + item->m_Poly->m_CornersList[ndx].y ); cutout->AppendPoint( mapPt(point) ); } } @@ -1253,16 +1253,16 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR ) mainPolygon->layer_id = layerIds[ kicadLayer2pcb[ item->GetLayer() ] ]; - int count = item->m_Poly->corner.size(); + int count = item->m_Poly->m_CornersList.size(); int ndx = 0; // used in 2 for() loops below for( ; ndxm_Poly->corner[ndx].x, - item->m_Poly->corner[ndx].y ); + wxPoint point( item->m_Poly->m_CornersList[ndx].x, + item->m_Poly->m_CornersList[ndx].y ); mainPolygon->AppendPoint( mapPt(point) ); // this was the end of the main polygon - if( item->m_Poly->corner[ndx].end_contour ) + if( item->m_Poly->m_CornersList[ndx].end_contour ) break; } @@ -1272,7 +1272,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR ) // handle the cutouts for( ++ndx; ndxm_Poly->corner[ndx-1].end_contour ) + if( item->m_Poly->m_CornersList[ndx-1].end_contour ) { window = new WINDOW( keepout ); keepout->AddWindow( window ); @@ -1286,8 +1286,8 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR ) wxASSERT( window ); wxASSERT( cutout ); - wxPoint point(item->m_Poly->corner[ndx].x, - item->m_Poly->corner[ndx].y ); + wxPoint point(item->m_Poly->m_CornersList[ndx].x, + item->m_Poly->m_CornersList[ndx].y ); cutout->AppendPoint( mapPt(point) ); } } diff --git a/pcbnew/zone_filling_algorithm.cpp b/pcbnew/zone_filling_algorithm.cpp index 539d6a0f0c..e829c37f96 100644 --- a/pcbnew/zone_filling_algorithm.cpp +++ b/pcbnew/zone_filling_algorithm.cpp @@ -188,7 +188,7 @@ int ZONE_CONTAINER::Fill_Zone_Areas_With_Segments() x_coordinates.clear(); for( ics = istart, ice = iend; ics <= iend; ice = ics, ics++ ) { - if ( m_FilledPolysList[ice].utility ) + if ( m_FilledPolysList[ice].m_utility ) continue; int seg_startX = m_FilledPolysList[ics].x; int seg_startY = m_FilledPolysList[ics].y; diff --git a/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp b/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp index 487ce0110d..48e1e418b5 100644 --- a/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp +++ b/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp @@ -81,14 +81,14 @@ extern void CreateThermalReliefPadPolygon( std::vector& aCornerBuffer, int aThermalRot ); // Local Functions: helper function to calculate solid areas -static void AddPolygonCornersToKPolygonList( std::vector & aCornersBuffer, - KPolygonSet& aKPolyList ); +static void AddPolygonCornersToKiPolygonList( std::vector & aCornersBuffer, + KI_POLYGON_SET& aKiPolyList ); -static int CopyPolygonsFromKPolygonListToFilledPolysList( ZONE_CONTAINER* aZone, - KPolygonSet& aKPolyList ); +static int CopyPolygonsFromKiPolygonListToFilledPolysList( ZONE_CONTAINER* aZone, + KI_POLYGON_SET& aKiPolyList ); -static int CopyPolygonsFromFilledPolysListTotKPolygonList( ZONE_CONTAINER* aZone, - KPolygonSet& aKPolyList ); +static int CopyPolygonsFromFilledPolysListToKiPolygonList( ZONE_CONTAINER* aZone, + KI_POLYGON_SET& aKiPolyList ); // Local Variables: @@ -148,8 +148,8 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) */ s_Correction = 1.0 / cos( 3.14159265 / s_CircleToSegmentsCount ); - // This KPolygonSet is the area(s) to fill, with m_ZoneMinThickness/2 - KPolygonSet polyset_zone_solid_areas; + // This KI_POLYGON_SET is the area(s) to fill, with m_ZoneMinThickness/2 + KI_POLYGON_SET polyset_zone_solid_areas; int margin = m_ZoneMinThickness / 2; /* First, creates the main polygon (i.e. the filled area using only one outline) @@ -160,7 +160,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) * the main polygon is stored in polyset_zone_solid_areas */ - CopyPolygonsFromFilledPolysListTotKPolygonList( this, polyset_zone_solid_areas ); + CopyPolygonsFromFilledPolysListToKiPolygonList( this, polyset_zone_solid_areas ); polyset_zone_solid_areas -= margin; if( polyset_zone_solid_areas.size() == 0 ) @@ -431,15 +431,15 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) // Calculate now actual solid areas if( cornerBufferPolysToSubstract.size() > 0 ) { - KPolygonSet polyset_holes; - AddPolygonCornersToKPolygonList( cornerBufferPolysToSubstract, polyset_holes ); + KI_POLYGON_SET polyset_holes; + AddPolygonCornersToKiPolygonList( cornerBufferPolysToSubstract, polyset_holes ); // Remove holes from initial area.: polyset_zone_solid_areas -= polyset_holes; } // put solid areas in m_FilledPolysList: m_FilledPolysList.clear(); - CopyPolygonsFromKPolygonListToFilledPolysList( this, polyset_zone_solid_areas ); + CopyPolygonsFromKiPolygonListToFilledPolysList( this, polyset_zone_solid_areas ); // Remove insulated islands: if( GetNet() > 0 ) @@ -455,13 +455,13 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) // remove copper areas if( cornerBufferPolysToSubstract.size() ) { - KPolygonSet polyset_holes; - AddPolygonCornersToKPolygonList( cornerBufferPolysToSubstract, polyset_holes ); + KI_POLYGON_SET polyset_holes; + AddPolygonCornersToKiPolygonList( cornerBufferPolysToSubstract, polyset_holes ); polyset_zone_solid_areas -= polyset_holes; // put these areas in m_FilledPolysList m_FilledPolysList.clear(); - CopyPolygonsFromKPolygonListToFilledPolysList( this, polyset_zone_solid_areas ); + CopyPolygonsFromKiPolygonListToFilledPolysList( this, polyset_zone_solid_areas ); if( GetNet() > 0 ) Test_For_Copper_Island_And_Remove_Insulated_Islands( aPcb ); @@ -470,12 +470,12 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) cornerBufferPolysToSubstract.clear(); } -void AddPolygonCornersToKPolygonList( std::vector & aCornersBuffer, - KPolygonSet& aKPolyList ) +void AddPolygonCornersToKiPolygonList( std::vector & aCornersBuffer, + KI_POLYGON_SET& aKiPolyList ) { unsigned ii; - std::vector cornerslist; + std::vector cornerslist; int polycount = 0; @@ -485,42 +485,42 @@ void AddPolygonCornersToKPolygonList( std::vector & aCornersBuffer, polycount++; } - aKPolyList.reserve( polycount ); + aKiPolyList.reserve( polycount ); for( unsigned icnt = 0; icnt < aCornersBuffer.size(); ) { - KPolygon poly; + KI_POLYGON poly; cornerslist.clear(); for( ii = icnt; ii < aCornersBuffer.size(); ii++ ) { - cornerslist.push_back( KPolyPoint( aCornersBuffer[ii].x, aCornersBuffer[ii].y ) ); + cornerslist.push_back( KI_POLY_POINT( aCornersBuffer[ii].x, aCornersBuffer[ii].y ) ); if( aCornersBuffer[ii].end_contour ) break; } bpl::set_points( poly, cornerslist.begin(), cornerslist.end() ); - aKPolyList.push_back( poly ); + aKiPolyList.push_back( poly ); icnt = ii + 1; } } -int CopyPolygonsFromKPolygonListToFilledPolysList( ZONE_CONTAINER* aZone, - KPolygonSet& aKPolyList ) +int CopyPolygonsFromKiPolygonListToFilledPolysList( ZONE_CONTAINER* aZone, + KI_POLYGON_SET& aKiPolyList ) { int count = 0; std::vector polysList; - for( unsigned ii = 0; ii < aKPolyList.size(); ii++ ) + for( unsigned ii = 0; ii < aKiPolyList.size(); ii++ ) { - KPolygon& poly = aKPolyList[ii]; + KI_POLYGON& poly = aKiPolyList[ii]; CPolyPt corner( 0, 0, false ); for( unsigned jj = 0; jj < poly.size(); jj++ ) { - KPolyPoint point = *(poly.begin() + jj); + KI_POLY_POINT point = *(poly.begin() + jj); corner.x = point.x(); corner.y = point.y(); corner.end_contour = false; @@ -542,10 +542,10 @@ int CopyPolygonsFromKPolygonListToFilledPolysList( ZONE_CONTAINER* aZone, } -int CopyPolygonsFromFilledPolysListTotKPolygonList( ZONE_CONTAINER* aZone, - KPolygonSet& aKPolyList ) +int CopyPolygonsFromFilledPolysListToKiPolygonList( ZONE_CONTAINER* aZone, + KI_POLYGON_SET& aKiPolyList ) { - std::vector polysList = aZone->GetFilledPolysList(); + const std::vector& polysList = aZone->GetFilledPolysList(); unsigned corners_count = polysList.size(); int count = 0; unsigned ic = 0; @@ -554,35 +554,32 @@ int CopyPolygonsFromFilledPolysListTotKPolygonList( ZONE_CONTAINER* aZone, for( unsigned ii = 0; ii < corners_count; ii++ ) { - CPolyPt* corner = &polysList[ic]; + const CPolyPt& corner = polysList[ii]; - if( corner->end_contour ) + if( corner.end_contour ) polycount++; } - aKPolyList.reserve( polycount ); - std::vector cornerslist; + aKiPolyList.reserve( polycount ); + std::vector cornerslist; while( ic < corners_count ) { cornerslist.clear(); - KPolygon poly; + KI_POLYGON poly; { - for( ; ic < corners_count; ic++ ) + while( ic < corners_count ) { - CPolyPt* corner = &polysList[ic]; - cornerslist.push_back( KPolyPoint( corner->x, corner->y ) ); + const CPolyPt& corner = polysList[ic++]; + cornerslist.push_back( KI_POLY_POINT( corner.x, corner.y ) ); count++; - if( corner->end_contour ) - { - ic++; + if( corner.end_contour ) break; - } } bpl::set_points( poly, cornerslist.begin(), cornerslist.end() ); - aKPolyList.push_back( poly ); + aKiPolyList.push_back( poly ); } } diff --git a/pcbnew/zones_functions_for_undo_redo.cpp b/pcbnew/zones_functions_for_undo_redo.cpp index d3971a44fd..7d13e3b6b4 100644 --- a/pcbnew/zones_functions_for_undo_redo.cpp +++ b/pcbnew/zones_functions_for_undo_redo.cpp @@ -115,7 +115,7 @@ bool ZONE_CONTAINER::IsSame( const ZONE_CONTAINER& aZoneToCompare ) wxASSERT( m_Poly ); // m_Poly == NULL Should never happen wxASSERT( aZoneToCompare.m_Poly ); - if( m_Poly->corner != aZoneToCompare.m_Poly->corner ) // Compare vector + if( m_Poly->m_CornersList != aZoneToCompare.m_Poly->m_CornersList ) // Compare vector return false; return true; diff --git a/pcbnew/zones_test_and_combine_areas.cpp b/pcbnew/zones_test_and_combine_areas.cpp index d790a8eb9e..fd5092d0bf 100644 --- a/pcbnew/zones_test_and_combine_areas.cpp +++ b/pcbnew/zones_test_and_combine_areas.cpp @@ -31,6 +31,7 @@ */ #include +#include #include #include #include @@ -142,7 +143,7 @@ int BOARD::TestAreaPolygon( ZONE_CONTAINER* CurrArea ) // first, check for sides intersecting other sides, especially arcs bool bInt = false; bool bArcInt = false; - int n_cont = p->GetNumContours(); + int n_cont = p->GetContoursCount(); // make bounding rect for each contour std::vector cr; @@ -550,7 +551,7 @@ bool BOARD::TestAreaIntersections( ZONE_CONTAINER* area_to_test ) continue; // test for intersecting segments - for( int icont1 = 0; icont1GetNumContours(); icont1++ ) + for( int icont1 = 0; icont1GetContoursCount(); icont1++ ) { int is1 = poly1->GetContourStart( icont1 ); int ie1 = poly1->GetContourEnd( icont1 ); @@ -574,7 +575,7 @@ bool BOARD::TestAreaIntersections( ZONE_CONTAINER* area_to_test ) style1 = poly1->GetSideStyle( ic1 ); - for( int icont2 = 0; icont2 < poly2->GetNumContours(); icont2++ ) + for( int icont2 = 0; icont2 < poly2->GetContoursCount(); icont2++ ) { int is2 = poly2->GetContourStart( icont2 ); int ie2 = poly2->GetContourEnd( icont2 ); @@ -668,7 +669,7 @@ int BOARD::TestAreaIntersection( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_ bool bInt = false; bool bArcInt = false; - for( int icont1 = 0; icont1GetNumContours(); icont1++ ) + for( int icont1 = 0; icont1GetContoursCount(); icont1++ ) { int is1 = poly1->GetContourStart( icont1 ); int ie1 = poly1->GetContourEnd( icont1 ); @@ -692,7 +693,7 @@ int BOARD::TestAreaIntersection( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_ style1 = poly1->GetSideStyle( ic1 ); - for( int icont2 = 0; icont2GetNumContours(); icont2++ ) + for( int icont2 = 0; icont2GetContoursCount(); icont2++ ) { int is2 = poly2->GetContourStart( icont2 ); int ie2 = poly2->GetContourEnd( icont2 ); @@ -778,145 +779,139 @@ int BOARD::TestAreaIntersection( ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_ return 1; } +/** + * Function CopyPolysListToKiPolygonWithHole + * converts the outline contours aPolysList to a KI_POLYGON_WITH_HOLES + * + * @param aPolysList = the list of corners of contours + * @param aPolygoneWithHole = a KI_POLYGON_WITH_HOLES to populate + */ +void CopyPolysListToKiPolygonWithHole( const std::vector& aPolysList, + KI_POLYGON_WITH_HOLES& aPolygoneWithHole ) +{ + unsigned corners_count = aPolysList.size(); + + std::vector cornerslist; + KI_POLYGON poly; + + // Enter main outline: this is the first contour + unsigned ic = 0; + while( ic < corners_count ) + { + const CPolyPt& corner = aPolysList[ic++]; + cornerslist.push_back( KI_POLY_POINT( corner.x, corner.y ) ); + + if( corner.end_contour ) + break; + } + + aPolygoneWithHole.set( cornerslist.begin(), cornerslist.end() ); + + // Enter holes: they are next contours (when exist) + if( ic < corners_count ) + { + KI_POLYGON_SET holePolyList; + while( ic < corners_count ) + { + cornerslist.clear(); + + while( ic < corners_count ) + { + const CPolyPt& corner = aPolysList[ic++]; + cornerslist.push_back( KI_POLY_POINT( corner.x, corner.y ) ); + + if( corner.end_contour ) + break; + } + + bpl::set_points( poly, cornerslist.begin(), cornerslist.end() ); + holePolyList.push_back( poly ); + } + aPolygoneWithHole.set_holes( holePolyList.begin(), holePolyList.end() ); + } +} + /** * Function CombineAreas - * If possible, combine 2 copper areas + * Merge 2 copper areas (which are expected intersecting) * @param aDeletedList = a PICKED_ITEMS_LIST * where to store deleted areas (useful in undo * commands can be NULL - * @param area_ref = tje main area (zone) + * @param area_ref = the main area (zone) * @param area_to_combine = the zone that can be merged with area_ref * area_ref must be BEFORE area_to_combine * area_to_combine will be deleted, if areas are combined * @return : 0 if no intersection * 1 if intersection - * 2 if arcs intersect + * 2 if arcs intersect (Currently not supported) */ + int BOARD::CombineAreas( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_ref, ZONE_CONTAINER* area_to_combine ) { if( area_ref == area_to_combine ) { wxASSERT( 0 ); + return 0; } // polygons intersect, combine them - std::vector arc_array1; - std::vector arc_array2; - bool keep_area_to_combine = false; +// std::vector arc_array1; +// std::vector arc_array2; + bool keep_area_to_combine = false; // TODO test if areas intersect - Bool_Engine* booleng = new Bool_Engine(); - ArmBoolEng( booleng ); + KI_POLYGON_WITH_HOLES areaRefPoly; + KI_POLYGON_WITH_HOLES areaToMergePoly; + CopyPolysListToKiPolygonWithHole( area_ref->m_Poly->m_CornersList, areaRefPoly ); + CopyPolysListToKiPolygonWithHole( area_to_combine->m_Poly->m_CornersList, areaToMergePoly ); - area_ref->m_Poly->AddPolygonsToBoolEng( booleng, GROUP_A, -1, -1 ); - area_to_combine->m_Poly->AddPolygonsToBoolEng( booleng, GROUP_B, -1, -1 ); - booleng->Do_Operation( BOOL_OR ); + KI_POLYGON_WITH_HOLES_SET mergedOutlines; + mergedOutlines.push_back( areaRefPoly ); + mergedOutlines += areaToMergePoly; + // We should have only one polygon with holes in mergedOutlines + // or the 2 initial outlines do not intersect + if( mergedOutlines.size() > 1 ) + return 0; + + areaRefPoly = mergedOutlines[0]; + area_ref->m_Poly->RemoveAllContours(); + + KI_POLYGON_WITH_HOLES::iterator_type corner = areaRefPoly.begin(); // create area with external contour: Recreate only area edges, NOT holes - if( booleng->StartPolygonGet() ) + area_ref->m_Poly->Start( area_ref->GetLayer(), corner->x(), corner->y(), + area_ref->m_Poly->GetHatchStyle() ); + while( ++corner != areaRefPoly.end() ) { - if( booleng->GetPolygonPointEdgeType() == KB_INSIDE_EDGE ) + area_ref->m_Poly->AppendCorner( corner->x(), corner->y() ); + } + + area_ref->m_Poly->Close(); + + // add holes (set of polygons) + KI_POLYGON_WITH_HOLES::iterator_holes_type hole = areaRefPoly.begin_holes(); + while( hole != areaRefPoly.end_holes() ) + { + KI_POLYGON::iterator_type hole_corner = hole->begin(); + // create area with external contour: Recreate only area edges, NOT holes + while( hole_corner != hole->end() ) { - DisplayError( NULL, wxT( "BOARD::CombineAreas() error: unexpected hole descriptor" ) ); + area_ref->m_Poly->AppendCorner( hole_corner->x(), hole_corner->y() ); + hole_corner++; } - - area_ref->m_Poly->RemoveAllContours(); - - // foreach point in the polygon - bool first = true; - - while( booleng->PolygonHasMorePoints() ) - { - int x = (int) booleng->GetPolygonXPoint(); - int y = (int) booleng->GetPolygonYPoint(); - - if( first ) - { - first = false; - area_ref->m_Poly->Start( area_ref->GetLayer( - ), x, y, area_ref->m_Poly->GetHatchStyle() ); - } - else - { - area_ref->m_Poly->AppendCorner( x, y ); - } - } - - booleng->EndPolygonGet(); area_ref->m_Poly->Close(); + hole++; } - // Recreate the area_to_combine if a second polygon exists - // if not exists , the first poly contains the 2 initial polygons -#if 0 // TestAreaIntersection must be called before combine areas, so - // 2 intersecting areas are expected, and only one outline contour after combining areas - else - { - area_to_combine->m_Poly->RemoveAllContours(); - keep_area_to_combine = true; - - // create area with external contour: Recreate only area edges, NOT holes (todo..) - { - // foreach point in the polygon - bool first = true; - while( booleng->PolygonHasMorePoints() ) - { - int x = booleng->GetPolygonXPoint(); - int y = booleng->GetPolygonYPoint(); - - if( first ) - { - first = false; - area_to_combine->m_Poly->Start( area_ref->GetLayer(), x, y, - area_ref->m_Poly->GetHatchStyle() ); - } - else - { - area_to_combine->m_Poly->AppendCorner( x, y ); - } - } - - booleng->EndPolygonGet(); - area_to_combine->m_Poly->Close(); - } - } -#endif - - // add holes - bool show_error = true; - - while( booleng->StartPolygonGet() ) - { - // we expect all vertex are holes inside the main outline - if( booleng->GetPolygonPointEdgeType() != KB_INSIDE_EDGE ) - { - if( show_error ) // show this error only once, if happens - DisplayError( NULL, - wxT( "BOARD::CombineAreas() error: unexpected outside contour descriptor" ) ); - - show_error = false; - continue; - } - - while( booleng->PolygonHasMorePoints() ) - { - int x = (int) booleng->GetPolygonXPoint(); - int y = (int) booleng->GetPolygonYPoint(); - area_ref->m_Poly->AppendCorner( x, y ); - } - - area_ref->m_Poly->Close(); - booleng->EndPolygonGet(); - } if( !keep_area_to_combine ) RemoveArea( aDeletedList, area_to_combine ); area_ref->utility = 1; - area_ref->m_Poly->RestoreArcs( &arc_array1 ); - area_ref->m_Poly->RestoreArcs( &arc_array2 ); +// area_ref->m_Poly->RestoreArcs( &arc_array1 ); +// area_ref->m_Poly->RestoreArcs( &arc_array2 ); area_ref->m_Poly->Hatch(); - delete booleng; + return 1; } @@ -1024,7 +1019,7 @@ int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_E } // now test spacing between areas - for( int icont = 0; icont < refSmoothedPoly->GetNumContours(); icont++ ) + for( int icont = 0; icont < refSmoothedPoly->GetContoursCount(); icont++ ) { int ic_start = refSmoothedPoly->GetContourStart( icont ); int ic_end = refSmoothedPoly->GetContourEnd( icont ); @@ -1048,7 +1043,7 @@ int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_E int astyle = refSmoothedPoly->GetSideStyle( ic ); - for( int icont2 = 0; icont2 < testSmoothedPoly->GetNumContours(); icont2++ ) + for( int icont2 = 0; icont2 < testSmoothedPoly->GetContoursCount(); icont2++ ) { int ic_start2 = testSmoothedPoly->GetContourStart( icont2 ); int ic_end2 = testSmoothedPoly->GetContourEnd( icont2 ); @@ -1128,7 +1123,7 @@ bool DRC::doEdgeZoneDrc( ZONE_CONTAINER* aArea, int aCornerIndex ) wxPoint end; // Search the end point of the edge starting at aCornerIndex - if( aArea->m_Poly->corner[aCornerIndex].end_contour == false + if( aArea->m_Poly->m_CornersList[aCornerIndex].end_contour == false && aCornerIndex < (aArea->GetNumCorners() - 1) ) { end = aArea->GetCornerPosition( aCornerIndex + 1 ); @@ -1141,7 +1136,7 @@ bool DRC::doEdgeZoneDrc( ZONE_CONTAINER* aArea, int aCornerIndex ) while( ii >= 0 ) { - if( aArea->m_Poly->corner[ii].end_contour ) + if( aArea->m_Poly->m_CornersList[ii].end_contour ) break; end = aArea->GetCornerPosition( ii ); @@ -1189,7 +1184,7 @@ bool DRC::doEdgeZoneDrc( ZONE_CONTAINER* aArea, int aCornerIndex ) int ax2 = end.x; int ay2 = end.y; - for( int icont2 = 0; icont2 < area_to_test->m_Poly->GetNumContours(); icont2++ ) + for( int icont2 = 0; icont2 < area_to_test->m_Poly->GetContoursCount(); icont2++ ) { int ic_start2 = area_to_test->m_Poly->GetContourStart( icont2 ); int ic_end2 = area_to_test->m_Poly->GetContourEnd( icont2 ); diff --git a/polygon/PolyLine.cpp b/polygon/PolyLine.cpp index 4630e9dbbc..99fa36f76c 100644 --- a/polygon/PolyLine.cpp +++ b/polygon/PolyLine.cpp @@ -18,8 +18,8 @@ CPolyLine::CPolyLine() { m_hatchStyle = NO_HATCH; m_hatchPitch = 0; - m_Width = 0; - utility = 0; + m_width = 0; + m_utility = 0; m_Kbool_Poly_Engine = NULL; } @@ -33,6 +33,16 @@ CPolyLine::~CPolyLine() delete m_Kbool_Poly_Engine; } +/** + * Function armBoolEng + * Initialise parameters used in kbool + * @param aBooleng = pointer to the Bool_Engine to initialise + * @param aConvertHoles = mode for holes when a boolean operation is made + * true: holes are linked into outer contours by double overlapping segments + * false: holes are not linked: in this mode contours are added clockwise + * and polygons added counter clockwise are holes (default) + */ +static void armBoolEng( Bool_Engine* aBooleng, bool aConvertHoles = false ); /** * Function NormalizeWithKbool @@ -95,8 +105,8 @@ int CPolyLine::NormalizeWithKbool( std::vector * aExtraPolyList, boo else if( n_ext_cont == 0 ) { // first external contour, replace this poly - corner.clear(); - side_style.clear(); + m_CornersList.clear(); + m_SideStyle.clear(); bool first = true; while( m_Kbool_Poly_Engine->PolygonHasMorePoints() ) { @@ -271,7 +281,7 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector< m_Kbool_Poly_Engine = NULL; } - int polycount = GetNumContours(); + int polycount = GetContoursCount(); if( !GetClosed() && (aStart_contour == (polycount - 1) || aStart_contour == -1) ) return 1; // error @@ -297,7 +307,7 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector< // Fill a kbool engine for this contour, // and combine it with previous contours Bool_Engine* booleng = new Bool_Engine(); - ArmBoolEng( booleng, aConvertHoles ); + armBoolEng( booleng, aConvertHoles ); if( m_Kbool_Poly_Engine ) // a previous contour exists. Put it in new engine { @@ -329,7 +339,7 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector< } for( int ic = ic_st; ic<=ic_end; ic++ ) { - int style = side_style[ic]; + int style = m_SideStyle[ic]; if( style == STRAIGHT ) n_vertices++; else @@ -345,19 +355,19 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector< int ivtx = 0; for( int ic = ic_st; ic<=ic_end; ic++ ) { - int style = side_style[ic]; - int x1 = corner[ic].x; - int y1 = corner[ic].y; + int style = m_SideStyle[ic]; + int x1 = m_CornersList[ic].x; + int y1 = m_CornersList[ic].y; int x2, y2; if( ic < ic_end ) { - x2 = corner[ic + 1].x; - y2 = corner[ic + 1].y; + x2 = m_CornersList[ic + 1].x; + y2 = m_CornersList[ic + 1].y; } else { - x2 = corner[ic_st].x; - y2 = corner[ic_st].y; + x2 = m_CornersList[ic_st].x; + y2 = m_CornersList[ic_st].y; } if( style == STRAIGHT ) { @@ -504,14 +514,14 @@ int CPolyLine::MakeKboolPoly( int aStart_contour, int aEnd_contour, std::vector< /** - * Function ArmBoolEng + * Function armBoolEng * Initialise parameters used in kbool * @param aBooleng = pointer to the Bool_Engine to initialise * @param aConvertHoles = mode for holes when a boolean operation is made * true: in resulting polygon, holes are linked into outer contours by double overlapping segments * false: in resulting polygons, holes are not linked: they are separate polygons */ -void ArmBoolEng( Bool_Engine* aBooleng, bool aConvertHoles ) +void armBoolEng( Bool_Engine* aBooleng, bool aConvertHoles ) { // set some global vals to arm the boolean engine @@ -614,7 +624,7 @@ int CPolyLine::RestoreArcs( std::vector * arc_array, std::vectorsize(); CPolyLine* poly; - // undraw polys and clear utility flag for all corners + // undraw polys and clear m_utility flag for all corners for( int ip = 0; ip * arc_array, std::vectorGetNumCorners(); ic++ ) poly->SetUtility( ic, 0 ); - // clear utility flag + // clear m_utility flag } // find arcs and replace them @@ -649,7 +659,7 @@ int CPolyLine::RestoreArcs( std::vector * arc_array, std::vectorGetNumContours(); + int polycount = poly->GetContoursCount(); for( int icont = 0; icont < polycount; icont++ ) { int ic_start = poly->GetContourStart( icont ); @@ -697,7 +707,7 @@ int CPolyLine::RestoreArcs( std::vector * arc_array, std::vectorside_style[arc_start] = style; + poly->m_SideStyle[arc_start] = style; // mark corners for deletion from arc_start+1 to arc_end-1 for( int i = arc_start + 1; i!=arc_end; ) @@ -769,8 +779,8 @@ void CPolyLine::Start( int layer, int x, int y, int hatch ) CPolyPt poly_pt( x, y ); poly_pt.end_contour = false; - corner.push_back( poly_pt ); - side_style.push_back( 0 ); + m_CornersList.push_back( poly_pt ); + m_SideStyle.push_back( 0 ); } @@ -783,10 +793,10 @@ void CPolyLine::AppendCorner( int x, int y, int style, bool bDraw ) poly_pt.end_contour = false; // add entries for new corner and side - corner.push_back( poly_pt ); - side_style.push_back( style ); - if( corner.size() > 0 && !corner[corner.size() - 1].end_contour ) - side_style[corner.size() - 1] = style; + m_CornersList.push_back( poly_pt ); + m_SideStyle.push_back( style ); + if( m_CornersList.size() > 0 && !m_CornersList[m_CornersList.size() - 1].end_contour ) + m_SideStyle[m_CornersList.size() - 1] = style; if( bDraw ) Hatch(); } @@ -801,8 +811,8 @@ void CPolyLine::Close( int style, bool bDraw ) wxASSERT( 0 ); } UnHatch(); - side_style[corner.size() - 1] = style; - corner[corner.size() - 1].end_contour = true; + m_SideStyle[m_CornersList.size() - 1] = style; + m_CornersList[m_CornersList.size() - 1].end_contour = true; if( bDraw ) Hatch(); } @@ -813,8 +823,8 @@ void CPolyLine::Close( int style, bool bDraw ) void CPolyLine::MoveCorner( int ic, int x, int y ) { UnHatch(); - corner[ic].x = x; - corner[ic].y = y; + m_CornersList[ic].x = x; + m_CornersList[ic].y = y; Hatch(); } @@ -827,23 +837,23 @@ void CPolyLine::DeleteCorner( int ic, bool bDraw ) int icont = GetContour( ic ); int istart = GetContourStart( icont ); int iend = GetContourEnd( icont ); - bool bClosed = icont < GetNumContours() - 1 || GetClosed(); + bool bClosed = icont < GetContoursCount() - 1 || GetClosed(); if( !bClosed ) { // open contour, must be last contour - corner.erase( corner.begin() + ic ); + m_CornersList.erase( m_CornersList.begin() + ic ); if( ic != istart ) - side_style.erase( side_style.begin() + ic - 1 ); + m_SideStyle.erase( m_SideStyle.begin() + ic - 1 ); } else { // closed contour - corner.erase( corner.begin() + ic ); - side_style.erase( side_style.begin() + ic ); + m_CornersList.erase( m_CornersList.begin() + ic ); + m_SideStyle.erase( m_SideStyle.begin() + ic ); if( ic == iend ) - corner[ic - 1].end_contour = true; + m_CornersList[ic - 1].end_contour = true; } if( bClosed && GetContourSize( icont ) < 3 ) { @@ -869,7 +879,7 @@ void CPolyLine::RemoveContour( int icont ) int istart = GetContourStart( icont ); int iend = GetContourEnd( icont ); - int polycount = GetNumContours(); + int polycount = GetContoursCount(); if( icont == 0 && polycount == 1 ) { // remove the only contour @@ -878,16 +888,16 @@ void CPolyLine::RemoveContour( int icont ) else if( icont == polycount - 1 ) { // remove last contour - corner.erase( corner.begin() + istart, corner.end() ); - side_style.erase( side_style.begin() + istart, side_style.end() ); + m_CornersList.erase( m_CornersList.begin() + istart, m_CornersList.end() ); + m_SideStyle.erase( m_SideStyle.begin() + istart, m_SideStyle.end() ); } else { // remove closed contour for( int ic = iend; ic>=istart; ic-- ) { - corner.erase( corner.begin() + ic ); - side_style.erase( side_style.begin() + ic ); + m_CornersList.erase( m_CornersList.begin() + ic ); + m_SideStyle.erase( m_SideStyle.begin() + ic ); } } Hatch(); @@ -904,7 +914,7 @@ CPolyLine* CPolyLine::Chamfer( unsigned int aDistance ) return newPoly; } - int polycount = GetNumContours(); + int polycount = GetContoursCount(); for( int contour = 0; contour < polycount; contour++ ) { unsigned int startIndex = GetContourStart( contour ); @@ -915,29 +925,29 @@ CPolyLine* CPolyLine::Chamfer( unsigned int aDistance ) int x1, y1, nx, ny; long long xa, ya, xb, yb; - x1 = corner[index].x; - y1 = corner[index].y; + x1 = m_CornersList[index].x; + y1 = m_CornersList[index].y; if( index == startIndex ) { - xa = corner[endIndex].x - x1; - ya = corner[endIndex].y - y1; + xa = m_CornersList[endIndex].x - x1; + ya = m_CornersList[endIndex].y - y1; } else { - xa = corner[index-1].x - x1; - ya = corner[index-1].y - y1; + xa = m_CornersList[index-1].x - x1; + ya = m_CornersList[index-1].y - y1; } if( index == endIndex ) { - xb = corner[startIndex].x - x1; - yb = corner[startIndex].y - y1; + xb = m_CornersList[startIndex].x - x1; + yb = m_CornersList[startIndex].y - y1; } else { - xb = corner[index+1].x - x1; - yb = corner[index+1].y - y1; + xb = m_CornersList[index+1].x - x1; + yb = m_CornersList[index+1].y - y1; } unsigned int lena = (unsigned int)sqrt( (double)(xa*xa + ya*ya) ); @@ -980,7 +990,7 @@ CPolyLine* CPolyLine::Fillet( unsigned int aRadius, unsigned int aSegments ) return newPoly; } - int polycount = GetNumContours(); + int polycount = GetContoursCount(); for( int contour = 0; contour < polycount; contour++ ) { unsigned int startIndex = GetContourStart( contour ); @@ -994,29 +1004,29 @@ CPolyLine* CPolyLine::Fillet( unsigned int aRadius, unsigned int aSegments ) long long xb, yb; // Next vertex double nx, ny; - x1 = corner[index].x; - y1 = corner[index].y; + x1 = m_CornersList[index].x; + y1 = m_CornersList[index].y; if( index == startIndex ) { - xa = corner[endIndex].x - x1; - ya = corner[endIndex].y - y1; + xa = m_CornersList[endIndex].x - x1; + ya = m_CornersList[endIndex].y - y1; } else { - xa = corner[index-1].x - x1; - ya = corner[index-1].y - y1; + xa = m_CornersList[index-1].x - x1; + ya = m_CornersList[index-1].y - y1; } if( index == endIndex ) { - xb = corner[startIndex].x - x1; - yb = corner[startIndex].y - y1; + xb = m_CornersList[startIndex].x - x1; + yb = m_CornersList[startIndex].y - y1; } else { - xb = corner[index+1].x - x1; - yb = corner[index+1].y - y1; + xb = m_CornersList[index+1].x - x1; + yb = m_CornersList[index+1].y - y1; } double lena = sqrt( (double) (xa*xa + ya*ya) ); @@ -1103,8 +1113,8 @@ void CPolyLine::RemoveAllContours( void ) * Others params are not chnaged */ { - corner.clear(); - side_style.clear(); + m_CornersList.clear(); + m_SideStyle.clear(); } @@ -1117,23 +1127,23 @@ void CPolyLine::RemoveAllContours( void ) void CPolyLine::InsertCorner( int ic, int x, int y ) { UnHatch(); - if( (unsigned) (ic) >= corner.size() ) + if( (unsigned) (ic) >= m_CornersList.size() ) { - corner.push_back( CPolyPt( x, y ) ); - side_style.push_back( STRAIGHT ); + m_CornersList.push_back( CPolyPt( x, y ) ); + m_SideStyle.push_back( STRAIGHT ); } else { - corner.insert( corner.begin() + ic + 1, CPolyPt( x, y ) ); - side_style.insert( side_style.begin() + ic + 1, STRAIGHT ); + m_CornersList.insert( m_CornersList.begin() + ic + 1, CPolyPt( x, y ) ); + m_SideStyle.insert( m_SideStyle.begin() + ic + 1, STRAIGHT ); } - if( (unsigned) (ic + 1) < corner.size() ) + if( (unsigned) (ic + 1) < m_CornersList.size() ) { - if( corner[ic].end_contour ) + if( m_CornersList[ic].end_contour ) { - corner[ic + 1].end_contour = true; - corner[ic].end_contour = false; + m_CornersList[ic + 1].end_contour = true; + m_CornersList[ic].end_contour = false; } } Hatch(); @@ -1150,7 +1160,7 @@ void CPolyLine::UnHatch() int CPolyLine::GetEndContour( int ic ) { - return corner[ic].end_contour; + return m_CornersList[ic].end_contour; } @@ -1158,10 +1168,10 @@ CRect CPolyLine::GetBounds() { CRect r = GetCornerBounds(); - r.left -= m_Width / 2; - r.right += m_Width / 2; - r.bottom -= m_Width / 2; - r.top += m_Width / 2; + r.left -= m_width / 2; + r.right += m_width / 2; + r.bottom -= m_width / 2; + r.top += m_width / 2; return r; } @@ -1172,12 +1182,12 @@ CRect CPolyLine::GetCornerBounds() r.left = r.bottom = INT_MAX; r.right = r.top = INT_MIN; - for( unsigned i = 0; i max_x ) - max_x = corner[ic].x; - if( corner[ic].y < min_y ) - min_y = corner[ic].y; - if( corner[ic].y > max_y ) - max_y = corner[ic].y; + if( m_CornersList[ic].x < min_x ) + min_x = m_CornersList[ic].x; + if( m_CornersList[ic].x > max_x ) + max_x = m_CornersList[ic].x; + if( m_CornersList[ic].y < min_y ) + min_y = m_CornersList[ic].y; + if( m_CornersList[ic].y > max_y ) + max_y = m_CornersList[ic].y; } // Calculate spacing betwwen 2 hatch lines @@ -1409,7 +1419,7 @@ void CPolyLine::Hatch() min_a += offset; // now calculate and draw hatch lines - int nc = corner.size(); + int nc = m_CornersList.size(); // loop through hatch lines #define MAXPTS 200 // Usually we store only few values per one hatch line @@ -1433,22 +1443,22 @@ void CPolyLine::Hatch() { double x, y, x2, y2; int ok; - if( corner[ic].end_contour || ( ic == (int) (corner.size() - 1) ) ) + if( m_CornersList[ic].end_contour || ( ic == (int) (m_CornersList.size() - 1) ) ) { ok = FindLineSegmentIntersection( a, slope, - corner[ic].x, corner[ic].y, - corner[i_start_contour].x, - corner[i_start_contour].y, - side_style[ic], + m_CornersList[ic].x, m_CornersList[ic].y, + m_CornersList[i_start_contour].x, + m_CornersList[i_start_contour].y, + m_SideStyle[ic], &x, &y, &x2, &y2 ); i_start_contour = ic + 1; } else { ok = FindLineSegmentIntersection( a, slope, - corner[ic].x, corner[ic].y, - corner[ic + 1].x, corner[ic + 1].y, - side_style[ic], + m_CornersList[ic].x, m_CornersList[ic].y, + m_CornersList[ic + 1].x, m_CornersList[ic + 1].y, + m_SideStyle[ic], &x, &y, &x2, &y2 ); } if( ok ) @@ -1534,7 +1544,7 @@ bool CPolyLine::TestPointInside( int px, int py ) // if the tested point is inside only one contour, it is inside the whole polygon // (in fact inside the main outline, and outside all holes). // if inside 2 contours (the main outline + an hole), it is outside the poly. - int polycount = GetNumContours(); + int polycount = GetContoursCount(); bool inside = false; for( int icont = 0; icont < polycount; icont++ ) { @@ -1542,7 +1552,7 @@ bool CPolyLine::TestPointInside( int px, int py ) int iend = GetContourEnd( icont ); // Test this polygon: - if( TestPointInsidePolygon( corner, istart, iend, px, py) ) // test point inside the current polygon + if( TestPointInsidePolygon( m_CornersList, istart, iend, px, py) ) // test point inside the current polygon inside = not inside; } @@ -1557,9 +1567,9 @@ void CPolyLine::Copy( CPolyLine* src ) m_hatchStyle = src->m_hatchStyle; m_hatchPitch = src->m_hatchPitch; // copy corners, using vector copy - corner = src->corner; + m_CornersList = src->m_CornersList; // copy side styles, using vector copy - side_style = src->side_style; + m_SideStyle = src->m_SideStyle; } @@ -1598,19 +1608,19 @@ void CPolyLine::MoveOrigin( int x_off, int y_off ) // void CPolyLine::SetX( int ic, int x ) { - corner[ic].x = x; + m_CornersList[ic].x = x; } void CPolyLine::SetY( int ic, int y ) { - corner[ic].y = y; + m_CornersList[ic].y = y; } void CPolyLine::SetEndContour( int ic, bool end_contour ) { - corner[ic].end_contour = end_contour; + m_CornersList[ic].end_contour = end_contour; } @@ -1676,7 +1686,7 @@ int CPolyLine::Distance( wxPoint aStart, wxPoint aEnd, int aWidth ) return 0; int distance = INT_MAX; - int polycount = GetNumContours(); + int polycount = GetContoursCount(); for( int icont = 0; icont < polycount; icont++ ) { @@ -1732,7 +1742,7 @@ int CPolyLine::Distance( const wxPoint& aPoint ) return 0; int distance = INT_MAX; - int polycount = GetNumContours(); + int polycount = GetContoursCount(); for( int icont = 0; icont < polycount; icont++ ) { diff --git a/polygon/PolyLine.h b/polygon/PolyLine.h index a27478dae4..468bf09f78 100644 --- a/polygon/PolyLine.h +++ b/polygon/PolyLine.h @@ -31,18 +31,6 @@ enum }; - -/** - * Function ArmBoolEng - * Initialise parameters used in kbool - * @param aBooleng = pointer to the Bool_Engine to initialise - * @param aConvertHoles = mode for holes when a boolean operation is made - * true: holes are linked into outer contours by double overlapping segments - * false: holes are not linked: in this mode contours are added clockwise - * and polygons added counter clockwise are holes (default) - */ -void ArmBoolEng( Bool_Engine* aBooleng, bool aConvertHoles = false ); - class CRect { public: @@ -86,22 +74,22 @@ class CPolyPt : public wxPoint { public: CPolyPt( int aX = 0, int aY = 0, bool aEnd = false, int aUtility = 0 ) : - wxPoint( aX, aY ), end_contour( aEnd ), utility( aUtility ) + wxPoint( aX, aY ), end_contour( aEnd ), m_utility( aUtility ) {} /// Pure copy constructor is here to dis-ambiguate from the /// specialized CPolyPt( const wxPoint& ) constructor version below. CPolyPt( const CPolyPt& aPt ) : - wxPoint( aPt.x, aPt.y ), end_contour( aPt.end_contour ), utility( aPt.utility ) + wxPoint( aPt.x, aPt.y ), end_contour( aPt.end_contour ), m_utility( aPt.m_utility ) {} CPolyPt( const wxPoint& aPoint ) : - wxPoint( aPoint ), end_contour( false ), utility( 0 ) + wxPoint( aPoint ), end_contour( false ), m_utility( 0 ) {} bool end_contour; - int utility; + int m_utility; bool operator == (const CPolyPt& cpt2 ) const { return (x == cpt2.x) && (y == cpt2.y) && (end_contour == cpt2.end_contour); } @@ -116,7 +104,7 @@ public: class CPolyLine { public: - enum side_style { STRAIGHT, ARC_CW, ARC_CCW }; // side styles + enum m_SideStyle { STRAIGHT, ARC_CW, ARC_CCW }; // side styles enum hatch_style { NO_HATCH, DIAGONAL_FULL, DIAGONAL_EDGE }; // hatch styles // constructors/destructor @@ -173,21 +161,21 @@ public: int GetNumCorners(); int GetNumSides(); int GetClosed(); - int GetNumContours(); + int GetContoursCount(); int GetContour( int ic ); int GetContourStart( int icont ); int GetContourEnd( int icont ); int GetContourSize( int icont ); - int GetX( int ic ) const { return corner[ic].x; } - int GetY( int ic ) const { return corner[ic].y; } + int GetX( int ic ) const { return m_CornersList[ic].x; } + int GetY( int ic ) const { return m_CornersList[ic].y; } - const wxPoint& GetPos( int ic ) const { return corner[ic]; } + const wxPoint& GetPos( int ic ) const { return m_CornersList[ic]; } int GetEndContour( int ic ); - int GetUtility( int ic ) { return corner[ic].utility; }; - void SetUtility( int ic, int utility ) { corner[ic].utility = utility; }; + int GetUtility( int ic ) { return m_CornersList[ic].m_utility; }; + void SetUtility( int ic, int utility ) { m_CornersList[ic].m_utility = utility; }; int GetSideStyle( int is ); int GetHatchPitch() { return m_hatchPitch; } int GetDefaultHatchPitchMils() { return 20; } // default hatch pitch value in mils @@ -301,18 +289,18 @@ public: private: 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 enum hatch_style m_hatchStyle; // hatch style, see enum above int m_hatchPitch; // for DIAGONAL_EDGE hatched outlines, basic distance between 2 hatch lines // and the len of eacvh segment // for DIAGONAL_FULL, the pitch is twice this value - int utility; + int m_utility; // a flag used in some calculations Bool_Engine* m_Kbool_Poly_Engine; // polygons set in kbool engine data public: - std::vector corner; // array of points for corners - std::vector side_style; // array of styles for sides - std::vector m_HatchLines; // hatch lines + std::vector m_CornersList; // array of points for corners + std::vector m_SideStyle; // array of styles for sides + std::vector m_HatchLines; // hatch lines showing the polygon area }; #endif // #ifndef POLYLINE_H