From 87fa6615914c2765196dd520fe54d2c85a2c6f7a Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Wed, 8 May 2013 20:20:58 +0200 Subject: [PATCH] More work on CPOLYGONS_LIST class. --- 3d-viewer/3d_draw.cpp | 17 +- 3d-viewer/3d_draw_basic_functions.cpp | 49 ++-- common/convert_basic_shapes_to_polygon.cpp | 76 ------ include/convert_basic_shapes_to_polygon.h | 27 --- ...board_items_to_polygon_shape_transform.cpp | 3 +- pcbnew/class_zone.cpp | 81 +++---- pcbnew/class_zone.h | 2 +- pcbnew/kicad_plugin.cpp | 20 +- pcbnew/legacy_plugin.cpp | 14 +- pcbnew/plot_board_layers.cpp | 7 +- pcbnew/plot_brditems_plotter.cpp | 6 +- ...nvert_brd_items_to_polygons_with_Boost.cpp | 8 +- ...ones_convert_to_polygons_aux_functions.cpp | 4 +- pcbnew/zones_functions_for_undo_redo.cpp | 3 +- ...ones_polygons_insulated_copper_islands.cpp | 4 +- pcbnew/zones_polygons_test_connections.cpp | 2 +- pcbnew/zones_test_and_combine_areas.cpp | 4 +- polygon/PolyLine.cpp | 166 +++++++------ polygon/PolyLine.h | 226 ++++++++++++++---- polygon/polygon_test_point_inside.cpp | 18 +- polygon/polygon_test_point_inside.h | 10 +- 21 files changed, 384 insertions(+), 363 deletions(-) diff --git a/3d-viewer/3d_draw.cpp b/3d-viewer/3d_draw.cpp index a7f04f7483..bd66df0ccb 100644 --- a/3d-viewer/3d_draw.cpp +++ b/3d-viewer/3d_draw.cpp @@ -91,8 +91,8 @@ static void BuildPadShapeThickOutlineAsPolygon( D_PAD* aPad, for( unsigned ii = 0, jj = corners.size() - 1; ii < corners.size(); jj = ii, ii++ ) { TransformRoundedEndsSegmentToPolygon( aCornerBuffer, - wxPoint( corners[jj].x, corners[jj].y ), - wxPoint( corners[ii].x, corners[ii].y ), + corners.GetPos( jj ), + corners.GetPos( ii ), aCircleToSegmentsCount, aWidth ); } } @@ -289,14 +289,13 @@ void EDA_3D_CANVAS::BuildBoard3DView() KI_POLYGON_SET polysetHoles; // Add polygons, without holes - AddPolygonCornersToKiPolygonList( bufferPolys, currLayerPolyset ); + bufferPolys.ExportTo( currLayerPolyset ); // Add holes in polygon list - currLayerHoles.insert( currLayerHoles.begin(), - allLayerHoles.begin(), allLayerHoles.end() ); + currLayerHoles.Append( allLayerHoles ); if( currLayerHoles.size() > 0 ) - AddPolygonCornersToKiPolygonList( currLayerHoles, polysetHoles ); + currLayerHoles.ExportTo( polysetHoles ); // Merge polygons, remove holes currLayerPolyset -= polysetHoles; @@ -309,7 +308,7 @@ void EDA_3D_CANVAS::BuildBoard3DView() glNormal3f( 0.0, 0.0, Get3DLayer_Z_Orientation( layer ) ); bufferPolys.clear(); - CopyPolygonsFromKiPolygonListToPolysList( currLayerPolyset, bufferPolys ); + bufferPolys.ImportFrom( currLayerPolyset ); Draw3D_SolidHorizontalPolyPolygons( bufferPolys, zpos, thickness, g_Parm_3D_Visu.m_BiuTo3Dunits ); @@ -410,7 +409,7 @@ void EDA_3D_CANVAS::BuildBoard3DView() KI_POLYGON_SET currLayerPolyset; KI_POLYGON_SET polyset; - AddPolygonCornersToKiPolygonList( bufferPolys, polyset ); + bufferPolys.ExportTo( polyset ); // merge polys: currLayerPolyset += polyset; @@ -430,7 +429,7 @@ void EDA_3D_CANVAS::BuildBoard3DView() glNormal3f( 0.0, 0.0, Get3DLayer_Z_Orientation( layer ) ); bufferPolys.clear(); - CopyPolygonsFromKiPolygonListToPolysList( currLayerPolyset, bufferPolys ); + bufferPolys.ImportFrom( currLayerPolyset ); Draw3D_SolidHorizontalPolyPolygons( bufferPolys, zpos, thickness, g_Parm_3D_Visu.m_BiuTo3Dunits ); } diff --git a/3d-viewer/3d_draw_basic_functions.cpp b/3d-viewer/3d_draw_basic_functions.cpp index c87500dfff..1e622062e9 100644 --- a/3d-viewer/3d_draw_basic_functions.cpp +++ b/3d-viewer/3d_draw_basic_functions.cpp @@ -70,7 +70,7 @@ static inline void SetNormalZneg() * from Z position = aZpos to aZpos + aHeight * Used to create the vertical sides of 3D horizontal shapes with thickness. */ -static void Draw3D_VerticalPolygonalCylinder( const std::vector& aPolysList, +static void Draw3D_VerticalPolygonalCylinder( const CPOLYGONS_LIST& aPolysList, int aHeight, int aZpos, bool aInside, double aBiuTo3DUnits ) { @@ -100,19 +100,19 @@ static void Draw3D_VerticalPolygonalCylinder( const std::vector& aPolys { unsigned jj = ii + 1; - if( aPolysList[ii].end_contour || jj >= aPolysList.size() ) + if( aPolysList.IsEndContour( ii ) || jj >= aPolysList.size() ) { jj = startContour; startContour = ii + 1; } // Build the 4 vertices of each GL_QUAD - coords[0].x = aPolysList[ii].x; - coords[0].y = -aPolysList[ii].y; + coords[0].x = aPolysList.GetX( ii ); + coords[0].y = -aPolysList.GetY( ii ); coords[1].x = coords[0].x; coords[1].y = coords[0].y; // only z change - coords[2].x = aPolysList[jj].x; - coords[2].y = -aPolysList[jj].y; + coords[2].x = aPolysList.GetX( jj ); + coords[2].y = -aPolysList.GetY( jj ); coords[3].x = coords[2].x; coords[3].y = coords[2].y; // only z change @@ -142,7 +142,7 @@ void SetGLColor( EDA_COLOR_T color ) * The top side is located at aZpos + aThickness / 2 * The bottom side is located at aZpos - aThickness / 2 */ -void Draw3D_SolidHorizontalPolyPolygons( const std::vector& aPolysList, +void Draw3D_SolidHorizontalPolyPolygons( const CPOLYGONS_LIST& aPolysList, int aZpos, int aThickness, double aBiuTo3DUnits ) { GLUtesselator* tess = gluNewTess(); @@ -164,7 +164,7 @@ void Draw3D_SolidHorizontalPolyPolygons( const std::vector& aPolysList, // gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD); // Draw solid areas contained in this list - std::vector polylist = aPolysList; // temporary copy for gluTessVertex + CPOLYGONS_LIST polylist = aPolysList; // temporary copy for gluTessVertex for( int side = 0; side < 2; side++ ) { @@ -179,15 +179,15 @@ void Draw3D_SolidHorizontalPolyPolygons( const std::vector& aPolysList, startContour = 0; } - v_data[0] = polylist[ii].x * aBiuTo3DUnits; - v_data[1] = -polylist[ii].y * aBiuTo3DUnits; + v_data[0] = polylist.GetX( ii ) * aBiuTo3DUnits; + v_data[1] = -polylist.GetY( ii ) * aBiuTo3DUnits; // gluTessVertex store pointers on data, not data, so do not store // different corners values in a temporary variable // but send pointer on each CPolyPt value in polylist // before calling gluDeleteTess gluTessVertex( tess, v_data, &polylist[ii] ); - if( polylist[ii].end_contour == 1 ) + if( polylist.IsEndContour( ii ) ) { gluTessEndContour( tess ); gluTessEndPolygon( tess ); @@ -220,11 +220,11 @@ void Draw3D_SolidHorizontalPolyPolygons( const std::vector& aPolysList, * The first polygon is the main polygon, others are holes * See Draw3D_SolidHorizontalPolyPolygons for more info */ -void Draw3D_SolidHorizontalPolygonWithHoles( const std::vector& aPolysList, +void Draw3D_SolidHorizontalPolygonWithHoles( const CPOLYGONS_LIST& aPolysList, int aZpos, int aThickness, double aBiuTo3DUnits ) { - std::vector polygon; + CPOLYGONS_LIST polygon; ConvertPolysListWithHolesToOnePolygon( aPolysList, polygon ); Draw3D_SolidHorizontalPolyPolygons( polygon, aZpos, aThickness, aBiuTo3DUnits ); @@ -241,7 +241,7 @@ void Draw3D_ZaxisCylinder( wxPoint aCenterPos, int aRadius, int aZpos, double aBiuTo3DUnits ) { const int slice = SEGM_PER_CIRCLE; - std::vector outer_cornerBuffer; + CPOLYGONS_LIST outer_cornerBuffer; TransformCircleToPolygon( outer_cornerBuffer, aCenterPos, aRadius + (aThickness / 2), slice ); @@ -249,7 +249,7 @@ void Draw3D_ZaxisCylinder( wxPoint aCenterPos, int aRadius, std::vector coords; coords.resize( 4 ); - std::vector inner_cornerBuffer; + CPOLYGONS_LIST inner_cornerBuffer; if( aThickness ) // build the the vertical inner polygon (hole) TransformCircleToPolygon( inner_cornerBuffer, aCenterPos, aRadius - (aThickness / 2), slice ); @@ -269,9 +269,8 @@ void Draw3D_ZaxisCylinder( wxPoint aCenterPos, int aRadius, { // draw top (front) and bottom (back) horizontal sides (rings) SetNormalZpos(); - outer_cornerBuffer.insert( outer_cornerBuffer.end(), - inner_cornerBuffer.begin(), inner_cornerBuffer.end() ); - std::vector polygon; + outer_cornerBuffer.Append( inner_cornerBuffer ); + CPOLYGONS_LIST polygon; ConvertPolysListWithHolesToOnePolygon( outer_cornerBuffer, polygon ); // draw top (front) horizontal ring @@ -303,7 +302,7 @@ void Draw3D_ZaxisOblongCylinder( wxPoint aAxis1Pos, wxPoint aAxis2Pos, const int slice = SEGM_PER_CIRCLE; // Build the points to approximate oblong cylinder by segments - std::vector outer_cornerBuffer; + CPOLYGONS_LIST outer_cornerBuffer; int segm_width = (aRadius * 2) + aThickness; TransformRoundedEndsSegmentToPolygon( outer_cornerBuffer, aAxis1Pos, @@ -316,7 +315,7 @@ void Draw3D_ZaxisOblongCylinder( wxPoint aAxis1Pos, wxPoint aAxis2Pos, if( aThickness ) { - std::vector inner_cornerBuffer; + CPOLYGONS_LIST inner_cornerBuffer; segm_width = aRadius * 2; TransformRoundedEndsSegmentToPolygon( inner_cornerBuffer, aAxis1Pos, aAxis2Pos, slice, segm_width ); @@ -328,11 +327,9 @@ void Draw3D_ZaxisOblongCylinder( wxPoint aAxis1Pos, wxPoint aAxis2Pos, // Build the horizontal full polygon shape // (outer polygon shape - inner polygon shape) - outer_cornerBuffer.insert( outer_cornerBuffer.end(), - inner_cornerBuffer.begin(), - inner_cornerBuffer.end() ); + outer_cornerBuffer.Append( inner_cornerBuffer ); - std::vector polygon; + CPOLYGONS_LIST polygon; ConvertPolysListWithHolesToOnePolygon( outer_cornerBuffer, polygon ); // draw top (front) horizontal side (ring) @@ -360,7 +357,7 @@ void Draw3D_ZaxisOblongCylinder( wxPoint aAxis1Pos, wxPoint aAxis2Pos, void Draw3D_SolidSegment( const wxPoint& aStart, const wxPoint& aEnd, int aWidth, int aThickness, int aZpos, double aBiuTo3DUnits ) { - std::vector cornerBuffer; + CPOLYGONS_LIST cornerBuffer; const int slice = SEGM_PER_CIRCLE; TransformRoundedEndsSegmentToPolygon( cornerBuffer, aStart, aEnd, slice, aWidth ); @@ -375,7 +372,7 @@ void Draw3D_ArcSegment( const wxPoint& aCenterPos, const wxPoint& aStartPoint, { const int slice = SEGM_PER_CIRCLE; - std::vector cornerBuffer; + CPOLYGONS_LIST cornerBuffer; TransformArcToPolygon( cornerBuffer, aCenterPos, aStartPoint, aArcAngle, slice, aWidth ); diff --git a/common/convert_basic_shapes_to_polygon.cpp b/common/convert_basic_shapes_to_polygon.cpp index e9ecc555d5..1805d84bff 100644 --- a/common/convert_basic_shapes_to_polygon.cpp +++ b/common/convert_basic_shapes_to_polygon.cpp @@ -32,82 +32,6 @@ #include #include -/* Helper functions: - * We are using a lots polygons in calculations. - * and we are using 2 descriptions, - * one easy to use with boost::polygon (KI_POLYGON_SET) - * one easy to use in zones and in draw functions (CPOLYGONS_LIST) - * Copy polygons from a KI_POLYGON_SET set of polygons to - * a CPOLYGONS_LIST polygon list - * Therefore we need conversion functions between these 2 descriptions - */ -void CopyPolygonsFromKiPolygonListToPolysList( KI_POLYGON_SET& aKiPolyList, - CPOLYGONS_LIST& aPolysList ) -{ - for( unsigned ii = 0; ii < aKiPolyList.size(); ii++ ) - { - KI_POLYGON& poly = aKiPolyList[ii]; - CPolyPt corner( 0, 0, false ); - - for( unsigned jj = 0; jj < poly.size(); jj++ ) - { - KI_POLY_POINT point = *(poly.begin() + jj); - corner.x = point.x(); - corner.y = point.y(); - corner.end_contour = false; - aPolysList.push_back( corner ); - } - - aPolysList.back().end_contour = true; - } -} - - -/** - * Helper function AddPolygonCornersToKiPolygonList - * This function adds a KI_POLYGON_SET description to a - * CPOLYGONS_LIST description - * @param aCornersBuffer = source (set of polygons using CPolyPt corners descr) - * @param aPolysList = destination (set of polygons) - */ -void AddPolygonCornersToKiPolygonList( CPOLYGONS_LIST& aCornersBuffer, - KI_POLYGON_SET& aKiPolyList ) -{ - std::vector cornerslist; - unsigned corners_count = aCornersBuffer.size(); - - // Count the number of polygons in aCornersBuffer - int polycount = 0; - - for( unsigned ii = 0; ii < corners_count; ii++ ) - { - if( aCornersBuffer[ii].end_contour ) - polycount++; - } - - aKiPolyList.reserve( polycount ); - - for( unsigned icnt = 0; icnt < corners_count; ) - { - KI_POLYGON poly; - cornerslist.clear(); - - unsigned ii; - - for( ii = icnt; ii < aCornersBuffer.size(); ii++ ) - { - 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() ); - aKiPolyList.push_back( poly ); - icnt = ii + 1; - } -} - /** * Function TransformCircleToPolygon diff --git a/include/convert_basic_shapes_to_polygon.h b/include/convert_basic_shapes_to_polygon.h index c7d99a8faa..00820c881f 100644 --- a/include/convert_basic_shapes_to_polygon.h +++ b/include/convert_basic_shapes_to_polygon.h @@ -35,33 +35,6 @@ #include #include -/** - * Helper function CopyPolygonsFromKiPolygonListToPolysList - * We are using a lots polygons in calculations. - * and we are using 2 descriptions, - * one easy to use with boost::polygon (KI_POLYGON_SET) - * one easy to use in zones and in draw functions (CPOLYGONS_LIST) - * Copy polygons from a KI_POLYGON_SET set of polygons to - * a CPOLYGONS_LIST corner polygon list - * Therefore we need conversion functions between these 2 descriptions - * This function converts a KI_POLYGON_SET description to a - * CPOLYGONS_LIST description - * @param aKiPolyList = source (set of polygons) - * @param aPolysList = destination (set of polygons using CPolyPt corners descr) - */ -void CopyPolygonsFromKiPolygonListToPolysList( KI_POLYGON_SET& aKiPolyList, - CPOLYGONS_LIST& aPolysList ); - -/** - * Helper function AddPolygonCornersToKiPolygonList - * This function adds a KI_POLYGON_SET description to a - * CPOLYGONS_LIST description - * @param aCornersBuffer = source (set of polygons using CPolyPt corners descr) - * @param aPolysList = destination (set of polygons) - */ -void AddPolygonCornersToKiPolygonList( CPOLYGONS_LIST& aCornersBuffer, - KI_POLYGON_SET& aKiPolyList ); - /** * Function TransformCircleToPolygon * convert a circle to a polygon, using multiple straight lines diff --git a/pcbnew/board_items_to_polygon_shape_transform.cpp b/pcbnew/board_items_to_polygon_shape_transform.cpp index f35b61916a..0d154cc3b9 100644 --- a/pcbnew/board_items_to_polygon_shape_transform.cpp +++ b/pcbnew/board_items_to_polygon_shape_transform.cpp @@ -177,8 +177,7 @@ void ZONE_CONTAINER::TransformSolidAreasShapesToPolygonSet( return; // add filled areas polygons - aCornerBuffer.insert( aCornerBuffer.end(), m_FilledPolysList.begin(), - m_FilledPolysList.end() ); + aCornerBuffer.Append( m_FilledPolysList ); // add filled areas outlines, which are drawn with thich lines wxPoint seg_start, seg_end; diff --git a/pcbnew/class_zone.cpp b/pcbnew/class_zone.cpp index 3c945e5e26..0082296d65 100644 --- a/pcbnew/class_zone.cpp +++ b/pcbnew/class_zone.cpp @@ -202,7 +202,7 @@ void ZONE_CONTAINER::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE aDrawMod { seg_start = GetCornerPosition( ic ) + offset; - if( m_Poly->m_CornersList[ic].end_contour == false && ic < GetNumCorners() - 1 ) + if( !m_Poly->m_CornersList.IsEndContour( ic ) && ic < GetNumCorners() - 1 ) { seg_end = GetCornerPosition( ic + 1 ) + offset; } @@ -283,16 +283,13 @@ void ZONE_CONTAINER::DrawFilledArea( EDA_DRAW_PANEL* panel, for( int ic = 0; ic <= imax; ic++ ) { - CPolyPt* corner = &m_FilledPolysList[ic]; - - wxPoint coord( corner->x + offset.x, corner->y + offset.y ); - + const CPolyPt& corner = m_FilledPolysList.GetCorner( ic ); + wxPoint coord( corner.x + offset.x, corner.y + offset.y ); CornersBuffer.push_back( coord ); - - CornersTypeBuffer.push_back( (char) corner->m_utility ); + CornersTypeBuffer.push_back( (char) corner.m_utility ); // the last corner of a filled area is found: draw it - if( (corner->end_contour) || (ic == imax) ) + if( (corner.end_contour) || (ic == imax) ) { /* Draw the current filled area: draw segments outline first * Curiously, draw segments outline first and after draw filled polygons @@ -418,13 +415,13 @@ void ZONE_CONTAINER::DrawWhileCreateOutline( EDA_DRAW_PANEL* panel, wxDC* DC, int yi = GetCornerPosition( ic ).y; int xf, yf; - if( m_Poly->m_CornersList[ic].end_contour == false && ic < icmax ) + if( !m_Poly->m_CornersList.IsEndContour( ic ) && ic < icmax ) { is_close_segment = false; xf = GetCornerPosition( ic + 1 ).x; yf = GetCornerPosition( ic + 1 ).y; - if( (m_Poly->m_CornersList[ic + 1].end_contour) || (ic == icmax - 1) ) + if( m_Poly->m_CornersList.IsEndContour( ic + 1 ) || (ic == icmax - 1) ) current_gr_mode = GR_XOR; else current_gr_mode = draw_mode; @@ -497,8 +494,8 @@ bool ZONE_CONTAINER::HitTestForCorner( const wxPoint& refPos ) for( unsigned item_pos = 0; item_pos < lim; item_pos++ ) { - delta.x = refPos.x - m_Poly->m_CornersList[item_pos].x; - delta.y = refPos.y - m_Poly->m_CornersList[item_pos].y; + delta.x = refPos.x - m_Poly->m_CornersList.GetX( item_pos ); + delta.y = refPos.y - m_Poly->m_CornersList.GetY( item_pos ); // Calculate a distance: int dist = std::max( abs( delta.x ), abs( delta.y ) ); @@ -533,7 +530,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->m_CornersList[item_pos].end_contour || end_segm >= lim ) + if( m_Poly->m_CornersList.IsEndContour ( item_pos ) || end_segm >= lim ) { unsigned tmp = first_corner_pos; first_corner_pos = end_segm; // first_corner_pos is now the beginning of the next outline @@ -541,13 +538,12 @@ bool ZONE_CONTAINER::HitTestForEdge( const wxPoint& refPos ) } // test the dist between segment and ref point - int dist = KiROUND( GetPointToLineSegmentDistance( - refPos.x, - refPos.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 ) ); + int dist = KiROUND( GetPointToLineSegmentDistance( + refPos.x, refPos.y, + m_Poly->m_CornersList.GetX( item_pos ), + m_Poly->m_CornersList.GetY( item_pos ), + m_Poly->m_CornersList.GetX( end_segm ), + m_Poly->m_CornersList.GetY( end_segm ) ) ); if( dist < min_dist ) { @@ -616,10 +612,10 @@ bool ZONE_CONTAINER::HitTestFilledArea( const wxPoint& aRefPos ) const for( indexend = 0; indexend < m_FilledPolysList.size(); indexend++ ) { - if( m_FilledPolysList[indexend].end_contour ) // end of a filled sub-area found + if( m_FilledPolysList.IsEndContour( indexend ) ) // end of a filled sub-area found { - if( TestPointInsidePolygon( m_FilledPolysList, indexstart, indexend, aRefPos.x, - aRefPos.y ) ) + if( TestPointInsidePolygon( m_FilledPolysList, indexstart, indexend, + aRefPos.x, aRefPos.y ) ) { inside = true; break; @@ -742,9 +738,8 @@ void ZONE_CONTAINER::Move( const wxPoint& offset ) /* move filled areas: */ for( unsigned ic = 0; ic < m_FilledPolysList.size(); ic++ ) { - CPolyPt* corner = &m_FilledPolysList[ic]; - corner->x += offset.x; - corner->y += offset.y; + m_FilledPolysList.SetX( ic, m_FilledPolysList.GetX( ic ) + offset.x ); + m_FilledPolysList.SetY( ic, m_FilledPolysList.GetX( ic ) + offset.y ); } for( unsigned ic = 0; ic < m_FillSegmList.size(); ic++ ) @@ -763,7 +758,7 @@ void ZONE_CONTAINER::MoveEdge( const wxPoint& offset ) SetCornerPosition( ii, GetCornerPosition( ii ) + offset ); // Move the end point of the selected edge: - if( m_Poly->m_CornersList[ii].end_contour || ii == GetNumCorners() - 1 ) + if( m_Poly->m_CornersList.IsEndContour( ii ) || ii == GetNumCorners() - 1 ) { int icont = m_Poly->GetContour( ii ); ii = m_Poly->GetContourStart( icont ); @@ -783,13 +778,12 @@ void ZONE_CONTAINER::Rotate( const wxPoint& centre, double angle ) { wxPoint pos; - for( unsigned ii = 0; ii < m_Poly->m_CornersList.size(); ii++ ) + for( unsigned ic = 0; ic < m_Poly->m_CornersList.size(); ic++ ) { - pos.x = m_Poly->m_CornersList[ii].x; - pos.y = m_Poly->m_CornersList[ii].y; + pos = m_Poly->m_CornersList.GetPos( ic ); RotatePoint( &pos, centre, angle ); - m_Poly->m_CornersList[ii].x = pos.x; - m_Poly->m_CornersList[ii].y = pos.y; + m_Poly->SetX( ic, pos.x ); + m_Poly->SetY( ic, pos.y ); } m_Poly->Hatch(); @@ -797,12 +791,10 @@ void ZONE_CONTAINER::Rotate( const wxPoint& centre, double angle ) /* rotate filled areas: */ for( unsigned ic = 0; ic < m_FilledPolysList.size(); ic++ ) { - CPolyPt* corner = &m_FilledPolysList[ic]; - pos.x = corner->x; - pos.y = corner->y; + pos = m_FilledPolysList.GetPos( ic ); RotatePoint( &pos, centre, angle ); - corner->x = pos.x; - corner->y = pos.y; + m_FilledPolysList.SetX( ic, pos.x ); + m_FilledPolysList.SetY( ic, pos.y ); } for( unsigned ic = 0; ic < m_FillSegmList.size(); ic++ ) @@ -822,11 +814,11 @@ void ZONE_CONTAINER::Flip( const wxPoint& aCentre ) void ZONE_CONTAINER::Mirror( const wxPoint& mirror_ref ) { - for( unsigned ii = 0; ii < m_Poly->m_CornersList.size(); ii++ ) + for( unsigned ic = 0; ic < m_Poly->m_CornersList.size(); ic++ ) { - 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; + int py = m_Poly->m_CornersList.GetY( ic ) - mirror_ref.y; + NEGATE( py ); + m_Poly->m_CornersList.SetY( ic, py + mirror_ref.y ); } m_Poly->Hatch(); @@ -834,10 +826,9 @@ void ZONE_CONTAINER::Mirror( const wxPoint& mirror_ref ) /* mirror filled areas: */ for( unsigned ic = 0; ic < m_FilledPolysList.size(); ic++ ) { - CPolyPt* corner = &m_FilledPolysList[ic]; - corner->y -= mirror_ref.y; - NEGATE( corner->y ); - corner->y += mirror_ref.y; + int py = m_FilledPolysList.GetY( ic ) - mirror_ref.y; + NEGATE( py ); + m_FilledPolysList.SetY( ic, py + mirror_ref.y ); } for( unsigned ic = 0; ic < m_FillSegmList.size(); ic++ ) diff --git a/pcbnew/class_zone.h b/pcbnew/class_zone.h index 9ac29f7c23..3a84b3ba5c 100644 --- a/pcbnew/class_zone.h +++ b/pcbnew/class_zone.h @@ -551,7 +551,7 @@ public: void AddFilledPolygon( CPOLYGONS_LIST& aPolygon ) { - m_FilledPolysList.insert( m_FilledPolysList.end(), aPolygon.begin(), aPolygon.end() ); + m_FilledPolysList.Append( aPolygon ); } void AddFillSegments( std::vector< SEGMENT >& aSegments ) diff --git a/pcbnew/kicad_plugin.cpp b/pcbnew/kicad_plugin.cpp index 5cc305c81b..20eb72a3a9 100644 --- a/pcbnew/kicad_plugin.cpp +++ b/pcbnew/kicad_plugin.cpp @@ -1403,14 +1403,14 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const m_out->Print( aNestLevel+1, "(polygon\n"); m_out->Print( aNestLevel+2, "(pts\n" ); - for( CPOLYGONS_LIST::const_iterator it = cv.begin(); it != cv.end(); ++it ) + for( unsigned it = 0; it < cv.size(); ++it ) { if( newLine == 0 ) m_out->Print( aNestLevel+3, "(xy %s %s)", - FMT_IU( it->x ).c_str(), FMT_IU( it->y ).c_str() ); + FMT_IU( cv.GetX( it ) ).c_str(), FMT_IU( cv.GetY( it ) ).c_str() ); else m_out->Print( 0, " (xy %s %s)", - FMT_IU( it->x ).c_str(), FMT_IU( it->y ).c_str() ); + FMT_IU( cv.GetX( it ) ).c_str(), FMT_IU( cv.GetY( it ) ).c_str() ); if( newLine < 4 ) { @@ -1422,14 +1422,14 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const m_out->Print( 0, "\n" ); } - if( it->end_contour ) + if( cv.IsEndContour( it ) ) { if( newLine != 0 ) m_out->Print( 0, "\n" ); m_out->Print( aNestLevel+2, ")\n" ); - if( it+1 != cv.end() ) + if( it+1 != cv.size() ) { newLine = 0; m_out->Print( aNestLevel+1, ")\n" ); @@ -1451,14 +1451,14 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const m_out->Print( aNestLevel+1, "(filled_polygon\n" ); m_out->Print( aNestLevel+2, "(pts\n" ); - for( CPOLYGONS_LIST::const_iterator it = fv.begin(); it != fv.end(); ++it ) + for( unsigned it = 0; it < fv.size(); ++it ) { if( newLine == 0 ) m_out->Print( aNestLevel+3, "(xy %s %s)", - FMT_IU( it->x ).c_str(), FMT_IU( it->y ).c_str() ); + FMT_IU( fv.GetX( it ) ).c_str(), FMT_IU( fv.GetY( it ) ).c_str() ); else m_out->Print( 0, " (xy %s %s)", - FMT_IU( it->x ).c_str(), FMT_IU( it->y ).c_str() ); + FMT_IU( fv.GetX( it ) ).c_str(), FMT_IU( fv.GetY( it ) ).c_str() ); if( newLine < 4 ) { @@ -1470,14 +1470,14 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const m_out->Print( 0, "\n" ); } - if( it->end_contour ) + if( fv.IsEndContour( it ) ) { if( newLine != 0 ) m_out->Print( 0, "\n" ); m_out->Print( aNestLevel+2, ")\n" ); - if( it+1 != fv.end() ) + if( it+1 != fv.size() ) { newLine = 0; m_out->Print( aNestLevel+1, ")\n" ); diff --git a/pcbnew/legacy_plugin.cpp b/pcbnew/legacy_plugin.cpp index d5d8719c8d..091b9f7176 100644 --- a/pcbnew/legacy_plugin.cpp +++ b/pcbnew/legacy_plugin.cpp @@ -3693,11 +3693,11 @@ void LEGACY_PLUGIN::saveZONE_CONTAINER( const ZONE_CONTAINER* me ) const // Save the corner list const CPOLYGONS_LIST& cv = me->Outline()->m_CornersList; - for( CPOLYGONS_LIST::const_iterator it = cv.begin(); it != cv.end(); ++it ) + for( unsigned it = 0; it < cv.size(); ++it ) { fprintf( m_fp, "ZCorner %s %d\n", - fmtBIUPair( it->x, it->y ).c_str(), - it->end_contour ); + fmtBIUPair( cv.GetX( it ), cv.GetY( it ) ).c_str(), + cv.IsEndContour( it ) ); } // Save the PolysList @@ -3706,12 +3706,12 @@ void LEGACY_PLUGIN::saveZONE_CONTAINER( const ZONE_CONTAINER* me ) const { fprintf( m_fp, "$POLYSCORNERS\n" ); - for( CPOLYGONS_LIST::const_iterator it = fv.begin(); it != fv.end(); ++it ) + for( unsigned it = 0; it < fv.size(); ++it ) { fprintf( m_fp, "%s %d %d\n", - fmtBIUPair( it->x, it->y ).c_str(), - it->end_contour, - it->m_utility ); + fmtBIUPair( fv.GetX( it ), fv.GetY( it ) ).c_str(), + fv.IsEndContour( it ), + fv.GetUtility( it ) ); } fprintf( m_fp, "$endPOLYSCORNERS\n" ); diff --git a/pcbnew/plot_board_layers.cpp b/pcbnew/plot_board_layers.cpp index 3661f9cc9a..a20e33fde7 100644 --- a/pcbnew/plot_board_layers.cpp +++ b/pcbnew/plot_board_layers.cpp @@ -52,9 +52,6 @@ #include #include -// Imported function -extern void AddPolygonCornersToKiPolygonList( CPOLYGONS_LIST& aCornersBuffer, - KI_POLYGON_SET& aKiPolyList ); // Local /* Plot a solder mask layer. * Solder mask layers have a minimum thickness value and cannot be drawn like standard layers, @@ -581,9 +578,9 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter, // having a thickness < aMinThickness // 2 - deflate resulting areas by aMinThickness/2 KI_POLYGON_SET areasToMerge; - AddPolygonCornersToKiPolygonList( bufferPolys, areasToMerge ); + bufferPolys.ExportTo( areasToMerge ); KI_POLYGON_SET initialAreas; - AddPolygonCornersToKiPolygonList( initialPolys, initialAreas ); + initialPolys.ExportTo( initialAreas ); // Merge polygons: because each shape was created with an extra margin // = aMinThickness/2, shapes too close ( dist < aMinThickness ) diff --git a/pcbnew/plot_brditems_plotter.cpp b/pcbnew/plot_brditems_plotter.cpp index b087af1a97..02c8a5f771 100644 --- a/pcbnew/plot_brditems_plotter.cpp +++ b/pcbnew/plot_brditems_plotter.cpp @@ -528,10 +528,10 @@ void BRDITEMS_PLOTTER::PlotFilledAreas( ZONE_CONTAINER* aZone ) */ for( unsigned ic = 0; ic < imax; ic++ ) { - const CPolyPt& corner = polysList[ic]; - cornerList.push_back( wxPoint( corner.x, corner.y) ); + wxPoint pos = polysList.GetPos( ic ); + cornerList.push_back( pos ); - if( corner.end_contour ) // Plot the current filled area outline + if( polysList.IsEndContour( ic ) ) // Plot the current filled area outline { // First, close the outline if( cornerList[0] != cornerList[cornerList.size() - 1] ) 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 b5acf10555..5418c55220 100644 --- a/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp +++ b/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp @@ -417,7 +417,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) if( cornerBufferPolysToSubstract.size() > 0 ) { KI_POLYGON_SET polyset_holes; - AddPolygonCornersToKiPolygonList( cornerBufferPolysToSubstract, polyset_holes ); + cornerBufferPolysToSubstract.ExportTo( polyset_holes ); // Remove holes from initial area.: polyset_zone_solid_areas -= polyset_holes; } @@ -443,7 +443,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) if( cornerBufferPolysToSubstract.size() ) { KI_POLYGON_SET polyset_holes; - AddPolygonCornersToKiPolygonList( cornerBufferPolysToSubstract, polyset_holes ); + cornerBufferPolysToSubstract.ExportTo( polyset_holes ); // Remove unconnected stubs polyset_zone_solid_areas -= polyset_holes; @@ -463,11 +463,11 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) void ZONE_CONTAINER::CopyPolygonsFromKiPolygonListToFilledPolysList( KI_POLYGON_SET& aKiPolyList ) { m_FilledPolysList.clear(); - CopyPolygonsFromKiPolygonListToPolysList( aKiPolyList, m_FilledPolysList ); + m_FilledPolysList.ImportFrom( aKiPolyList ); } void ZONE_CONTAINER::CopyPolygonsFromFilledPolysListToKiPolygonList( KI_POLYGON_SET& aKiPolyList ) { - AddPolygonCornersToKiPolygonList( m_FilledPolysList, aKiPolyList ); + m_FilledPolysList.ExportTo( aKiPolyList ); } diff --git a/pcbnew/zones_convert_to_polygons_aux_functions.cpp b/pcbnew/zones_convert_to_polygons_aux_functions.cpp index e46a7ff152..9498cffbec 100644 --- a/pcbnew/zones_convert_to_polygons_aux_functions.cpp +++ b/pcbnew/zones_convert_to_polygons_aux_functions.cpp @@ -107,9 +107,7 @@ void ZONE_CONTAINER::TransformOutlinesShapeWithClearanceToPolygon( aCornerBuffer.push_back( corner ); } - corner.end_contour = true; - aCornerBuffer.pop_back(); - aCornerBuffer.push_back( corner ); + aCornerBuffer.back().end_contour = true; } } diff --git a/pcbnew/zones_functions_for_undo_redo.cpp b/pcbnew/zones_functions_for_undo_redo.cpp index 922e955c41..52166bc5db 100644 --- a/pcbnew/zones_functions_for_undo_redo.cpp +++ b/pcbnew/zones_functions_for_undo_redo.cpp @@ -115,7 +115,8 @@ bool ZONE_CONTAINER::IsSame( const ZONE_CONTAINER& aZoneToCompare ) wxASSERT( m_Poly ); // m_Poly == NULL Should never happen wxASSERT( aZoneToCompare.Outline() ); - if( Outline()->m_CornersList != aZoneToCompare.Outline()->m_CornersList ) // Compare vector + if( Outline()->m_CornersList.GetList() != + aZoneToCompare.Outline()->m_CornersList.GetList() ) // Compare vector return false; return true; diff --git a/pcbnew/zones_polygons_insulated_copper_islands.cpp b/pcbnew/zones_polygons_insulated_copper_islands.cpp index 2b1cfa9369..214508d9f9 100644 --- a/pcbnew/zones_polygons_insulated_copper_islands.cpp +++ b/pcbnew/zones_polygons_insulated_copper_islands.cpp @@ -108,9 +108,7 @@ void ZONE_CONTAINER::TestForCopperIslandAndRemoveInsulatedIslands( BOARD* aPcb ) } else // Not connected: remove this polygon { - m_FilledPolysList.erase( m_FilledPolysList.begin() + indexstart, - m_FilledPolysList.begin() + indexend + 1 ); - + m_FilledPolysList.DeleteCorners( indexstart, indexend ); indexend = indexstart; /* indexstart points the first point of the next polygon * because the current poly is removed */ } diff --git a/pcbnew/zones_polygons_test_connections.cpp b/pcbnew/zones_polygons_test_connections.cpp index d85fe4979c..6b0bd80582 100644 --- a/pcbnew/zones_polygons_test_connections.cpp +++ b/pcbnew/zones_polygons_test_connections.cpp @@ -147,7 +147,7 @@ void BOARD::Test_Connections_To_Copper_Areas( int aNetcode ) for( indexend = 0; indexend < polysList.size(); indexend++ ) { // end of a filled sub-area found - if( polysList[indexend].end_contour ) + if( polysList.IsEndContour( indexend ) ) { subnet++; EDA_RECT bbox = curr_zone->CalculateSubAreaBoundaryBox( indexstart, indexend ); diff --git a/pcbnew/zones_test_and_combine_areas.cpp b/pcbnew/zones_test_and_combine_areas.cpp index ed20b1e3e3..6896d355a7 100644 --- a/pcbnew/zones_test_and_combine_areas.cpp +++ b/pcbnew/zones_test_and_combine_areas.cpp @@ -295,8 +295,8 @@ bool BOARD::CombineAreas( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_ // polygons intersect, combine them KI_POLYGON_WITH_HOLES areaRefPoly; KI_POLYGON_WITH_HOLES areaToMergePoly; - CopyPolysListToKiPolygonWithHole( area_ref->Outline()->m_CornersList, areaRefPoly ); - CopyPolysListToKiPolygonWithHole( area_to_combine->Outline()->m_CornersList, areaToMergePoly ); + area_ref->Outline()->m_CornersList.ExportTo( areaRefPoly ); + area_to_combine->Outline()->m_CornersList.ExportTo( areaToMergePoly ); KI_POLYGON_WITH_HOLES_SET mergedOutlines; mergedOutlines.push_back( areaRefPoly ); diff --git a/polygon/PolyLine.cpp b/polygon/PolyLine.cpp index c174c983b9..652cedeb2e 100644 --- a/polygon/PolyLine.cpp +++ b/polygon/PolyLine.cpp @@ -111,7 +111,7 @@ int CPolyLine::NormalizeAreaOutlines( std::vector* aNewPolygonList ) ClipperLib::Polygon& polygon = normalized_polygons[ii]; cornerslist.clear(); for( unsigned jj = 0; jj < polygon.size(); jj++ ) - cornerslist.push_back( KI_POLY_POINT( KiROUND( polygon[jj].X ), + cornerslist.push_back( KI_POLY_POINT( KiROUND( polygon[jj].X ), KiROUND( polygon[jj].Y ) ) ); mainpoly.set( cornerslist.begin(), cornerslist.end() ); all_contours.push_back( mainpoly ); @@ -138,7 +138,7 @@ int CPolyLine::NormalizeAreaOutlines( std::vector* aNewPolygonList ) ClipperLib::Polygon& polygon = normalized_polygons[ii]; cornerslist.clear(); for( unsigned jj = 0; jj < polygon.size(); jj++ ) - cornerslist.push_back( KI_POLY_POINT( KiROUND( polygon[jj].X ), + cornerslist.push_back( KI_POLY_POINT( KiROUND( polygon[jj].X ), KiROUND( polygon[jj].Y ) ) ); bpl::set_points( poly_tmp, cornerslist.begin(), cornerslist.end() ); polysholes.push_back( poly_tmp ); @@ -232,15 +232,6 @@ void CPolyLine::AppendCorner( int x, int y ) m_CornersList.push_back( poly_pt ); } - -// close last polyline contour -// -void CPolyLine::CloseLastContour() -{ - m_CornersList[m_CornersList.size() - 1].end_contour = true; -} - - // move corner of polyline // void CPolyLine::MoveCorner( int ic, int x, int y ) @@ -264,12 +255,12 @@ void CPolyLine::DeleteCorner( int ic ) if( !closed ) { // open contour, must be last contour - m_CornersList.erase( m_CornersList.begin() + ic ); + m_CornersList.DeleteCorner( ic ); } else { // closed contour - m_CornersList.erase( m_CornersList.begin() + ic ); + m_CornersList.DeleteCorner( ic ); if( ic == iend ) m_CornersList[ic - 1].end_contour = true; @@ -304,17 +295,12 @@ void CPolyLine::RemoveContour( int icont ) // remove the only contour wxASSERT( 0 ); } - else if( icont == polycount - 1 ) - { - // remove last contour - m_CornersList.erase( m_CornersList.begin() + istart, m_CornersList.end() ); - } else { // remove closed contour for( int ic = iend; ic>=istart; ic-- ) { - m_CornersList.erase( m_CornersList.begin() + ic ); + m_CornersList.DeleteCorner( ic ); } } @@ -555,7 +541,7 @@ void CPolyLine::InsertCorner( int ic, int x, int y ) } else { - m_CornersList.insert( m_CornersList.begin() + ic + 1, CPolyPt( x, y ) ); + m_CornersList.InsertCorner(ic, CPolyPt( x, y ) ); } if( (unsigned) (ic + 1) < m_CornersList.size() ) @@ -632,21 +618,12 @@ CRect CPolyLine::GetCornerBounds( int icont ) } -int CPolyLine::GetNumCorners() +int CPolyLine::GetNumCorners() const { return m_CornersList.size(); } -int CPolyLine::GetNumSides() -{ - if( GetClosed() ) - return m_CornersList.size(); - else - return m_CornersList.size() - 1; -} - - int CPolyLine::GetContoursCount() { int ncont = 0; @@ -958,8 +935,8 @@ bool CPolyLine::TestPointInside( int px, int py ) int istart = GetContourStart( icont ); int iend = GetContourEnd( icont ); - // Test this polygon: - if( TestPointInsidePolygon( m_CornersList, istart, iend, px, py ) ) // test point inside the current polygon + // test point inside the current polygon + if( TestPointInsidePolygon( m_CornersList, istart, iend, px, py ) ) inside = not inside; } @@ -1009,28 +986,6 @@ void CPolyLine::MoveOrigin( int x_off, int y_off ) Hatch(); } - -// Set various parameters: -// the calling function should UnHatch() before calling them, -// and Draw() after -// -void CPolyLine::SetX( int ic, int x ) -{ - m_CornersList[ic].x = x; -} - - -void CPolyLine::SetY( int ic, int y ) -{ - m_CornersList[ic].y = y; -} - - -void CPolyLine::SetEndContour( int ic, bool end_contour ) -{ - m_CornersList[ic].end_contour = end_contour; -} - /* * AppendArc: * adds segments to current contour to approximate the given arc @@ -1040,7 +995,7 @@ void CPolyLine::AppendArc( int xi, int yi, int xf, int yf, int xc, int yc, int n // get radius double radius = ::Distance( xi, yi, xf, yf ); - // get angles of start and finish + // get angles of start pint and end point double th_i = atan2( (double) (yi - yc), (double) (xi - xc) ); double th_f = atan2( (double) (yf - yc), (double) (xf - xc) ); double th_d = (th_f - th_i) / (num - 1); @@ -1199,17 +1154,13 @@ int CPolyLine::Distance( const wxPoint& aPoint ) } -/** - * 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 +/* + * Copy the contours to a KI_POLYGON_WITH_HOLES + * The first contour is the main outline, others are holes */ -void CopyPolysListToKiPolygonWithHole( const CPOLYGONS_LIST& aPolysList, - KI_POLYGON_WITH_HOLES& aPolygoneWithHole ) +void CPOLYGONS_LIST::ExportTo( KI_POLYGON_WITH_HOLES& aPolygoneWithHole ) { - unsigned corners_count = aPolysList.size(); + unsigned corners_count = m_cornersList.size(); std::vector cornerslist; KI_POLYGON poly; @@ -1219,7 +1170,7 @@ void CopyPolysListToKiPolygonWithHole( const CPOLYGONS_LIST& aPolysList, while( ic < corners_count ) { - const CPolyPt& corner = aPolysList[ic++]; + const CPolyPt& corner = GetCorner( ic++ ); cornerslist.push_back( KI_POLY_POINT( corner.x, corner.y ) ); if( corner.end_contour ) @@ -1239,10 +1190,9 @@ void CopyPolysListToKiPolygonWithHole( const CPOLYGONS_LIST& aPolysList, while( ic < corners_count ) { - const CPolyPt& corner = aPolysList[ic++]; - cornerslist.push_back( KI_POLY_POINT( corner.x, corner.y ) ); + cornerslist.push_back( KI_POLY_POINT( GetX( ic ), GetY( ic ) ) ); - if( corner.end_contour ) + if( IsEndContour( ic ) ) break; } @@ -1254,6 +1204,74 @@ void CopyPolysListToKiPolygonWithHole( const CPOLYGONS_LIST& aPolysList, } } +/** + * Copy all contours to a KI_POLYGON_SET aPolygons + * Each contour is copied into a KI_POLYGON, and each KI_POLYGON + * is append to aPolygons + */ +void CPOLYGONS_LIST::ExportTo( KI_POLYGON_SET& aPolygons ) +{ + std::vector cornerslist; + unsigned corners_count = GetCornersCount(); + + // Count the number of polygons in aCornersBuffer + int polycount = 0; + + for( unsigned ii = 0; ii < corners_count; ii++ ) + { + if( IsEndContour( ii ) ) + polycount++; + } + + aPolygons.reserve( polycount ); + + for( unsigned icnt = 0; icnt < corners_count; ) + { + KI_POLYGON poly; + cornerslist.clear(); + + unsigned ii; + + for( ii = icnt; ii < corners_count; ii++ ) + { + cornerslist.push_back( KI_POLY_POINT( GetX( ii ), GetY( ii ) ) ); + + if( IsEndContour( ii ) ) + break; + } + + bpl::set_points( poly, cornerslist.begin(), cornerslist.end() ); + aPolygons.push_back( poly ); + icnt = ii + 1; + } +} + + +/* Imports all polygons found in a KI_POLYGON_SET in list + */ +void CPOLYGONS_LIST::ImportFrom( KI_POLYGON_SET& aPolygons ) +{ + CPolyPt corner; + + for( unsigned ii = 0; ii < aPolygons.size(); ii++ ) + { + KI_POLYGON& poly = aPolygons[ii]; + + for( unsigned jj = 0; jj < poly.size(); jj++ ) + { + KI_POLY_POINT point = *(poly.begin() + jj); + corner.x = point.x(); + corner.y = point.y(); + corner.end_contour = false; + AddCorner( corner ); + } + + CloseLastContour(); + } +} + + + /** * Function ConvertPolysListWithHolesToOnePolygon * converts the outline contours aPolysListWithHoles with holes to one polygon @@ -1271,9 +1289,7 @@ void ConvertPolysListWithHolesToOnePolygon( const CPOLYGONS_LIST& aPolysListWith int polycount = 0; for( unsigned ii = 0; ii < corners_count; ii++ ) { - const CPolyPt& corner = aPolysListWithHoles[ii]; - - if( corner.end_contour ) + if( aPolysListWithHoles.IsEndContour( ii ) ) polycount++; } @@ -1295,7 +1311,7 @@ void ConvertPolysListWithHolesToOnePolygon( const CPOLYGONS_LIST& aPolysListWith // enter main outline while( ic < corners_count ) { - const CPolyPt& corner = aPolysListWithHoles[ic++]; + const CPolyPt& corner = aPolysListWithHoles.GetCorner( ic++ ); cornerslist.push_back( KI_POLY_POINT( corner.x, corner.y ) ); if( corner.end_contour ) @@ -1310,7 +1326,7 @@ void ConvertPolysListWithHolesToOnePolygon( const CPOLYGONS_LIST& aPolysListWith { while( ic < corners_count ) { - const CPolyPt& corner = aPolysListWithHoles[ic++]; + const CPolyPt& corner = aPolysListWithHoles.GetCorner( ic++ ); cornerslist.push_back( KI_POLY_POINT( corner.x, corner.y ) ); if( corner.end_contour ) @@ -1337,10 +1353,10 @@ void ConvertPolysListWithHolesToOnePolygon( const CPOLYGONS_LIST& aPolysListWith corner.x = point.x(); corner.y = point.y(); corner.end_contour = false; - aOnePolyList.push_back( corner ); + aOnePolyList.AddCorner( corner ); } - aOnePolyList.back().end_contour = true; + aOnePolyList.CloseLastContour(); } /** diff --git a/polygon/PolyLine.h b/polygon/PolyLine.h index cd62ed264c..0dff5e88b9 100644 --- a/polygon/PolyLine.h +++ b/polygon/PolyLine.h @@ -77,13 +77,129 @@ public: }; /** - * CPOLYGONS_LIST handle a list of contours. - * Each contour is a polygon, i.e. a list of corners. + * CPOLYGONS_LIST handle a list of contours (polygons corners). * Each corner is a CPolyPt item. * The last cornet of each contour has its end_contour member = true */ -typedef std::vector CPOLYGONS_LIST; +class CPOLYGONS_LIST +{ +private: + std::vector m_cornersList; // array of points for corners +public: + CPOLYGONS_LIST() {}; + CPolyPt& operator [](int aIdx) {return m_cornersList[aIdx]; } + + // Accessor: + const std::vector & GetList() const {return m_cornersList;} + int GetX( int ic ) const { return m_cornersList[ic].x; } + void SetX( int ic, int aValue ) { m_cornersList[ic].x = aValue; } + int GetY( int ic ) const { return m_cornersList[ic].y; } + void SetY( int ic, int aValue ) { m_cornersList[ic].y = aValue; } + int GetUtility( int ic ) const { return m_cornersList[ic].m_utility; } + void SetFlag( int ic, int aFlag ) + { + m_cornersList[ic].m_utility = aFlag; + } + + bool IsEndContour( int ic ) const + { + return m_cornersList[ic].end_contour; + } + + void SetEndContour( int ic, bool end_contour ) + { + m_cornersList[ic].end_contour = end_contour; + } + + const wxPoint& GetPos( int ic ) const { return m_cornersList[ic]; } + const CPolyPt& GetCorner( int ic ) const { return m_cornersList[ic]; } + + // vector <> methods + void reserve( int aSize ) { m_cornersList.reserve( aSize ); } + void clear() { m_cornersList.clear(); } + unsigned size() const { return m_cornersList.size(); } + void push_back( const CPolyPt& aItem ) { m_cornersList.push_back( aItem ); } + CPolyPt& back() { return m_cornersList.back(); } + + unsigned GetCornersCount() const { return m_cornersList.size(); } + + void DeleteCorner( int aIdx ) + { + m_cornersList.erase( m_cornersList.begin() + aIdx ); + } + + void DeleteCorners( int aIdFirstCorner, int aIdLastCorner ) + { + m_cornersList.erase( m_cornersList.begin() + aIdFirstCorner, + m_cornersList.begin() + aIdLastCorner + 1 ); + } + + void Append( const CPOLYGONS_LIST& aList ) + { + m_cornersList.insert( m_cornersList.end(), + aList.m_cornersList.begin(), + aList.m_cornersList.end() ); + } + + void Append( const CPolyPt& aItem ) + { + m_cornersList.push_back( aItem ); + } + + void Append( const wxPoint& aItem ) + { + CPolyPt item( aItem ); + + m_cornersList.push_back( aItem ); + } + + void InsertCorner( int aPosition, const CPolyPt& aItem ) + { + m_cornersList.insert( m_cornersList.begin() + aPosition + 1, aItem ); + } + + /** + * Function ExportTo + * Copy all contours to a KI_POLYGON_SET + * @param aPolygons = the KI_POLYGON_WITH_HOLES to populate + */ + void ExportTo( KI_POLYGON_SET& aPolygons ); + + /** + * Function ExportTo + * Copy the contours to a KI_POLYGON_WITH_HOLES + * The first contour is the main outline, others are holes + * @param aPolygoneWithHole = the KI_POLYGON_WITH_HOLES to populate + */ + void ExportTo( KI_POLYGON_WITH_HOLES& aPolygoneWithHole ); + + /** + * Function ImportFrom + * Copy all polygons from a KI_POLYGON_SET in list + * @param aPolygons = the KI_POLYGON_SET to import + */ + void ImportFrom( KI_POLYGON_SET& aPolygons ); + + /** + * function AddCorner + * add a corner to the list + */ + void AddCorner( const CPolyPt& aCorner ) + { + m_cornersList.push_back( aCorner ); + } + + /** + * function CloseLastContour + * Set the .end_contour member of the last corner in list to true + */ + void CloseLastContour() + { + if( m_cornersList.size() > 0 ) + m_cornersList.back().end_contour = true; + } +}; class CPolyLine { @@ -99,7 +215,7 @@ public: * Copy settings (layer, hatch styles) from aPoly * @param aPoly is the CPolyLine to import settings */ - void ImportSettings( const CPolyLine * aPoly ); + void ImportSettings( const CPolyLine* aPoly ); // functions for modifying the CPolyLine contours @@ -117,9 +233,19 @@ public: * keep the controur closed by modifying the previous corner * @param ic = the index of the corner to delete */ - void DeleteCorner ( int ic ); + void DeleteCorner( int ic ); void MoveCorner( int ic, int x, int y ); - void CloseLastContour(); + + /** + * function CloseLastContour + * Set the .end_contour member of the last corner + * of the last contour to true + */ + void CloseLastContour() + { + m_CornersList.CloseLastContour(); + } + void RemoveContour( int icont ); /** @@ -132,7 +258,7 @@ public: * When a CPolyLine is self intersectic, it need to be normalized. * (converted to non intersecting polygons) */ - bool IsPolygonSelfIntersecting(); + bool IsPolygonSelfIntersecting(); /** * Function Chamfer @@ -157,7 +283,7 @@ public: * (i.e. when 2 successive corners are at the same location) * @return the count of removed corners. */ - int RemoveNullSegments(); + int RemoveNullSegments(); void RemoveAllContours( void ); @@ -185,24 +311,25 @@ public: // access functions void SetLayer( LAYER_NUM aLayer ) { m_layer = aLayer; } LAYER_NUM GetLayer() const { return m_layer; } - int GetNumCorners(); - int GetNumSides(); - int GetClosed(); - int GetContoursCount(); - int GetContour( int ic ); - int GetContourStart( int icont ); - int GetContourEnd( int icont ); - int GetContourSize( int icont ); + int GetNumCorners() const; + int GetClosed(); + int GetContoursCount(); + int GetContour( int ic ); + int GetContourStart( int icont ); + int GetContourEnd( int icont ); + int GetContourSize( int icont ); - int GetX( int ic ) const { return m_CornersList[ic].x; } - int GetY( int ic ) const { return m_CornersList[ic].y; } + int GetX( int ic ) const { return m_CornersList.GetX( ic ); } + int GetY( int ic ) const { return m_CornersList.GetY( ic ); } + bool IsEndContour( int ic ) const + { return m_CornersList.IsEndContour( ic ); } - const wxPoint& GetPos( int ic ) const { return m_CornersList[ic]; } + const wxPoint& GetPos( int ic ) const { return m_CornersList.GetPos( ic ); } - int GetEndContour( int ic ); + int GetEndContour( int ic ); - int GetUtility( int ic ) const { return m_CornersList[ic].m_utility; }; - void SetUtility( int ic, int utility ) { m_CornersList[ic].m_utility = utility; }; + int GetUtility( int ic ) const { return m_CornersList.GetUtility( ic ); }; + void SetUtility( int ic, int aFlag ) { m_CornersList.SetFlag( ic, aFlag ); }; int GetHatchPitch() const { return m_hatchPitch; } static int GetDefaultHatchPitchMils() { return 20; } // default hatch pitch value in mils @@ -212,13 +339,25 @@ public: { SetHatchPitch( aHatchPitch ); m_hatchStyle = (enum HATCH_STYLE) aHatchStyle; + if( aRebuildHatch ) Hatch(); } - void SetX( int ic, int x ); - void SetY( int ic, int y ); - void SetEndContour( int ic, bool end_contour ); + void SetX( int ic, int x ) + { + m_CornersList.SetX( ic, x ); + } + + void SetY( int ic, int y ) + { + m_CornersList.SetY( ic, y ); + } + + void SetEndContour( int ic, bool end_contour ) + { + m_CornersList.SetEndContour( ic, end_contour ); + } void SetHatchStyle( enum HATCH_STYLE style ) { @@ -235,7 +374,7 @@ public: * @return the polygon count (always >= 1, because there is at least one polygon) * There are new polygons only if the polygon count is > 1 */ - int NormalizeAreaOutlines( std::vector* aNewPolygonList ); + int NormalizeAreaOutlines( std::vector* aNewPolygonList ); // Bezier Support void AppendBezier( int x1, int y1, int x2, int y2, int x3, int y3 ); @@ -262,39 +401,28 @@ public: int Distance( wxPoint aStart, wxPoint aEnd, int aWidth ); private: - LAYER_NUM m_layer; // layer to draw on - 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 m_utility; // a flag used in some calculations - + LAYER_NUM m_layer; // layer to draw on + 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 m_utility; // a flag used in some calculations public: - CPOLYGONS_LIST m_CornersList; // array of points for corners - std::vector m_HatchLines; // hatch lines showing the polygon area + CPOLYGONS_LIST m_CornersList; // array of points for corners + std::vector m_HatchLines; // hatch lines showing the polygon area }; -/** - * 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 CPOLYGONS_LIST& aPolysList, - KI_POLYGON_WITH_HOLES& aPolygoneWithHole ); - - /** * Function ConvertPolysListWithHolesToOnePolygon * converts the outline contours aPolysListWithHoles with holes to one polygon * with no holes (only one contour) * holes are linked to main outlines by overlap segments, to give only one polygon * - * @param aPolysListWithHoles = the list of corners of contours (haing holes + * @param aPolysListWithHoles = the list of corners of contours + * (main outline and holes) * @param aOnePolyList = a polygon with no holes */ -void ConvertPolysListWithHolesToOnePolygon( const CPOLYGONS_LIST& aPolysListWithHoles, - CPOLYGONS_LIST& aOnePolyList ); +void ConvertPolysListWithHolesToOnePolygon( const CPOLYGONS_LIST& aPolysListWithHoles, + CPOLYGONS_LIST& aOnePolyList ); #endif // #ifndef POLYLINE_H diff --git a/polygon/polygon_test_point_inside.cpp b/polygon/polygon_test_point_inside.cpp index 6ae8204c37..aafade407c 100644 --- a/polygon/polygon_test_point_inside.cpp +++ b/polygon/polygon_test_point_inside.cpp @@ -26,11 +26,11 @@ #define OUTSIDE false #define INSIDE true -bool TestPointInsidePolygon( CPOLYGONS_LIST aPolysList, - int aIdxstart, - int aIdxend, - int aRefx, - int aRefy) +bool TestPointInsidePolygon( const CPOLYGONS_LIST& aPolysList, + int aIdxstart, + int aIdxend, + int aRefx, + int aRefy) /** * Function TestPointInsidePolygon @@ -50,10 +50,10 @@ bool TestPointInsidePolygon( CPOLYGONS_LIST aPolysList, // find all intersection points of line with polyline sides for( ics = aIdxstart, ice = aIdxend; ics <= aIdxend; ice = ics++ ) { - int seg_startX = aPolysList[ics].x; - int seg_startY = aPolysList[ics].y; - int seg_endX = aPolysList[ice].x; - int seg_endY = aPolysList[ice].y; + int seg_startX = aPolysList.GetX( ics ); + int seg_startY = aPolysList.GetY( ics ); + int seg_endX = aPolysList.GetX( ice ); + int seg_endY = aPolysList.GetY( ice ); /* Trivial cases: skip if ref above or below the segment to test */ if( ( seg_startY > aRefy ) && (seg_endY > aRefy ) ) diff --git a/polygon/polygon_test_point_inside.h b/polygon/polygon_test_point_inside.h index 6669e6762b..90117dd2d4 100644 --- a/polygon/polygon_test_point_inside.h +++ b/polygon/polygon_test_point_inside.h @@ -19,11 +19,11 @@ public: * @param aRefx, aRefy: the point coordinate to test * @return true if the point is inside, false for outside */ -bool TestPointInsidePolygon( std::vector aPolysList, - int aIdxstart, - int aIdxend, - int aRefx, - int aRefy); +bool TestPointInsidePolygon( const CPOLYGONS_LIST& aPolysList, + int aIdxstart, + int aIdxend, + int aRefx, + int aRefy); /** * Function TestPointInsidePolygon (overlaid) * same as previous, but mainly use wxPoint