diff --git a/common/geometry/shape_collisions.cpp b/common/geometry/shape_collisions.cpp index 98a2857340..3cd1ccbd4c 100644 --- a/common/geometry/shape_collisions.cpp +++ b/common/geometry/shape_collisions.cpp @@ -248,9 +248,7 @@ static inline bool Collide( const SHAPE_RECT& aA, const SHAPE_LINE_CHAIN& aB, in { for( int s = 0; s < aB.SegmentCount(); s++ ) { - SEG seg = aB.CSegment( s ); - - if( aA.Collide( seg, aClearance ) ) + if( aA.Collide( aB.CSegment( s ), aClearance ) ) return true; } diff --git a/common/geometry/shape_poly_set.cpp b/common/geometry/shape_poly_set.cpp index 4e3c75a362..a0d141b205 100644 --- a/common/geometry/shape_poly_set.cpp +++ b/common/geometry/shape_poly_set.cpp @@ -192,6 +192,8 @@ int SHAPE_POLY_SET::NewHole( int aOutline ) int SHAPE_POLY_SET::Append( int x, int y, int aOutline, int aHole, bool aAllowDuplication ) { + assert( m_polys.size() ); + if( aOutline < 0 ) aOutline += m_polys.size(); @@ -273,25 +275,6 @@ SHAPE_POLY_SET SHAPE_POLY_SET::Subset( int aFirstPolygon, int aLastPolygon ) } -VECTOR2I& SHAPE_POLY_SET::Vertex( int aIndex, int aOutline, int aHole ) -{ - if( aOutline < 0 ) - aOutline += m_polys.size(); - - int idx; - - if( aHole < 0 ) - idx = 0; - else - idx = aHole + 1; - - assert( aOutline < (int) m_polys.size() ); - assert( idx < (int) m_polys[aOutline].size() ); - - return m_polys[aOutline][idx].Point( aIndex ); -} - - const VECTOR2I& SHAPE_POLY_SET::CVertex( int aIndex, int aOutline, int aHole ) const { if( aOutline < 0 ) @@ -311,18 +294,6 @@ const VECTOR2I& SHAPE_POLY_SET::CVertex( int aIndex, int aOutline, int aHole ) c } -VECTOR2I& SHAPE_POLY_SET::Vertex( int aGlobalIndex ) -{ - SHAPE_POLY_SET::VERTEX_INDEX index; - - // Assure the passed index references a legal position; abort otherwise - if( !GetRelativeIndices( aGlobalIndex, &index ) ) - throw( std::out_of_range( "aGlobalIndex-th vertex does not exist" ) ); - - return m_polys[index.m_polygon][index.m_contour].Point( index.m_vertex ); -} - - const VECTOR2I& SHAPE_POLY_SET::CVertex( int aGlobalIndex ) const { SHAPE_POLY_SET::VERTEX_INDEX index; @@ -335,12 +306,6 @@ const VECTOR2I& SHAPE_POLY_SET::CVertex( int aGlobalIndex ) const } -VECTOR2I& SHAPE_POLY_SET::Vertex( SHAPE_POLY_SET::VERTEX_INDEX index ) -{ - return Vertex( index.m_vertex, index.m_polygon, index.m_contour - 1 ); -} - - const VECTOR2I& SHAPE_POLY_SET::CVertex( SHAPE_POLY_SET::VERTEX_INDEX index ) const { return CVertex( index.m_vertex, index.m_polygon, index.m_contour - 1 ); @@ -1444,6 +1409,23 @@ void SHAPE_POLY_SET::RemoveVertex( VERTEX_INDEX aIndex ) } +void SHAPE_POLY_SET::SetVertex( int aGlobalIndex, const VECTOR2I& aPos ) +{ + VERTEX_INDEX index; + + if( GetRelativeIndices( aGlobalIndex, &index ) ) + SetVertex( index, aPos ); + else + throw( std::out_of_range( "aGlobalIndex-th vertex does not exist" ) ); +} + + +void SHAPE_POLY_SET::SetVertex( const VERTEX_INDEX& aIndex, const VECTOR2I& aPos ) +{ + m_polys[aIndex.m_polygon][aIndex.m_contour].SetPoint( aIndex.m_vertex, aPos ); +} + + bool SHAPE_POLY_SET::containsSingle( const VECTOR2I& aP, int aSubpolyIndex, int aAccuracy, bool aUseBBoxCaches ) const { @@ -1478,6 +1460,18 @@ void SHAPE_POLY_SET::Move( const VECTOR2I& aVector ) } +void SHAPE_POLY_SET::Mirror( bool aX, bool aY, const VECTOR2I& aRef ) +{ + for( POLYGON& poly : m_polys ) + { + for( SHAPE_LINE_CHAIN& path : poly ) + { + path.Mirror( aX, aY, aRef ); + } + } +} + + void SHAPE_POLY_SET::Rotate( double aAngle, const VECTOR2I& aCenter ) { for( POLYGON& poly : m_polys ) @@ -1676,8 +1670,8 @@ SHAPE_POLY_SET::POLYGON SHAPE_POLY_SET::chamferFilletPolygon( CORNER_MODE aMode, for( int currVertex = 0; currVertex < currContour.PointCount(); currVertex++ ) { // Current vertex - int x1 = currContour.Point( currVertex ).x; - int y1 = currContour.Point( currVertex ).y; + int x1 = currContour.CPoint( currVertex ).x; + int y1 = currContour.CPoint( currVertex ).y; if( aPreserveCorners && aPreserveCorners->count( VECTOR2I( x1, y1 ) ) > 0 ) { @@ -1698,12 +1692,12 @@ SHAPE_POLY_SET::POLYGON SHAPE_POLY_SET::chamferFilletPolygon( CORNER_MODE aMode, nextVertex = currVertex == currContour.PointCount() - 1 ? 0 : currVertex + 1; // Previous vertex computation - double xa = currContour.Point( prevVertex ).x - x1; - double ya = currContour.Point( prevVertex ).y - y1; + double xa = currContour.CPoint( prevVertex ).x - x1; + double ya = currContour.CPoint( prevVertex ).y - y1; // Next vertex computation - double xb = currContour.Point( nextVertex ).x - x1; - double yb = currContour.Point( nextVertex ).y - y1; + double xb = currContour.CPoint( nextVertex ).x - x1; + double yb = currContour.CPoint( nextVertex ).y - y1; // Compute the new distances double lena = hypot( xa, ya ); diff --git a/common/gr_basic.cpp b/common/gr_basic.cpp index 6d14ecfc4c..0ae89bf3c0 100644 --- a/common/gr_basic.cpp +++ b/common/gr_basic.cpp @@ -71,8 +71,7 @@ static const bool NOT_FILLED = false; GR_DRAWMODE g_XorMode = GR_NXOR; -static void ClipAndDrawPoly( EDA_RECT * ClipBox, wxDC * DC, wxPoint Points[], - int n ); +static void ClipAndDrawPoly( EDA_RECT* ClipBox, wxDC* DC, const wxPoint* Points, int n ); /* These functions are used by corresponding functions * ( GRSCircle is called by GRCircle for instance) after mapping coordinates @@ -428,7 +427,7 @@ void GRFilledSegment( EDA_RECT* aClipBox, wxDC* aDC, wxPoint aStart, wxPoint aEn } -static bool IsGRSPolyDrawable( EDA_RECT* ClipBox, int n, wxPoint Points[] ) +static bool IsGRSPolyDrawable( EDA_RECT* ClipBox, int n, const wxPoint* Points, ) { if( !ClipBox ) return true; @@ -470,9 +469,8 @@ static bool IsGRSPolyDrawable( EDA_RECT* ClipBox, int n, wxPoint Points[] ) /* * Draw a new polyline and fill it if Fill, in screen space. */ -static void GRSPoly( EDA_RECT* ClipBox, wxDC* DC, int n, wxPoint Points[], - bool Fill, int width, - COLOR4D Color, COLOR4D BgColor ) +static void GRSPoly( EDA_RECT* ClipBox, wxDC* DC, int n, const wxPoint* Points, bool Fill, + int width, COLOR4D Color, COLOR4D BgColor ) { if( !IsGRSPolyDrawable( ClipBox, n, Points ) ) return; @@ -503,11 +501,8 @@ static void GRSPoly( EDA_RECT* ClipBox, wxDC* DC, int n, wxPoint Points[], /* * Draw a new closed polyline and fill it if Fill, in screen space. */ -static void GRSClosedPoly( EDA_RECT* aClipBox, wxDC* aDC, - int aPointCount, wxPoint aPoints[], - bool aFill, int aWidth, - COLOR4D aColor, - COLOR4D aBgColor ) +static void GRSClosedPoly( EDA_RECT* aClipBox, wxDC* aDC, int aPointCount, const wxPoint* aPoints, + bool aFill, int aWidth, COLOR4D aColor, COLOR4D aBgColor ) { if( !IsGRSPolyDrawable( aClipBox, aPointCount, aPoints ) ) return; @@ -543,8 +538,8 @@ static void GRSClosedPoly( EDA_RECT* aClipBox, wxDC* aDC, /* * Draw a new polyline and fill it if Fill, in drawing space. */ -void GRPoly( EDA_RECT* ClipBox, wxDC* DC, int n, wxPoint Points[], - bool Fill, int width, COLOR4D Color, COLOR4D BgColor ) +void GRPoly( EDA_RECT* ClipBox, wxDC* DC, int n, const wxPoint* Points, bool Fill, int width, + COLOR4D Color, COLOR4D BgColor ) { GRSPoly( ClipBox, DC, n, Points, Fill, width, Color, BgColor ); } @@ -553,15 +548,15 @@ void GRPoly( EDA_RECT* ClipBox, wxDC* DC, int n, wxPoint Points[], /* * Draw a closed polyline and fill it if Fill, in object space. */ -void GRClosedPoly( EDA_RECT* ClipBox, wxDC* DC, int n, wxPoint Points[], - bool Fill, COLOR4D Color, COLOR4D BgColor ) +void GRClosedPoly( EDA_RECT* ClipBox, wxDC* DC, int n, const wxPoint* Points, bool Fill, + COLOR4D Color, COLOR4D BgColor ) { GRClosedPoly( ClipBox, DC, n, Points, Fill, 0, Color, BgColor ); } -void GRClosedPoly( EDA_RECT* ClipBox, wxDC* DC, int n, wxPoint Points[], - bool Fill, int width, COLOR4D Color, COLOR4D BgColor ) +void GRClosedPoly( EDA_RECT* ClipBox, wxDC* DC, int n, const wxPoint* Points, bool Fill, int width, + COLOR4D Color, COLOR4D BgColor ) { GRSClosedPoly( ClipBox, DC, n, Points, Fill, width, Color, BgColor ); } @@ -958,7 +953,7 @@ void GRSFilledRect( EDA_RECT* aClipBox, wxDC* aDC, int x1, int y1, int x2, int y */ #include -void ClipAndDrawPoly( EDA_RECT* aClipBox, wxDC* aDC, wxPoint aPoints[], int n ) +void ClipAndDrawPoly( EDA_RECT* aClipBox, wxDC* aDC, const wxPoint* Points, int n ) { if( aClipBox == NULL ) { diff --git a/common/page_layout/ws_draw_item.cpp b/common/page_layout/ws_draw_item.cpp index 0a437a1f0c..4ab2ef2c51 100644 --- a/common/page_layout/ws_draw_item.cpp +++ b/common/page_layout/ws_draw_item.cpp @@ -200,8 +200,8 @@ void WS_DRAW_ITEM_POLYPOLYGONS::PrintWsItem( wxDC* aDC, const wxPoint& aOffset, SHAPE_LINE_CHAIN& outline = m_Polygons.Outline( idx ); for( int ii = 0; ii < outline.PointCount(); ii++ ) - points_moved.emplace_back( outline.Point( ii ).x + aOffset.x, - outline.Point( ii ).y + aOffset.y ); + points_moved.emplace_back( + outline.CPoint( ii ).x + aOffset.x, outline.CPoint( ii ).y + aOffset.y ); GRPoly( nullptr, aDC, points_moved.size(), &points_moved[0], FILLED_SHAPE, GetPenWidth(), aColor, aColor ); diff --git a/common/plotters/DXF_plotter.cpp b/common/plotters/DXF_plotter.cpp index 0e7a85366b..d9f721c466 100644 --- a/common/plotters/DXF_plotter.cpp +++ b/common/plotters/DXF_plotter.cpp @@ -777,12 +777,12 @@ void DXF_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize // TransformRoundRectToPolygon creates only one convex polygon SHAPE_LINE_CHAIN& poly = outline.Outline( 0 ); - MoveTo( wxPoint( poly.Point( 0 ).x, poly.Point( 0 ).y ) ); + MoveTo( wxPoint( poly.CPoint( 0 ).x, poly.CPoint( 0 ).y ) ); for( int ii = 1; ii < poly.PointCount(); ++ii ) - LineTo( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) ); + LineTo( wxPoint( poly.CPoint( ii ).x, poly.CPoint( ii ).y ) ); - FinishTo( wxPoint( poly.Point( 0 ).x, poly.Point( 0 ).y ) ); + FinishTo( wxPoint( poly.CPoint( 0 ).x, poly.CPoint( 0 ).y ) ); } void DXF_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize, @@ -793,12 +793,12 @@ void DXF_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize, { SHAPE_LINE_CHAIN& poly = aPolygons->Outline( cnt ); - MoveTo( wxPoint( poly.Point( 0 ).x, poly.Point( 0 ).y ) ); + MoveTo( wxPoint( poly.CPoint( 0 ).x, poly.CPoint( 0 ).y ) ); for( int ii = 1; ii < poly.PointCount(); ++ii ) - LineTo( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) ); + LineTo( wxPoint( poly.CPoint( ii ).x, poly.CPoint( ii ).y ) ); - FinishTo(wxPoint( poly.Point( 0 ).x, poly.Point( 0 ).y ) ); + FinishTo( wxPoint( poly.CPoint( 0 ).x, poly.CPoint( 0 ).y ) ); } } diff --git a/common/plotters/GERBER_plotter.cpp b/common/plotters/GERBER_plotter.cpp index 8b46ad44b9..235723136c 100644 --- a/common/plotters/GERBER_plotter.cpp +++ b/common/plotters/GERBER_plotter.cpp @@ -902,7 +902,7 @@ void GERBER_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aS cornerList.reserve( poly.PointCount() + 1 ); for( int ii = 0; ii < poly.PointCount(); ++ii ) - cornerList.emplace_back( poly.Point( ii ).x, poly.Point( ii ).y ); + cornerList.emplace_back( poly.CPoint( ii ).x, poly.CPoint( ii ).y ); // Close polygon cornerList.push_back( cornerList[0] ); @@ -942,7 +942,7 @@ void GERBER_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize cornerList.clear(); for( int ii = 0; ii < poly.PointCount(); ++ii ) - cornerList.emplace_back( poly.Point( ii ).x, poly.Point( ii ).y ); + cornerList.emplace_back( poly.CPoint( ii ).x, poly.CPoint( ii ).y ); // Close polygon cornerList.push_back( cornerList[0] ); diff --git a/common/plotters/HPGL_plotter.cpp b/common/plotters/HPGL_plotter.cpp index 284338cf1b..399f0583ff 100644 --- a/common/plotters/HPGL_plotter.cpp +++ b/common/plotters/HPGL_plotter.cpp @@ -650,7 +650,7 @@ void HPGL_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSiz cornerList.reserve( poly.PointCount() ); for( int ii = 0; ii < poly.PointCount(); ++ii ) - cornerList.emplace_back( poly.Point( ii ).x, poly.Point( ii ).y ); + cornerList.emplace_back( poly.CPoint( ii ).x, poly.CPoint( ii ).y ); if( cornerList.back() != cornerList.front() ) cornerList.push_back( cornerList.front() ); @@ -672,7 +672,7 @@ void HPGL_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize, cornerList.reserve( poly.PointCount() ); for( int ii = 1; ii < poly.PointCount(); ++ii ) - cornerList.emplace_back( poly.Point( ii ).x, poly.Point( ii ).y ); + cornerList.emplace_back( poly.CPoint( ii ).x, poly.CPoint( ii ).y ); if( cornerList.back() != cornerList.front() ) cornerList.push_back( cornerList.front() ); diff --git a/common/plotters/PS_plotter.cpp b/common/plotters/PS_plotter.cpp index 95e1a88f11..68cbbdb44f 100644 --- a/common/plotters/PS_plotter.cpp +++ b/common/plotters/PS_plotter.cpp @@ -209,7 +209,7 @@ void PSLIKE_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aS cornerList.reserve( poly.PointCount() ); for( int ii = 0; ii < poly.PointCount(); ++ii ) - cornerList.emplace_back( poly.Point( ii ).x, poly.Point( ii ).y ); + cornerList.emplace_back( poly.CPoint( ii ).x, poly.CPoint( ii ).y ); // Close polygon cornerList.push_back( cornerList[0] ); @@ -242,7 +242,7 @@ void PSLIKE_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize cornerList.clear(); for( int ii = 0; ii < poly.PointCount(); ++ii ) - cornerList.emplace_back( poly.Point( ii ).x, poly.Point( ii ).y ); + cornerList.emplace_back( poly.CPoint( ii ).x, poly.CPoint( ii ).y ); // Close polygon cornerList.push_back( cornerList[0] ); diff --git a/common/plotters/common_plot_functions.cpp b/common/plotters/common_plot_functions.cpp index 4b5cf5f0d1..3e9c8d0a7c 100644 --- a/common/plotters/common_plot_functions.cpp +++ b/common/plotters/common_plot_functions.cpp @@ -126,8 +126,7 @@ void PlotWorkSheet( PLOTTER* plotter, const TITLE_BLOCK& aTitleBlock, SHAPE_LINE_CHAIN& outline = poly->GetPolygons().Outline( idx ); for( int ii = 0; ii < outline.PointCount(); ii++ ) - points.emplace_back( outline.Point( ii ).x , - outline.Point( ii ).y ); + points.emplace_back( outline.CPoint( ii ).x, outline.CPoint( ii ).y ); plotter->PlotPoly( points, FILLED_SHAPE, poly->GetPenWidth() ); } diff --git a/common/swig/kicad.i b/common/swig/kicad.i index 8f1b30c24b..04ffb65354 100644 --- a/common/swig/kicad.i +++ b/common/swig/kicad.i @@ -141,7 +141,6 @@ typedef long time_t; // ignore warning from nested classes #pragma SWIG nowarn=325 -%ignore SHAPE_LINE_CHAIN::convertFromClipper; #include %include diff --git a/gerbview/am_primitive.cpp b/gerbview/am_primitive.cpp index a31667480b..2fade5ff93 100644 --- a/gerbview/am_primitive.cpp +++ b/gerbview/am_primitive.cpp @@ -836,8 +836,8 @@ void APERTURE_MACRO::DrawApertureMacroShape( GERBER_DRAW_ITEM* aParent, { SHAPE_LINE_CHAIN& poly = shapeBuffer->Outline( ii ); - GRClosedPoly( aClipBox, aDC, - poly.PointCount(), (wxPoint*)&poly.Point( 0 ), aFilledShape, aColor, aColor ); + GRClosedPoly( aClipBox, aDC, poly.PointCount(), (wxPoint*) &poly.CPoint( 0 ), aFilledShape, + aColor, aColor ); } } diff --git a/gerbview/dcode.cpp b/gerbview/dcode.cpp index dbf63e32c2..975bd3fc7d 100644 --- a/gerbview/dcode.cpp +++ b/gerbview/dcode.cpp @@ -279,7 +279,7 @@ void D_CODE::DrawFlashedPolygon( GERBER_DRAW_ITEM* aParent, for( int ii = 0; ii < pointCount; ii++ ) { - wxPoint p( m_Polygon.Vertex( ii ).x, m_Polygon.Vertex( ii ).y ); + wxPoint p( m_Polygon.CVertex( ii ).x, m_Polygon.CVertex( ii ).y ); points[ii] = p + aPosition; points[ii] = aParent->GetABPosition( points[ii] ); } diff --git a/gerbview/export_to_pcbnew.cpp b/gerbview/export_to_pcbnew.cpp index 59ebce744f..e54a1f18ab 100644 --- a/gerbview/export_to_pcbnew.cpp +++ b/gerbview/export_to_pcbnew.cpp @@ -546,7 +546,7 @@ void GBR_TO_PCB_EXPORTER::writePcbPolygonItem( GERBER_DRAW_ITEM* aGbrItem, LAYER int cnt_max = poly.PointCount() -1; // Do not generate last corner, if it is the same point as the first point: - if( poly.Point( 0 ) == poly.Point( cnt_max ) ) + if( poly.CPoint( 0 ) == poly.CPoint( cnt_max ) ) cnt_max--; for( int ii = 0; ii <= cnt_max; ii++ ) @@ -557,9 +557,8 @@ void GBR_TO_PCB_EXPORTER::writePcbPolygonItem( GERBER_DRAW_ITEM* aGbrItem, LAYER fprintf( m_fp, "\n" ); } - fprintf( m_fp, " (xy %s %s)", - Double2Str( MapToPcbUnits( poly.Point( ii ).x ) ).c_str(), - Double2Str( MapToPcbUnits( -poly.Point( ii ).y ) ).c_str() ); + fprintf( m_fp, " (xy %s %s)", Double2Str( MapToPcbUnits( poly.CPoint( ii ).x ) ).c_str(), + Double2Str( MapToPcbUnits( -poly.CPoint( ii ).y ) ).c_str() ); } fprintf( m_fp, ")" ); diff --git a/gerbview/gerber_draw_item.cpp b/gerbview/gerber_draw_item.cpp index 0d541b7c29..b3ad616778 100644 --- a/gerbview/gerber_draw_item.cpp +++ b/gerbview/gerber_draw_item.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 1992-2017 - * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -413,11 +413,7 @@ void GERBER_DRAW_ITEM::MoveAB( const wxPoint& aMoveVector ) m_End += xymove; m_ArcCentre += xymove; - if( m_Polygon.OutlineCount() > 0 ) - { - for( auto it = m_Polygon.Iterate( 0 ); it; ++it ) - *it += xymove; - } + m_Polygon.Move( VECTOR2I( xymove ) ); } @@ -427,11 +423,7 @@ void GERBER_DRAW_ITEM::MoveXY( const wxPoint& aMoveVector ) m_End += aMoveVector; m_ArcCentre += aMoveVector; - if( m_Polygon.OutlineCount() > 0 ) - { - for( auto it = m_Polygon.Iterate( 0 ); it; ++it ) - *it += aMoveVector; - } + m_Polygon.Move( VECTOR2I( aMoveVector ) ); } @@ -624,13 +616,10 @@ void GERBER_DRAW_ITEM::ConvertSegmentToPolygon() m_Polygon.Append( VECTOR2I( close ) ); // close the shape // Create final polygon: - for( auto it = m_Polygon.Iterate( 0 ); it; ++it ) - { - if( change ) - ( *it ).y = -( *it ).y; + if( change ) + m_Polygon.Mirror( false, true ); - *it += start; - } + m_Polygon.Move( VECTOR2I( start ) ); } @@ -645,7 +634,7 @@ void GERBER_DRAW_ITEM::PrintGerberPoly( wxDC* aDC, COLOR4D aColor, const wxPoint for( int ii = 0; ii < pointCount; ii++ ) { - wxPoint p( poly.Point( ii ).x, poly.Point( ii ).y ); + wxPoint p( poly.CPoint( ii ).x, poly.CPoint( ii ).y ); points[ii] = p + aOffset; points[ii] = GetABPosition( points[ii] ); } @@ -798,7 +787,7 @@ bool GERBER_DRAW_ITEM::HitTest( const wxPoint& aRefPos, int aAccuracy ) const case GBR_SPOT_POLY: poly = GetDcodeDescr()->m_Polygon; - poly.Move( m_Start ); + poly.Move( VECTOR2I( m_Start ) ); return poly.Contains( VECTOR2I( ref_pos ), 0, aAccuracy ); case GBR_SPOT_RECT: diff --git a/gerbview/gerbview_painter.cpp b/gerbview/gerbview_painter.cpp index a77d02db98..95fe37bfa3 100644 --- a/gerbview/gerbview_painter.cpp +++ b/gerbview/gerbview_painter.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -253,10 +254,16 @@ void GERBVIEW_PAINTER::draw( /*const*/ GERBER_DRAW_ITEM* aItem, int aLayer ) if( !isFilled ) m_gal->SetLineWidth( m_gerbviewSettings.m_outlineWidth ); - SHAPE_POLY_SET absolutePolygon = aItem->m_Polygon; + std::vector pts = aItem->m_Polygon.COutline( 0 ).CPoints(); - for( auto it = absolutePolygon.Iterate( 0 ); it; ++it ) - *it = aItem->GetABPosition( *it ); + for( auto& pt : pts ) + pt = aItem->GetABPosition( pt ); + + + SHAPE_POLY_SET absolutePolygon; + SHAPE_LINE_CHAIN chain( pts ); + chain.SetClosed( true ); + absolutePolygon.AddOutline( chain ); // Degenerated polygons (having < 3 points) are drawn as lines // to avoid issues in draw polygon functions @@ -362,7 +369,8 @@ void GERBVIEW_PAINTER::draw( /*const*/ GERBER_DRAW_ITEM* aItem, int aLayer ) { if( aItem->m_Polygon.OutlineCount() == 0 ) aItem->ConvertSegmentToPolygon(); - drawPolygon( aItem, aItem->m_Polygon, isFilled ); + + drawPolygon( aItem, code, isFilled ); } else { @@ -392,23 +400,25 @@ void GERBVIEW_PAINTER::draw( /*const*/ GERBER_DRAW_ITEM* aItem, int aLayer ) } -void GERBVIEW_PAINTER::drawPolygon( GERBER_DRAW_ITEM* aParent, - SHAPE_POLY_SET& aPolygon, - bool aFilled ) +void GERBVIEW_PAINTER::drawPolygon( + GERBER_DRAW_ITEM* aParent, D_CODE* aCode, bool aFilled, bool aShift ) { - for( auto it = aPolygon.Iterate( 0 ); it; ++it ) - *it = aParent->GetABPosition( *it ); + SHAPE_POLY_SET poly; + auto& pts = aCode->m_Polygon.COutline( 0 ).CPoints(); + VECTOR2I offset = aShift ? VECTOR2I( aParent->m_Start ) : VECTOR2I( 0, 0 ); + + for( auto& pt : pts ) + poly.Append( aParent->GetABPosition( pt + offset ) ); if( !m_gerbviewSettings.m_polygonFill ) m_gal->SetLineWidth( m_gerbviewSettings.m_outlineWidth ); if( !aFilled ) { - for( int i = 0; i < aPolygon.OutlineCount(); i++ ) - m_gal->DrawPolyline( aPolygon.COutline( i ) ); + m_gal->DrawPolyline( poly.COutline( 0 ) ); } else - m_gal->DrawPolygon( aPolygon ); + m_gal->DrawPolygon( poly ); } @@ -442,9 +452,9 @@ void GERBVIEW_PAINTER::drawFlashedShape( GERBER_DRAW_ITEM* aItem, bool aFilled ) code->ConvertShapeToPolygon(); SHAPE_POLY_SET poly = code->m_Polygon; - poly.Move( aItem->m_Start ); + poly.Move( VECTOR2I( aItem->m_Start ) ); - drawPolygon( aItem, poly, aFilled ); + drawPolygon( aItem, code, aFilled ); } break; @@ -469,10 +479,7 @@ void GERBVIEW_PAINTER::drawFlashedShape( GERBER_DRAW_ITEM* aItem, bool aFilled ) if( code->m_Polygon.OutlineCount() == 0 ) code->ConvertShapeToPolygon(); - SHAPE_POLY_SET poly = code->m_Polygon; - poly.Move( aItem->m_Start ); - - drawPolygon( aItem, poly, aFilled ); + drawPolygon( aItem, code, aFilled ); } break; } @@ -511,10 +518,7 @@ void GERBVIEW_PAINTER::drawFlashedShape( GERBER_DRAW_ITEM* aItem, bool aFilled ) if( code->m_Polygon.OutlineCount() == 0 ) code->ConvertShapeToPolygon(); - SHAPE_POLY_SET poly = code->m_Polygon; - poly.Move( aItem->m_Start ); - - drawPolygon( aItem, poly, aFilled ); + drawPolygon( aItem, code, aFilled ); } break; } @@ -524,10 +528,7 @@ void GERBVIEW_PAINTER::drawFlashedShape( GERBER_DRAW_ITEM* aItem, bool aFilled ) if( code->m_Polygon.OutlineCount() == 0 ) code->ConvertShapeToPolygon(); - SHAPE_POLY_SET poly = code->m_Polygon; - poly.Move( aItem->m_Start ); - - drawPolygon( aItem, poly, aFilled ); + drawPolygon( aItem, code, aFilled ); break; } diff --git a/gerbview/gerbview_painter.h b/gerbview/gerbview_painter.h index cb281a4192..00ff26602c 100644 --- a/gerbview/gerbview_painter.h +++ b/gerbview/gerbview_painter.h @@ -23,6 +23,8 @@ #include #include + +#include #include #include @@ -191,8 +193,14 @@ protected: // Drawing functions void draw( /*const*/ GERBER_DRAW_ITEM* aVia, int aLayer ); - /// Helper routine to draw a polygon - void drawPolygon( GERBER_DRAW_ITEM* aParent, SHAPE_POLY_SET& aPolygon, bool aFilled ); + /** + * Helper routine to draw a polygon + * @param aParent Pointer to the draw item for AB Position calculation + * @param aCode Flash code pointer + * @param aFilled If true, draw the polygon as filled, otherwise only outline + * @param aShift If true, draw the polygon relative to the parent item position + */ + void drawPolygon( GERBER_DRAW_ITEM* aParent, D_CODE* aCode, bool aFilled, bool aShift = false ); /// Helper to draw a flashed shape (aka spot) void drawFlashedShape( GERBER_DRAW_ITEM* aItem, bool aFilled ); diff --git a/gerbview/rs274d.cpp b/gerbview/rs274d.cpp index 24c2141c0a..6acb231f9c 100644 --- a/gerbview/rs274d.cpp +++ b/gerbview/rs274d.cpp @@ -555,7 +555,7 @@ bool GERBER_FILE_IMAGE::Execute_G_Command( char*& text, int G_command ) if( m_Exposure && GetItemsList() ) // End of polygon { GERBER_DRAW_ITEM * gbritem = m_Drawings.GetLast(); - gbritem->m_Polygon.Append( gbritem->m_Polygon.Vertex( 0 ) ); + gbritem->m_Polygon.Append( gbritem->m_Polygon.CVertex( 0 ) ); StepAndRepeatItem( *gbritem ); } m_Exposure = false; @@ -670,7 +670,7 @@ bool GERBER_FILE_IMAGE::Execute_DCODE_Command( char*& text, int D_commande ) if( m_Exposure && GetItemsList() ) // End of polygon { gbritem = m_Drawings.GetLast(); - gbritem->m_Polygon.Append( gbritem->m_Polygon.Vertex( 0 ) ); + gbritem->m_Polygon.Append( gbritem->m_Polygon.CVertex( 0 ) ); StepAndRepeatItem( *gbritem ); } m_Exposure = false; diff --git a/include/geometry/poly_grid_partition.h b/include/geometry/poly_grid_partition.h index f23eea6558..a449ff1f97 100644 --- a/include/geometry/poly_grid_partition.h +++ b/include/geometry/poly_grid_partition.h @@ -177,7 +177,7 @@ enum HASH_FLAG for( int i = 0; i& aV ) : SHAPE( SH_LINE_CHAIN ), m_closed( false ) @@ -138,6 +136,13 @@ public: m_points.emplace_back( pt.x, pt.y ); } + SHAPE_LINE_CHAIN( const std::vector& aV ) : + SHAPE( SH_LINE_CHAIN ), + m_closed( false ) + { + m_points = aV; + } + SHAPE_LINE_CHAIN( const ClipperLib::Path& aPath ) : SHAPE( SH_LINE_CHAIN ), m_closed( true ) @@ -252,22 +257,22 @@ public: } /** - * Function Point() - * - * Returns a reference to a given point in the line chain. - * @param aIndex index of the point - * @return reference to the point + * Accessor Function to move a point to a specific location + * @param aIndex Index (wrapping) of the point to move + * @param aPos New absolute location of the point */ - VECTOR2I& Point( int aIndex ) + void SetPoint( int aIndex, const VECTOR2I& aPos ) { if( aIndex < 0 ) aIndex += PointCount(); + else if( aIndex >= PointCount() ) + aIndex -= PointCount(); - return m_points[aIndex]; + m_points[aIndex] = aPos; } /** - * Function CPoint() + * Function Point() * * Returns a const reference to a given point in the line chain. * @param aIndex index of the point @@ -288,14 +293,6 @@ public: return m_points; } - /** - * Returns the last point in the line chain. - */ - VECTOR2I& LastPoint() - { - return m_points[PointCount() - 1]; - } - /** * Returns the last point in the line chain. */ @@ -618,13 +615,6 @@ public: */ SHAPE_LINE_CHAIN& Simplify(); - /** - * Function convertFromClipper() - * Appends the Clipper path to the current SHAPE_LINE_CHAIN - * - */ - void convertFromClipper( const ClipperLib::Path& aPath ); - /** * Creates a new Clipper path from the SHAPE_LINE_CHAIN in a given orientation * @@ -678,13 +668,31 @@ public: (*i) += aVector; } + /** + * Mirrors the line points about y or x (or both) + * @param aX If true, mirror about the y axis (flip X coordinate) + * @param aY If true, mirror about the x axis (flip Y coordinate) + * @param aRef sets the reference point about which to mirror + */ + void Mirror( bool aX = true, bool aY = false, const VECTOR2I& aRef = { 0, 0 } ) + { + for( auto& pt : m_points ) + { + if( aX ) + pt.x = -pt.x + 2 * aRef.x; + + if( aY ) + pt.y = -pt.y + 2 * aRef.y; + } + } + /** * Function Rotate * rotates all vertices by a given angle * @param aCenter is the rotation center * @param aAngle rotation angle in radians */ - void Rotate( double aAngle, const VECTOR2I& aCenter ); + void Rotate( double aAngle, const VECTOR2I& aCenter = VECTOR2I( 0, 0 ) ); bool IsSolid() const override { diff --git a/include/geometry/shape_poly_set.h b/include/geometry/shape_poly_set.h index f8e15a865f..8d89827068 100644 --- a/include/geometry/shape_poly_set.h +++ b/include/geometry/shape_poly_set.h @@ -229,17 +229,18 @@ class SHAPE_POLY_SET : public SHAPE Advance(); } - T& Get() + const T& Get() { - return m_poly->Polygon( m_currentPolygon )[m_currentContour].Point( m_currentVertex ); + return m_poly->Polygon( m_currentPolygon )[m_currentContour].CPoint( + m_currentVertex ); } - T& operator*() + const T& operator*() { return Get(); } - T* operator->() + const T* operator->() { return &Get(); } @@ -508,21 +509,12 @@ class SHAPE_POLY_SET : public SHAPE */ void InsertVertex( int aGlobalIndex, VECTOR2I aNewVertex ); - ///> Returns the index-th vertex in a given hole outline within a given outline - VECTOR2I& Vertex( int aIndex, int aOutline, int aHole ); - ///> Returns the index-th vertex in a given hole outline within a given outline const VECTOR2I& CVertex( int aIndex, int aOutline, int aHole ) const; - ///> Returns the aGlobalIndex-th vertex in the poly set - VECTOR2I& Vertex( int aGlobalIndex ); - ///> Returns the aGlobalIndex-th vertex in the poly set const VECTOR2I& CVertex( int aGlobalIndex ) const; - ///> Returns the index-th vertex in a given hole outline within a given outline - VECTOR2I& Vertex( VERTEX_INDEX aIndex ); - ///> Returns the index-th vertex in a given hole outline within a given outline const VECTOR2I& CVertex( VERTEX_INDEX aIndex ) const; @@ -938,13 +930,21 @@ class SHAPE_POLY_SET : public SHAPE /// @copydoc SHAPE::Move() void Move( const VECTOR2I& aVector ) override; + /** + * Mirrors the line points about y or x (or both) + * @param aX If true, mirror about the y axis (flip x coordinate) + * @param aY If true, mirror about the x axis + * @param aRef sets the reference point about which to mirror + */ + void Mirror( bool aX = true, bool aY = false, const VECTOR2I& aRef = { 0, 0 } ); + /** * Function Rotate * rotates all vertices by a given angle * @param aCenter is the rotation center * @param aAngle rotation angle in radians */ - void Rotate( double aAngle, const VECTOR2I& aCenter ); + void Rotate( double aAngle, const VECTOR2I& aCenter = { 0, 0 } ); /// @copydoc SHAPE::IsSolid() bool IsSolid() const override @@ -1075,6 +1075,22 @@ class SHAPE_POLY_SET : public SHAPE */ int RemoveNullSegments(); + /** + * Function SetVertex + * Accessor function to set the position of a specific point + * @param aIndex VERTEX_INDEX of the point to move + * @param aPos destination position of the specified point + */ + void SetVertex( const VERTEX_INDEX& aIndex, const VECTOR2I& aPos ); + + /** + * Sets the vertex based on the global index. Throws if the index + * doesn't exist + * @param aGlobalIndex global index of the to-be-moved vertex + * @param aPos New position on the vertex + */ + void SetVertex( int aGlobalIndex, const VECTOR2I& aPos ); + ///> Returns total number of vertices stored in the set. int TotalVertices() const; diff --git a/include/geometry/shape_simple.h b/include/geometry/shape_simple.h index 3d735809f6..dded08ea94 100644 --- a/include/geometry/shape_simple.h +++ b/include/geometry/shape_simple.h @@ -90,20 +90,6 @@ public: /** * Function Point() * - * Returns a reference to a given point in the polygon. Negative indices - * count from the end of the point list, e.g. -1 means "last point", -2 - * means "second to last point" and so on. - * @param aIndex index of the point - * @return reference to the point - */ - VECTOR2I& Point( int aIndex ) - { - return m_points.Point( aIndex ); - } - - /** - * Function CPoint() - * * Returns a const reference to a given point in the polygon. Negative * indices count from the end of the point list, e.g. -1 means "last * point", -2 means "second to last point" and so on. diff --git a/include/gr_basic.h b/include/gr_basic.h index eb31612a71..5db694bb4c 100644 --- a/include/gr_basic.h +++ b/include/gr_basic.h @@ -111,8 +111,8 @@ void GRMoveTo( int x, int y ); void GRLineTo( EDA_RECT* ClipBox, wxDC* DC, int x, int y, int width, COLOR4D Color ); -void GRPoly( EDA_RECT* ClipBox, wxDC* DC, int n, wxPoint Points[], bool Fill, - int width, COLOR4D Color, COLOR4D BgColor ); +void GRPoly( EDA_RECT* ClipBox, wxDC* DC, int n, const wxPoint* Points, bool Fill, int width, + COLOR4D Color, COLOR4D BgColor ); /** Draw cubic (4 points: start control1, control2, end) bezier curve */ @@ -131,13 +131,8 @@ void GRBezier( EDA_RECT* aClipBox, wxDC* aDC, std::vector& aPoints, * @param aPenColor the color of the border. * @param aFillColor the fill color of the polygon's interior. */ -void GRClosedPoly( EDA_RECT* ClipBox, - wxDC * aDC, - int aPointCount, - wxPoint aPoints[], - bool doFill, - COLOR4D aPenColor, - COLOR4D aFillColor ); +void GRClosedPoly( EDA_RECT* ClipBox, wxDC* aDC, int aPointCount, const wxPoint* aPoints, + bool doFill, COLOR4D aPenColor, COLOR4D aFillColor ); // @todo could make these 2 closed polygons calls a single function and default // the aPenWidth argument @@ -155,14 +150,8 @@ void GRClosedPoly( EDA_RECT* ClipBox, * @param aPenColor the color of the border. * @param aFillColor the fill color of the polygon's interior. */ -void GRClosedPoly( EDA_RECT* ClipBox, - wxDC* aDC, - int aPointCount, - wxPoint aPoints[], - bool doFill, - int aPenWidth, - COLOR4D aPenColor, - COLOR4D aFillColor ); +void GRClosedPoly( EDA_RECT* ClipBox, wxDC* aDC, int aPointCount, const wxPoint* aPoints, + bool doFill, int aPenWidth, COLOR4D aPenColor, COLOR4D aFillColor ); /** diff --git a/pcbnew/class_drawsegment.cpp b/pcbnew/class_drawsegment.cpp index 3eed91cfb3..6cb9401276 100644 --- a/pcbnew/class_drawsegment.cpp +++ b/pcbnew/class_drawsegment.cpp @@ -4,7 +4,7 @@ * Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck * Copyright (C) 2011 Wayne Stambaugh - * Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -100,10 +100,7 @@ void DRAWSEGMENT::Move( const wxPoint& aMoveVector ) switch ( m_Shape ) { case S_POLYGON: - for( auto iter = m_Poly.Iterate(); iter; iter++ ) - { - (*iter) += VECTOR2I( aMoveVector ); - } + m_Poly.Move( VECTOR2I( aMoveVector ) ); break; case S_CURVE: @@ -136,10 +133,7 @@ void DRAWSEGMENT::Rotate( const wxPoint& aRotCentre, double aAngle ) break; case S_POLYGON: - for( auto iter = m_Poly.Iterate(); iter; iter++ ) - { - RotatePoint( *iter, VECTOR2I(aRotCentre), aAngle); - } + m_Poly.Rotate( -DECIDEG2RAD( aAngle ), VECTOR2I( aRotCentre ) ); break; case S_CURVE: @@ -184,13 +178,7 @@ void DRAWSEGMENT::Flip( const wxPoint& aCentre, bool aFlipLeftRight ) break; case S_POLYGON: - for( auto iter = m_Poly.Iterate(); iter; iter++ ) - { - if( aFlipLeftRight ) - iter->x = aCentre.x - ( iter->x - aCentre.x ); - else - iter->y = aCentre.y - ( iter->y - aCentre.y ); - } + m_Poly.Mirror( aFlipLeftRight, !aFlipLeftRight, VECTOR2I( aCentre ) ); break; case S_CURVE: @@ -441,7 +429,8 @@ void DRAWSEGMENT::Print( PCB_BASE_FRAME* aFrame, wxDC* DC, const wxPoint& aOffse for( int jj = 0; jj < outline.OutlineCount(); ++jj ) { SHAPE_LINE_CHAIN& poly = outline.Outline( jj ); - GRClosedPoly( nullptr, DC, poly.PointCount(), (wxPoint*)&poly.Point( 0 ), + GRClosedPoly( nullptr, DC, poly.PointCount(), + static_cast( &poly.CPoint( 0 ) ), IsPolygonFilled(), GetWidth(), color, color ); } } diff --git a/pcbnew/class_edge_mod.cpp b/pcbnew/class_edge_mod.cpp index 8d4aa63a09..8d940c1562 100644 --- a/pcbnew/class_edge_mod.cpp +++ b/pcbnew/class_edge_mod.cpp @@ -327,14 +327,8 @@ void EDGE_MODULE::Flip( const wxPoint& aCentre, bool aFlipLeftRight ) case S_POLYGON: // polygon corners coordinates are always relative to the // footprint position, orientation 0 - for( auto iter = m_Poly.Iterate(); iter; iter++ ) - { - if( aFlipLeftRight ) - MIRROR( iter->x, 0 ); - else - MIRROR( iter->y, 0 ); - } - break; + m_Poly.Mirror( aFlipLeftRight, !aFlipLeftRight ); + break; } // DRAWSEGMENT items are not usually on copper layers, but @@ -391,13 +385,8 @@ void EDGE_MODULE::Mirror( wxPoint aCentre, bool aMirrorAroundXAxis ) case S_POLYGON: // polygon corners coordinates are always relative to the // footprint position, orientation 0 - for( auto iter = m_Poly.Iterate(); iter; iter++ ) - { - if( aMirrorAroundXAxis ) - MIRROR( iter->y, aCentre.y ); - else - MIRROR( iter->x, aCentre.x ); - } + m_Poly.Mirror( !aMirrorAroundXAxis, aMirrorAroundXAxis ); + break; } SetDrawCoord(); @@ -433,8 +422,7 @@ void EDGE_MODULE::Move( const wxPoint& aMoveVector ) case S_POLYGON: // polygon corners coordinates are always relative to the // footprint position, orientation 0 - for( auto iter = m_Poly.Iterate(); iter; iter++ ) - *iter += VECTOR2I( aMoveVector ); + m_Poly.Move( VECTOR2I( aMoveVector ) ); break; } diff --git a/pcbnew/class_pad.cpp b/pcbnew/class_pad.cpp index 3413f02a93..534352b6e2 100644 --- a/pcbnew/class_pad.cpp +++ b/pcbnew/class_pad.cpp @@ -3,7 +3,7 @@ * * Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck - * Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -491,13 +491,7 @@ void D_PAD::FlipPrimitives() } // Flip local coordinates in merged Polygon - for( int cnt = 0; cnt < m_customShapeAsPolygon.OutlineCount(); ++cnt ) - { - SHAPE_LINE_CHAIN& poly = m_customShapeAsPolygon.Outline( cnt ); - - for( int ii = 0; ii < poly.PointCount(); ++ii ) - MIRROR( poly.Point( ii ).y, 0 ); - } + m_customShapeAsPolygon.Mirror( false, true ); } @@ -528,9 +522,7 @@ void D_PAD::MirrorXPrimitives( int aX ) for( int cnt = 0; cnt < m_customShapeAsPolygon.OutlineCount(); ++cnt ) { SHAPE_LINE_CHAIN& poly = m_customShapeAsPolygon.Outline( cnt ); - - for( int ii = 0; ii < poly.PointCount(); ++ii ) - MIRROR( poly.Point( ii ).x, 0 ); + poly.Mirror( true, false ); } } diff --git a/pcbnew/class_zone.cpp b/pcbnew/class_zone.cpp index c645ce7f36..4c8b6fc3fc 100644 --- a/pcbnew/class_zone.cpp +++ b/pcbnew/class_zone.cpp @@ -625,8 +625,8 @@ bool ZONE_CONTAINER::HitTest( const EDA_RECT& aRect, bool aContained, int aAccur for( int ii = 0; ii < count; ii++ ) { - auto vertex = m_Poly->Vertex( ii ); - auto vertexNext = m_Poly->Vertex( ( ii + 1 ) % count ); + auto vertex = m_Poly->CVertex( ii ); + auto vertexNext = m_Poly->CVertex( ( ii + 1 ) % count ); // Test if the point is within the rect if( arect.Contains( ( wxPoint ) vertex ) ) @@ -789,8 +789,8 @@ void ZONE_CONTAINER::MoveEdge( const wxPoint& offset, int aEdge ) if( m_Poly->GetNeighbourIndexes( aEdge, nullptr, &next_corner ) ) { - m_Poly->Vertex( aEdge ) += VECTOR2I( offset ); - m_Poly->Vertex( next_corner ) += VECTOR2I( offset ); + m_Poly->SetVertex( aEdge, m_Poly->CVertex( aEdge ) + VECTOR2I( offset ) ); + m_Poly->SetVertex( next_corner, m_Poly->CVertex( next_corner ) + VECTOR2I( offset ) ); Hatch(); SetNeedRefill( true ); @@ -802,19 +802,13 @@ void ZONE_CONTAINER::Rotate( const wxPoint& centre, double angle ) { wxPoint pos; - for( auto iterator = m_Poly->IterateWithHoles(); iterator; iterator++ ) - { - pos = static_cast( *iterator ); - RotatePoint( &pos, centre, angle ); - iterator->x = pos.x; - iterator->y = pos.y; - } + angle = -DECIDEG2RAD( angle ); + m_Poly->Rotate( angle, VECTOR2I( centre ) ); Hatch(); /* rotate filled areas: */ - for( auto ic = m_FilledPolysList.Iterate(); ic; ++ic ) - RotatePoint( &ic->x, &ic->y, centre.x, centre.y, angle ); + m_FilledPolysList.Rotate( angle, VECTOR2I( centre ) ); for( unsigned ic = 0; ic < m_FillSegmList.size(); ic++ ) { @@ -846,23 +840,12 @@ void ZONE_CONTAINER::Flip( const wxPoint& aCentre, bool aFlipLeftRight ) void ZONE_CONTAINER::Mirror( const wxPoint& aMirrorRef, bool aMirrorLeftRight ) { - for( auto iterator = m_Poly->IterateWithHoles(); iterator; iterator++ ) - { - if( aMirrorLeftRight ) - iterator->x = ( aMirrorRef.x - iterator->x ) + aMirrorRef.x; - else - iterator->y = ( aMirrorRef.y - iterator->y ) + aMirrorRef.y; - } + // ZONE_CONTAINERs mirror about the x-axis (why?!?) + m_Poly->Mirror( aMirrorLeftRight, !aMirrorLeftRight, VECTOR2I( aMirrorRef ) ); Hatch(); - for( auto ic = m_FilledPolysList.Iterate(); ic; ++ic ) - { - if( aMirrorLeftRight ) - ic->x = ( aMirrorRef.x - ic->x ) + aMirrorRef.x; - else - ic->y = ( aMirrorRef.y - ic->y ) + aMirrorRef.y; - } + m_FilledPolysList.Mirror( aMirrorLeftRight, !aMirrorLeftRight, VECTOR2I( aMirrorRef ) ); for( SEG& seg : m_FillSegmList ) { @@ -1009,10 +992,10 @@ void ZONE_CONTAINER::Hatch() return; // define range for hatch lines - int min_x = m_Poly->Vertex( 0 ).x; - int max_x = m_Poly->Vertex( 0 ).x; - int min_y = m_Poly->Vertex( 0 ).y; - int max_y = m_Poly->Vertex( 0 ).y; + int min_x = m_Poly->CVertex( 0 ).x; + int max_x = m_Poly->CVertex( 0 ).x; + int min_y = m_Poly->CVertex( 0 ).y; + int max_y = m_Poly->CVertex( 0 ).y; for( auto iterator = m_Poly->IterateWithHoles(); iterator; iterator++ ) { diff --git a/pcbnew/class_zone.h b/pcbnew/class_zone.h index f69c93f6e8..744d396ada 100644 --- a/pcbnew/class_zone.h +++ b/pcbnew/class_zone.h @@ -486,12 +486,12 @@ public: // Convert global to relative indices if( m_Poly->GetRelativeIndices( aCornerIndex, &relativeIndices ) ) { - if( m_Poly->Vertex( relativeIndices ).x != new_pos.x || - m_Poly->Vertex( relativeIndices ).y != new_pos.y ) + if( m_Poly->CVertex( relativeIndices ).x != new_pos.x + || m_Poly->CVertex( relativeIndices ).y != new_pos.y ) + { SetNeedRefill( true ); - - m_Poly->Vertex( relativeIndices ).x = new_pos.x; - m_Poly->Vertex( relativeIndices ).y = new_pos.y; + m_Poly->SetVertex( relativeIndices, new_pos ); + } } else throw( std::out_of_range( "aCornerIndex-th vertex does not exist" ) ); diff --git a/pcbnew/drc/courtyard_overlap.cpp b/pcbnew/drc/courtyard_overlap.cpp index e964e8a559..a855968c41 100644 --- a/pcbnew/drc/courtyard_overlap.cpp +++ b/pcbnew/drc/courtyard_overlap.cpp @@ -125,8 +125,8 @@ bool DRC_COURTYARD_OVERLAP::RunDRC( BOARD& aBoard ) const if( courtyard.OutlineCount() ) { //Overlap between footprint and candidate - VECTOR2I& pos = courtyard.Vertex( 0, 0, -1 ); - auto marker = std::unique_ptr( + auto& pos = courtyard.CVertex( 0, 0, -1 ); + auto marker = std::unique_ptr( marker_factory.NewMarker( wxPoint( pos.x, pos.y ), footprint, candidate, DRCE_OVERLAPPING_FOOTPRINTS ) ); HandleMarker( std::move( marker ) ); @@ -162,8 +162,8 @@ bool DRC_COURTYARD_OVERLAP::RunDRC( BOARD& aBoard ) const if( courtyard.OutlineCount() ) { //Overlap between footprint and candidate - VECTOR2I& pos = courtyard.Vertex( 0, 0, -1 ); - auto marker = std::unique_ptr( + auto& pos = courtyard.CVertex( 0, 0, -1 ); + auto marker = std::unique_ptr( marker_factory.NewMarker( wxPoint( pos.x, pos.y ), footprint, candidate, DRCE_OVERLAPPING_FOOTPRINTS ) ); HandleMarker( std::move( marker ) ); diff --git a/pcbnew/exporters/export_vrml.cpp b/pcbnew/exporters/export_vrml.cpp index 89765fb4f8..bcf62477c5 100644 --- a/pcbnew/exporters/export_vrml.cpp +++ b/pcbnew/exporters/export_vrml.cpp @@ -1119,8 +1119,8 @@ static void export_vrml_padshape( MODEL_VRML& aModel, VRML_LAYER* aTinLayer, D_P cornerList.reserve( poly.PointCount() ); for( int ii = 0; ii < poly.PointCount(); ++ii ) - cornerList.emplace_back( poly.Point( ii ).x * BOARD_SCALE, - -poly.Point( ii ).y * BOARD_SCALE ); + cornerList.emplace_back( + poly.CPoint( ii ).x * BOARD_SCALE, -poly.CPoint( ii ).y * BOARD_SCALE ); // Close polygon cornerList.push_back( cornerList[0] ); @@ -1142,8 +1142,8 @@ static void export_vrml_padshape( MODEL_VRML& aModel, VRML_LAYER* aTinLayer, D_P cornerList.clear(); for( int ii = 0; ii < poly.PointCount(); ++ii ) - cornerList.emplace_back( poly.Point( ii ).x * BOARD_SCALE, - -poly.Point( ii ).y * BOARD_SCALE ); + cornerList.emplace_back( + poly.CPoint( ii ).x * BOARD_SCALE, -poly.CPoint( ii ).y * BOARD_SCALE ); // Close polygon cornerList.push_back( cornerList[0] ); diff --git a/pcbnew/pad_custom_shape_functions.cpp b/pcbnew/pad_custom_shape_functions.cpp index 46b68a337e..f1175b8516 100644 --- a/pcbnew/pad_custom_shape_functions.cpp +++ b/pcbnew/pad_custom_shape_functions.cpp @@ -388,20 +388,8 @@ void D_PAD::CustomShapeAsPolygonToBoardPosition( SHAPE_POLY_SET * aMergedPolygon // Move, rotate, ... coordinates in aMergedPolygon according to the // pad position and orientation - for( int cnt = 0; cnt < aMergedPolygon->OutlineCount(); ++cnt ) - { - SHAPE_LINE_CHAIN& poly = aMergedPolygon->Outline( cnt ); - - for( int ii = 0; ii < poly.PointCount(); ++ii ) - { - wxPoint corner( poly.Point( ii ).x, poly.Point( ii ).y ); - RotatePoint( &corner, aRotation ); - corner += aPosition; - - poly.Point( ii ).x = corner.x; - poly.Point( ii ).y = corner.y; - } - } + aMergedPolygon->Rotate( -DECIDEG2RAD( aRotation ) ); + aMergedPolygon->Move( VECTOR2I( aPosition ) ); } bool D_PAD::GetBestAnchorPosition( VECTOR2I& aPos ) diff --git a/pcbnew/pad_print_functions.cpp b/pcbnew/pad_print_functions.cpp index 1b63a4fd9e..6f22cd1687 100644 --- a/pcbnew/pad_print_functions.cpp +++ b/pcbnew/pad_print_functions.cpp @@ -280,7 +280,8 @@ void D_PAD::PrintShape( wxDC* aDC, PAD_DRAWINFO& aDrawInfo ) if( poly.PointCount() > 0 ) { - GRClosedPoly( nullptr, aDC, poly.PointCount(), (wxPoint*)&poly.Point( 0 ), + GRClosedPoly( nullptr, aDC, poly.PointCount(), + static_cast( &poly.CPoint( 0 ) ), false, 0, aDrawInfo.m_Color, aDrawInfo.m_Color ); } } @@ -307,7 +308,8 @@ void D_PAD::PrintShape( wxDC* aDC, PAD_DRAWINFO& aDrawInfo ) SHAPE_LINE_CHAIN& poly = outline.Outline( 0 ); - GRClosedPoly( nullptr, aDC, poly.PointCount(), (wxPoint*)&poly.Point( 0 ), filled, 0, + GRClosedPoly( nullptr, aDC, poly.PointCount(), + static_cast( &poly.CPoint( 0 ) ), filled, 0, aDrawInfo.m_Color, aDrawInfo.m_Color ); if( aDrawInfo.m_PadClearance ) @@ -327,7 +329,7 @@ void D_PAD::PrintShape( wxDC* aDC, PAD_DRAWINFO& aDrawInfo ) SHAPE_LINE_CHAIN& clearance_poly = outline.Outline( 0 ); GRClosedPoly( nullptr, aDC, clearance_poly.PointCount(), - (wxPoint*)&clearance_poly.Point( 0 ), false, 0, + static_cast( &clearance_poly.CPoint( 0 ) ), false, 0, aDrawInfo.m_Color, aDrawInfo.m_Color ); } } @@ -373,7 +375,6 @@ void D_PAD::PrintShape( wxDC* aDC, PAD_DRAWINFO& aDrawInfo ) SHAPE_POLY_SET outline; // Will contain the corners in board coordinates outline.Append( m_customShapeAsPolygon ); CustomShapeAsPolygonToBoardPosition( &outline, pad_pos, GetOrientation() ); - SHAPE_LINE_CHAIN* poly; if( aDrawInfo.m_Mask_margin.x ) { @@ -387,9 +388,9 @@ void D_PAD::PrintShape( wxDC* aDC, PAD_DRAWINFO& aDrawInfo ) // ( can happen with CUSTOM pads and negative margins ) for( int jj = 0; jj < outline.OutlineCount(); ++jj ) { - poly = &outline.Outline( jj ); + auto& poly = outline.Outline( jj ); - GRClosedPoly( nullptr, aDC, poly->PointCount(), (wxPoint*)&poly->Point( 0 ), + GRClosedPoly( nullptr, aDC, poly.PointCount(), static_cast( &poly.CPoint( 0 ) ), aDrawInfo.m_ShowPadFilled, 0, aDrawInfo.m_Color, aDrawInfo.m_Color ); } @@ -404,11 +405,12 @@ void D_PAD::PrintShape( wxDC* aDC, PAD_DRAWINFO& aDrawInfo ) for( int jj = 0; jj < clearance_outline.OutlineCount(); ++jj ) { - poly = &clearance_outline.Outline( jj ); + auto& poly = clearance_outline.Outline( jj ); - if( poly->PointCount() > 0 ) + if( poly.PointCount() > 0 ) { - GRClosedPoly( nullptr, aDC, poly->PointCount(), (wxPoint*)&poly->Point( 0 ), + GRClosedPoly( nullptr, aDC, poly.PointCount(), + static_cast( &poly.CPoint( 0 ) ), false, 0, aDrawInfo.m_Color, aDrawInfo.m_Color ); } } diff --git a/pcbnew/router/pns_diff_pair.cpp b/pcbnew/router/pns_diff_pair.cpp index 00ad05d4e2..4f43208715 100644 --- a/pcbnew/router/pns_diff_pair.cpp +++ b/pcbnew/router/pns_diff_pair.cpp @@ -831,8 +831,8 @@ void DIFF_PAIR::CoupledSegmentPairs( COUPLED_SEGMENTS_VEC& aPairs ) const { for( int j = 0; j < n.SegmentCount(); j++ ) { - SEG sp = p.CSegment( i ); - SEG sn = n.CSegment( j ); + SEG sp = p.Segment( i ); + SEG sn = n.Segment( j ); SEG p_clip, n_clip; diff --git a/pcbnew/router/pns_kicad_iface.cpp b/pcbnew/router/pns_kicad_iface.cpp index 9ae2bb5e4e..f5754390cb 100644 --- a/pcbnew/router/pns_kicad_iface.cpp +++ b/pcbnew/router/pns_kicad_iface.cpp @@ -687,7 +687,7 @@ std::unique_ptr PNS_KICAD_IFACE::syncPad( D_PAD* aPad ) SHAPE_SIMPLE* shape = new SHAPE_SIMPLE(); for( int ii = 0; ii < poly.PointCount(); ++ii ) - shape->Append( poly.Point( ii ) ); + shape->Append( poly.CPoint( ii ) ); solid->SetShape( shape ); } @@ -781,7 +781,7 @@ std::unique_ptr PNS_KICAD_IFACE::syncPad( D_PAD* aPad ) for( int ii = 0; ii < poly.PointCount(); ++ii ) { - shape->Append( wxPoint( poly.Point( ii ).x, poly.Point( ii ).y ) ); + shape->Append( wxPoint( poly.CPoint( ii ).x, poly.CPoint( ii ).y ) ); } solid->SetShape( shape ); diff --git a/pcbnew/router/pns_line.cpp b/pcbnew/router/pns_line.cpp index ab694cd5c9..529aeeb381 100644 --- a/pcbnew/router/pns_line.cpp +++ b/pcbnew/router/pns_line.cpp @@ -469,7 +469,7 @@ void LINE::dragCorner45( const VECTOR2I& aP, int aIndex, int aSnappingThreshold void LINE::dragCornerFree( const VECTOR2I& aP, int aIndex, int aSnappingThreshold ) { - m_line.Point( aIndex ) = aP; + m_line.SetPoint( aIndex, aP ); m_line.Simplify(); } diff --git a/pcbnew/router/pns_line_placer.cpp b/pcbnew/router/pns_line_placer.cpp index 0404a90417..79a10886c8 100644 --- a/pcbnew/router/pns_line_placer.cpp +++ b/pcbnew/router/pns_line_placer.cpp @@ -147,7 +147,7 @@ bool LINE_PLACER::handleSelfIntersections() // from the beginning if( n < 2 ) { - m_p_start = tail.Point( 0 ); + m_p_start = tail.CPoint( 0 ); m_direction = m_initial_direction; tail.Clear(); head.Clear(); @@ -1228,7 +1228,7 @@ bool LINE_PLACER::buildInitialLine( const VECTOR2I& aP, LINE& aHead, bool aInver VECTOR2I newLast = l.CSegment( 0 ).LineProject( l.CPoint( -1 ) ); l.Remove( -1, -1 ); - l.Point( 1 ) = newLast; + l.SetPoint( 1, newLast ); } } diff --git a/pcbnew/router/pns_meander.cpp b/pcbnew/router/pns_meander.cpp index 8165b7139b..a892d293b9 100644 --- a/pcbnew/router/pns_meander.cpp +++ b/pcbnew/router/pns_meander.cpp @@ -413,7 +413,7 @@ SHAPE_LINE_CHAIN MEANDER_SHAPE::genMeanderShape( VECTOR2D aP, VECTOR2D aDir, SEG axis( aP, aP + aDir ); for( int i = 0; i < lc.PointCount(); i++ ) - lc.Point( i ) = reflect( lc.CPoint( i ), axis ); + lc.SetPoint( i, reflect( lc.CPoint( i ), axis ) ); } return lc; diff --git a/pcbnew/specctra_import_export/specctra_export.cpp b/pcbnew/specctra_import_export/specctra_export.cpp index ab33b099e3..4329bf413c 100644 --- a/pcbnew/specctra_import_export/specctra_export.cpp +++ b/pcbnew/specctra_import_export/specctra_export.cpp @@ -506,8 +506,8 @@ PADSTACK* SPECCTRA_DB::makePADSTACK( BOARD* aBoard, D_PAD* aPad ) for( int idx = 0; idx < polygonal_shape.PointCount(); idx++ ) { - POINT corner( scale( polygonal_shape.Point( idx ).x ), - scale( -polygonal_shape.Point( idx ).y ) ); + POINT corner( scale( polygonal_shape.CPoint( idx ).x ), + scale( -polygonal_shape.CPoint( idx ).y ) ); corner += dsnOffset; polygon->AppendPoint( corner ); @@ -843,12 +843,12 @@ void SPECCTRA_DB::fillBOUNDARY( BOARD* aBoard, BOUNDARY* boundary ) for( int ii = 0; ii < outline.PointCount(); ii++ ) { - wxPoint pos( outline.Point( ii ).x, outline.Point( ii ).y ); + wxPoint pos( outline.CPoint( ii ).x, outline.CPoint( ii ).y ); path->AppendPoint( mapPt( pos ) ); } // Close polygon: - wxPoint pos0( outline.Point( 0 ).x, outline.Point( 0 ).y ); + wxPoint pos0( outline.CPoint( 0 ).x, outline.CPoint( 0 ).y ); path->AppendPoint( mapPt( pos0 ) ); // Generate holes as keepout: @@ -866,12 +866,12 @@ void SPECCTRA_DB::fillBOUNDARY( BOARD* aBoard, BOUNDARY* boundary ) for( int jj = 0; jj < hole.PointCount(); jj++ ) { - wxPoint pos( hole.Point( jj ).x, hole.Point( jj ).y ); + wxPoint pos( hole.CPoint( jj ).x, hole.CPoint( jj ).y ); poly_ko->AppendPoint( mapPt( pos ) ); } // Close polygon: - wxPoint pos( hole.Point( 0 ).x, hole.Point( 0 ).y ); + wxPoint pos( hole.CPoint( 0 ).x, hole.CPoint( 0 ).y ); poly_ko->AppendPoint( mapPt( pos ) ); } } diff --git a/pcbnew/tools/drc.cpp b/pcbnew/tools/drc.cpp index d406f6c2c2..e8c0d32ea9 100644 --- a/pcbnew/tools/drc.cpp +++ b/pcbnew/tools/drc.cpp @@ -986,7 +986,7 @@ void DRC::testCopperDrawItem( DRAWSEGMENT* aItem ) auto l = arc.ConvertToPolyline(); for( int i = 0; i < l.SegmentCount(); i++ ) - itemShape.push_back( l.CSegment(i) ); + itemShape.push_back( l.Segment( i ) ); break; } @@ -1003,7 +1003,7 @@ void DRC::testCopperDrawItem( DRAWSEGMENT* aItem ) auto l = circle.ConvertToPolyline(); for( int i = 0; i < l.SegmentCount(); i++ ) - itemShape.push_back( l.CSegment(i) ); + itemShape.push_back( l.Segment( i ) ); break; } diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index 1a66ad9f00..d515c7f340 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -509,7 +509,7 @@ void POINT_EDITOR::updateItem() const SHAPE_POLY_SET& outline = segment->GetPolyShape(); for( int i = 0; i < outline.TotalVertices(); ++i ) - outline.Vertex( i ) = m_editPoints->Point( i ).GetPosition(); + outline.SetVertex( i, m_editPoints->Point( i ).GetPosition() ); validatePolygon( outline ); break; @@ -552,10 +552,10 @@ void POINT_EDITOR::updateItem() const for( int i = 0; i < outline.TotalVertices(); ++i ) { - if( outline.Vertex( i ) != m_editPoints->Point( i ).GetPosition() ) + if( outline.CVertex( i ) != m_editPoints->Point( i ).GetPosition() ) zone->SetNeedRefill( true ); - outline.Vertex( i ) = m_editPoints->Point( i ).GetPosition(); + outline.SetVertex( i, m_editPoints->Point( i ).GetPosition() ); } validatePolygon( outline ); @@ -902,7 +902,7 @@ findVertex( SHAPE_POLY_SET& aPolySet, const EDIT_POINT& aPoint ) { auto vertexIdx = it.GetIndex(); - if( aPolySet.Vertex( vertexIdx ) == aPoint.GetPosition() ) + if( aPolySet.CVertex( vertexIdx ) == aPoint.GetPosition() ) return std::make_pair( true, vertexIdx ); } @@ -1006,7 +1006,7 @@ int POINT_EDITOR::addCorner( const TOOL_EVENT& aEvent ) firstPointInContour = curr_idx+1; // Prepare next contour analysis } - SEG curr_segment( zoneOutline->Vertex( curr_idx ), zoneOutline->Vertex( jj ) ); + SEG curr_segment( zoneOutline->CVertex( curr_idx ), zoneOutline->CVertex( jj ) ); unsigned int distance = curr_segment.Distance( cursorPos ); @@ -1019,8 +1019,8 @@ int POINT_EDITOR::addCorner( const TOOL_EVENT& aEvent ) } // Find the point on the closest segment - VECTOR2I sideOrigin = zoneOutline->Vertex( nearestIdx ); - VECTOR2I sideEnd = zoneOutline->Vertex( nextNearestIdx ); + auto& sideOrigin = zoneOutline->CVertex( nearestIdx ); + auto& sideEnd = zoneOutline->CVertex( nextNearestIdx ); SEG nearestSide( sideOrigin, sideEnd ); VECTOR2I nearestPoint = nearestSide.NearestPoint( cursorPos ); diff --git a/pcbnew/zone_filler.cpp b/pcbnew/zone_filler.cpp index 3004dc5491..2ff6def32b 100644 --- a/pcbnew/zone_filler.cpp +++ b/pcbnew/zone_filler.cpp @@ -980,11 +980,8 @@ void ZONE_FILLER::buildThermalSpokes( const ZONE_CONTAINER* aZone, break; } - for( int j = 0; j < spoke.PointCount(); j++ ) - { - RotatePoint( spoke.Point( j ), padAngle ); - spoke.Point( j ) += shapePos; - } + spoke.Rotate( padAngle ); + spoke.Move( shapePos ); spoke.SetClosed( true ); spoke.GenerateBBoxCache(); diff --git a/pcbnew/zones_by_polygon.cpp b/pcbnew/zones_by_polygon.cpp index 7b1be1adbb..e4fa975d20 100644 --- a/pcbnew/zones_by_polygon.cpp +++ b/pcbnew/zones_by_polygon.cpp @@ -41,11 +41,11 @@ #include #include +// TODO: Remove these to the commit object below // Local variables static PICKED_ITEMS_LIST s_PickedList; // a picked list to save zones for undo/redo command static PICKED_ITEMS_LIST s_AuxiliaryList; // a picked list to store zones that are deleted or added when combined - void PCB_EDIT_FRAME::Edit_Zone_Params( ZONE_CONTAINER* aZone ) { int dialogResult; diff --git a/qa/pcbnew_tools/tools/polygon_triangulation/polygon_triangulation.cpp b/qa/pcbnew_tools/tools/polygon_triangulation/polygon_triangulation.cpp index 1aeeed756c..815d98bdba 100644 --- a/qa/pcbnew_tools/tools/polygon_triangulation/polygon_triangulation.cpp +++ b/qa/pcbnew_tools/tools/polygon_triangulation/polygon_triangulation.cpp @@ -61,19 +61,21 @@ void unfracture( SHAPE_POLY_SET::POLYGON* aPoly, SHAPE_POLY_SET::POLYGON* aResul bool operator==( const EDGE& aOther ) const { - return compareSegs( m_poly->CSegment(m_index), aOther.m_poly->CSegment(aOther.m_index) ); + return compareSegs( + m_poly->Segment( m_index ), aOther.m_poly->Segment( aOther.m_index ) ); } bool operator!=( const EDGE& aOther ) const { - return ! compareSegs( m_poly->CSegment(m_index), aOther.m_poly->CSegment(aOther.m_index) ); + return !compareSegs( + m_poly->Segment( m_index ), aOther.m_poly->Segment( aOther.m_index ) ); } struct HASH { std::size_t operator()( const EDGE& aEdge ) const { - const auto& a = aEdge.m_poly->CSegment(aEdge.m_index); + const auto& a = aEdge.m_poly->Segment( aEdge.m_index ); return (std::size_t) ( a.A.x + a.B.x + a.A.y + a.B.y ); } }; @@ -178,9 +180,9 @@ aResult->clear(); queue.erase( edgeBuf[i] ); } -// auto p_last = lc.CPoint( edgeBuf[cnt-1]->index + 1 ); -//printf("appendl %d %d\n", p_last.x, p_last.y); -// outl.Append( p_last ); + // auto p_last = lc.Point( edgeBuf[cnt-1]->index + 1 ); + //printf("appendl %d %d\n", p_last.x, p_last.y); + // outl.Append( p_last ); outl.SetClosed(true);