From 65185f53a12a9e4cdf347779a90f3012a56b413f Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Mon, 14 Mar 2022 15:52:12 +0000 Subject: [PATCH] Rotate fp zones before comparing with library versions. Also includes some performance fixes to not copy around triangulation data when it's not needed. Fixes https://gitlab.com/kicad/code/kicad/issues/10143 --- .../3d_canvas/create_3Dgraphic_brd_items.cpp | 6 ++-- .../3d_rendering/opengl/create_scene.cpp | 20 ++++++----- .../raytracing/shapes2D/triangle_2d.cpp | 4 +-- .../raytracing/shapes2D/triangle_2d.h | 2 +- common/drawing_sheet/ds_data_item.cpp | 1 + common/plotters/GERBER_plotter.cpp | 2 +- gerbview/export_to_pcbnew.cpp | 4 +-- libs/kimath/include/geometry/shape_poly_set.h | 6 ++++ libs/kimath/src/geometry/shape_poly_set.cpp | 16 +++++++++ pcbnew/autorouter/ar_autoplacer.cpp | 4 +-- pcbnew/convert_shape_list_to_polygon.cpp | 8 ++--- pcbnew/drc/drc_test_provider_disallow.cpp | 2 +- .../drc/drc_test_provider_library_parity.cpp | 14 +++++--- ...drc_test_provider_mechanical_clearance.cpp | 2 +- .../drc/drc_test_provider_sliver_checker.cpp | 9 ++--- pcbnew/drc/drc_test_provider_text_dims.cpp | 2 +- pcbnew/exporters/export_hyperlynx.cpp | 36 +++++++++++-------- pcbnew/footprint.cpp | 2 +- pcbnew/pcb_expr_evaluator.cpp | 6 ++-- pcbnew/pcb_painter.cpp | 4 +-- pcbnew/plot_board_layers.cpp | 2 +- pcbnew/plot_brditems_plotter.cpp | 2 +- pcbnew/zone.cpp | 11 +++--- pcbnew/zone_filler.cpp | 10 +++--- 24 files changed, 105 insertions(+), 70 deletions(-) diff --git a/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp b/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp index c4c1f2a31c..3748459fa9 100644 --- a/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp +++ b/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp @@ -722,11 +722,9 @@ void BOARD_ADAPTER::addShape( const PCB_SHAPE* aShape, CONTAINER_2D_BASE* aConta void BOARD_ADAPTER::addSolidAreasShapes( const ZONE* aZone, CONTAINER_2D_BASE* aContainer, PCB_LAYER_ID aLayerId ) { - // Copy the polys list because we have to simplify it - SHAPE_POLY_SET polyList = SHAPE_POLY_SET( *aZone->GetFilledPolysList( aLayerId ) ); - // This convert the poly in outline and holes - ConvertPolygonToTriangles( polyList, *aContainer, m_biuTo3Dunits, *aZone ); + ConvertPolygonToTriangles( *aZone->GetFilledPolysList( aLayerId ), *aContainer, + m_biuTo3Dunits, *aZone ); } diff --git a/3d-viewer/3d_rendering/opengl/create_scene.cpp b/3d-viewer/3d_rendering/opengl/create_scene.cpp index df3f275aa0..d2bd22d044 100644 --- a/3d-viewer/3d_rendering/opengl/create_scene.cpp +++ b/3d-viewer/3d_rendering/opengl/create_scene.cpp @@ -395,9 +395,8 @@ OPENGL_RENDER_LIST* RENDER_3D_OPENGL::createBoard( const SHAPE_POLY_SET& aBoardP { OPENGL_RENDER_LIST* dispLists = nullptr; CONTAINER_2D boardContainer; - SHAPE_POLY_SET brd_outlines = aBoardPoly; - ConvertPolygonToTriangles( brd_outlines, boardContainer, m_boardAdapter.BiuTo3dUnits(), + ConvertPolygonToTriangles( aBoardPoly, boardContainer, m_boardAdapter.BiuTo3dUnits(), (const BOARD_ITEM &)*m_boardAdapter.GetBoard() ); const LIST_OBJECT2D& listBoardObject2d = boardContainer.GetList(); @@ -481,7 +480,7 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo m_antiBoard = createBoard( m_antiBoardPolys ); } - SHAPE_POLY_SET board_poly_with_holes = m_boardAdapter.GetBoardPoly(); + SHAPE_POLY_SET board_poly_with_holes = m_boardAdapter.GetBoardPoly().CloneDropTriangulation(); board_poly_with_holes.BooleanSubtract( m_boardAdapter.GetThroughHoleOdPolys(), SHAPE_POLY_SET::PM_FAST ); board_poly_with_holes.BooleanSubtract( m_boardAdapter.GetOuterNonPlatedThroughHolePoly(), @@ -496,11 +495,13 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo if( aStatusReporter ) aStatusReporter->Report( _( "Load OpenGL: holes and vias" ) ); - SHAPE_POLY_SET outerPolyTHT = m_boardAdapter.GetThroughHoleOdPolys(); + SHAPE_POLY_SET outerPolyTHT = m_boardAdapter.GetThroughHoleOdPolys().CloneDropTriangulation(); if( m_boardAdapter.m_Cfg->m_Render.realistic ) + { outerPolyTHT.BooleanIntersection( m_boardAdapter.GetBoardPoly(), SHAPE_POLY_SET::PM_STRICTLY_SIMPLE ); + } m_outerThroughHoles = generateHoles( m_boardAdapter.GetThroughHoleOds().GetList(), outerPolyTHT, 1.0f, 0.0f, false, @@ -630,9 +631,12 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo if( m_boardAdapter.m_Cfg->m_Render.renderPlatedPadsAsPlated && m_boardAdapter.m_Cfg->m_Render.realistic ) { - if( m_boardAdapter.GetFrontPlatedPadPolys() ) + const SHAPE_POLY_SET* frontPlatedPadPolys = m_boardAdapter.GetFrontPlatedPadPolys(); + const SHAPE_POLY_SET* backPlatedPadPolys = m_boardAdapter.GetBackPlatedPadPolys(); + + if( frontPlatedPadPolys ) { - SHAPE_POLY_SET polySubtracted = *m_boardAdapter.GetFrontPlatedPadPolys(); + SHAPE_POLY_SET polySubtracted = frontPlatedPadPolys->CloneDropTriangulation(); polySubtracted.BooleanIntersection( m_boardAdapter.GetBoardPoly(), SHAPE_POLY_SET::PM_FAST ); polySubtracted.BooleanSubtract( m_boardAdapter.GetThroughHoleOdPolys(), @@ -648,9 +652,9 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo m_layers[F_Cu] = generateEmptyLayerList( F_Cu ); } - if( m_boardAdapter.GetBackPlatedPadPolys() ) + if( backPlatedPadPolys ) { - SHAPE_POLY_SET polySubtracted = *m_boardAdapter.GetBackPlatedPadPolys(); + SHAPE_POLY_SET polySubtracted = backPlatedPadPolys->CloneDropTriangulation(); polySubtracted.BooleanIntersection( m_boardAdapter.GetBoardPoly(), SHAPE_POLY_SET::PM_FAST ); polySubtracted.BooleanSubtract( m_boardAdapter.GetThroughHoleOdPolys(), diff --git a/3d-viewer/3d_rendering/raytracing/shapes2D/triangle_2d.cpp b/3d-viewer/3d_rendering/raytracing/shapes2D/triangle_2d.cpp index b72071c6c1..688712c563 100644 --- a/3d-viewer/3d_rendering/raytracing/shapes2D/triangle_2d.cpp +++ b/3d-viewer/3d_rendering/raytracing/shapes2D/triangle_2d.cpp @@ -118,14 +118,14 @@ bool TRIANGLE_2D::IsPointInside( const SFVEC2F& aPoint ) const } -void ConvertPolygonToTriangles( SHAPE_POLY_SET& aPolyList, CONTAINER_2D_BASE& aDstContainer, +void ConvertPolygonToTriangles( const SHAPE_POLY_SET& aPolyList, CONTAINER_2D_BASE& aDstContainer, float aBiuTo3dUnitsScale, const BOARD_ITEM& aBoardItem ) { VECTOR2I a; VECTOR2I b; VECTOR2I c; - aPolyList.CacheTriangulation( false ); + const_cast( aPolyList ).CacheTriangulation( false ); const double conver_d = (double)aBiuTo3dUnitsScale; for( unsigned int j = 0; j < aPolyList.TriangulatedPolyCount(); j++ ) diff --git a/3d-viewer/3d_rendering/raytracing/shapes2D/triangle_2d.h b/3d-viewer/3d_rendering/raytracing/shapes2D/triangle_2d.h index 06d79f5ab7..e3b7ffe25f 100644 --- a/3d-viewer/3d_rendering/raytracing/shapes2D/triangle_2d.h +++ b/3d-viewer/3d_rendering/raytracing/shapes2D/triangle_2d.h @@ -64,6 +64,6 @@ private: }; -void ConvertPolygonToTriangles( SHAPE_POLY_SET& aPolyList, CONTAINER_2D_BASE& aDstContainer, +void ConvertPolygonToTriangles( const SHAPE_POLY_SET& aPolyList, CONTAINER_2D_BASE& aDstContainer, float aBiuTo3dUnitsScale, const BOARD_ITEM& aBoardItem ); #endif // _TRIANGLE_2D_H_ diff --git a/common/drawing_sheet/ds_data_item.cpp b/common/drawing_sheet/ds_data_item.cpp index 124e4c61cf..6a597cc413 100644 --- a/common/drawing_sheet/ds_data_item.cpp +++ b/common/drawing_sheet/ds_data_item.cpp @@ -417,6 +417,7 @@ void DS_DATA_ITEM_POLYGONS::SyncDrawItems( DS_DRAW_ITEM_LIST* aCollector, KIGFX: // Transfer all outlines (basic polygons) SHAPE_POLY_SET& polygons = poly_shape->GetPolygons(); + for( int kk = 0; kk < GetPolyCount(); kk++ ) { // Create new outline diff --git a/common/plotters/GERBER_plotter.cpp b/common/plotters/GERBER_plotter.cpp index 63f53f82cb..3300bf712c 100644 --- a/common/plotters/GERBER_plotter.cpp +++ b/common/plotters/GERBER_plotter.cpp @@ -1696,7 +1696,7 @@ void GERBER_PLOTTER::FlashPadCustom( const VECTOR2I& aPadPos, const VECTOR2I& aS if( aData ) gbr_metadata = *static_cast( aData ); - SHAPE_POLY_SET polyshape = *aPolygons; + SHAPE_POLY_SET polyshape = aPolygons->CloneDropTriangulation(); if( aTraceMode != FILLED ) { diff --git a/gerbview/export_to_pcbnew.cpp b/gerbview/export_to_pcbnew.cpp index 364e1ca983..5d0ca03aba 100644 --- a/gerbview/export_to_pcbnew.cpp +++ b/gerbview/export_to_pcbnew.cpp @@ -476,7 +476,7 @@ void GBR_TO_PCB_EXPORTER::writePcbHeader( const int* aLayerLookUpTable ) void GBR_TO_PCB_EXPORTER::writePcbPolygon( const SHAPE_POLY_SET& aPolys, int aLayer, const VECTOR2I& aOffset ) { - SHAPE_POLY_SET polys = aPolys; + SHAPE_POLY_SET polys = aPolys.CloneDropTriangulation(); // Cleanup the polygon polys.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE ); @@ -523,7 +523,7 @@ void GBR_TO_PCB_EXPORTER::writePcbPolygon( const SHAPE_POLY_SET& aPolys, int aLa void GBR_TO_PCB_EXPORTER::writePcbZoneItem( const GERBER_DRAW_ITEM* aGbrItem, int aLayer ) { - SHAPE_POLY_SET polys = aGbrItem->m_Polygon; + SHAPE_POLY_SET polys = aGbrItem->m_Polygon.CloneDropTriangulation(); polys.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE ); if( polys.OutlineCount() == 0 ) diff --git a/libs/kimath/include/geometry/shape_poly_set.h b/libs/kimath/include/geometry/shape_poly_set.h index 73284ee5d3..528bd4fe5b 100644 --- a/libs/kimath/include/geometry/shape_poly_set.h +++ b/libs/kimath/include/geometry/shape_poly_set.h @@ -536,6 +536,8 @@ public: /// @copydoc SHAPE::Clone() SHAPE* Clone() const override; + SHAPE_POLY_SET CloneDropTriangulation() const; + ///< Creates a new empty polygon in the set and returns its index int NewOutline(); @@ -1366,6 +1368,10 @@ public: static const SHAPE_POLY_SET BuildPolysetFromOrientedPaths( const std::vector& aPaths, bool aReverseOrientation = false, bool aEvenOdd = false ); private: + enum DROP_TRIANGULATION_FLAG { SINGLETON }; + + SHAPE_POLY_SET( const SHAPE_POLY_SET& aOther, DROP_TRIANGULATION_FLAG ); + void fractureSingle( POLYGON& paths ); void unfractureSingle ( POLYGON& path ); void importTree( ClipperLib::PolyTree* tree, diff --git a/libs/kimath/src/geometry/shape_poly_set.cpp b/libs/kimath/src/geometry/shape_poly_set.cpp index ee15873c35..c2eae1b368 100644 --- a/libs/kimath/src/geometry/shape_poly_set.cpp +++ b/libs/kimath/src/geometry/shape_poly_set.cpp @@ -108,6 +108,16 @@ SHAPE_POLY_SET::SHAPE_POLY_SET( const SHAPE_POLY_SET& aOther ) : } +SHAPE_POLY_SET::SHAPE_POLY_SET( const SHAPE_POLY_SET& aOther, DROP_TRIANGULATION_FLAG ) : + SHAPE( aOther ), + m_polys( aOther.m_polys ) +{ + m_triangulationValid = false; + m_hash = MD5_HASH(); + m_triangulatedPolys.clear(); +} + + SHAPE_POLY_SET::~SHAPE_POLY_SET() { } @@ -119,6 +129,12 @@ SHAPE* SHAPE_POLY_SET::Clone() const } +SHAPE_POLY_SET SHAPE_POLY_SET::CloneDropTriangulation() const +{ + return SHAPE_POLY_SET( *this, DROP_TRIANGULATION_FLAG::SINGLETON ); +} + + bool SHAPE_POLY_SET::GetRelativeIndices( int aGlobalIdx, SHAPE_POLY_SET::VERTEX_INDEX* aRelativeIndices ) const { diff --git a/pcbnew/autorouter/ar_autoplacer.cpp b/pcbnew/autorouter/ar_autoplacer.cpp index 1dd6a6ada1..7ea7d6e8b1 100644 --- a/pcbnew/autorouter/ar_autoplacer.cpp +++ b/pcbnew/autorouter/ar_autoplacer.cpp @@ -145,7 +145,7 @@ bool AR_AUTOPLACER::fillMatrix() VECTOR2I coord_orgin = m_matrix.GetBrdCoordOrigin(); // Board coordinate of matruix cell (0,0) // Create a single board outline: - SHAPE_POLY_SET brd_shape = m_boardShape; + SHAPE_POLY_SET brd_shape = m_boardShape.CloneDropTriangulation(); brd_shape.Fracture( SHAPE_POLY_SET::PM_FAST ); const SHAPE_LINE_CHAIN& outline = brd_shape.Outline(0); const BOX2I& rect = outline.BBox(); @@ -800,7 +800,7 @@ void AR_AUTOPLACER::drawPlacementRoutingMatrix( ) m_overlay->SetIsFill( true ); m_overlay->SetIsStroke( false ); - SHAPE_POLY_SET freeArea = m_topFreeArea; + SHAPE_POLY_SET freeArea = m_topFreeArea.CloneDropTriangulation(); freeArea.Fracture( SHAPE_POLY_SET::PM_FAST ); // Draw the free polygon areas, top side: diff --git a/pcbnew/convert_shape_list_to_polygon.cpp b/pcbnew/convert_shape_list_to_polygon.cpp index 0cbce66cb6..52d36ecfc4 100644 --- a/pcbnew/convert_shape_list_to_polygon.cpp +++ b/pcbnew/convert_shape_list_to_polygon.cpp @@ -244,9 +244,9 @@ bool ConvertOutlineToPolygon( std::vector& aSegList, SHAPE_POLY_SET& case SHAPE_T::POLY: { - const SHAPE_POLY_SET poly = graphic->GetPolyShape(); - EDA_ANGLE orientation = ANGLE_0; - VECTOR2I offset = VECTOR2I( 0, 0 ); + const SHAPE_POLY_SET& poly = graphic->GetPolyShape(); + EDA_ANGLE orientation = ANGLE_0; + VECTOR2I offset = VECTOR2I( 0, 0 ); if( graphic->GetParentFootprint() ) { @@ -946,7 +946,7 @@ bool isCopperOutside( const FOOTPRINT* aMod, SHAPE_POLY_SET& aShape ) for( PAD* pad : aMod->Pads() ) { - SHAPE_POLY_SET poly = aShape; + SHAPE_POLY_SET poly = aShape.CloneDropTriangulation(); poly.BooleanIntersection( *pad->GetEffectivePolygon(), SHAPE_POLY_SET::PM_FAST ); diff --git a/pcbnew/drc/drc_test_provider_disallow.cpp b/pcbnew/drc/drc_test_provider_disallow.cpp index 462dfd5602..25ab38395e 100644 --- a/pcbnew/drc/drc_test_provider_disallow.cpp +++ b/pcbnew/drc/drc_test_provider_disallow.cpp @@ -130,7 +130,7 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run() // enough to exclude it. This is particularly important for detecting // copper fills as they will be exactly touching along the entire // exclusion border. - SHAPE_POLY_SET areaPoly = *ruleArea->Outline(); + SHAPE_POLY_SET areaPoly = ruleArea->Outline()->CloneDropTriangulation(); areaPoly.Deflate( epsilon, 0, SHAPE_POLY_SET::ALLOW_ACUTE_CORNERS ); DRC_RTREE* zoneRTree = board->m_CopperZoneRTrees[ copperZone ].get(); diff --git a/pcbnew/drc/drc_test_provider_library_parity.cpp b/pcbnew/drc/drc_test_provider_library_parity.cpp index 28e4e23eb5..708e068df9 100644 --- a/pcbnew/drc/drc_test_provider_library_parity.cpp +++ b/pcbnew/drc/drc_test_provider_library_parity.cpp @@ -294,11 +294,17 @@ bool zonesNeedUpdate( const FP_ZONE* a, const FP_ZONE* b ) TEST( a->Outline()->TotalVertices(), b->Outline()->TotalVertices() ); + // The footprint's zone will be in board position, so we must translate & rotate the library + // footprint's zone to match. + FOOTPRINT* parentFootprint = static_cast( a->GetParentFootprint() ); + const SHAPE_POLY_SET& aPoly = *a->Outline(); + SHAPE_POLY_SET bPoly = b->Outline()->CloneDropTriangulation(); + + bPoly.Rotate( parentFootprint->GetOrientation() ); + bPoly.Move( parentFootprint->GetPosition() ); + for( int ii = 0; ii < a->Outline()->TotalVertices(); ++ii ) - { - TEST( a->Outline()->CVertex( ii ) - a->GetParent()->GetPosition(), - b->Outline()->CVertex( ii ) - b->GetParent()->GetPosition() ); - } + TEST( aPoly.CVertex( ii ), bPoly.CVertex( ii ) ); return false; } diff --git a/pcbnew/drc/drc_test_provider_mechanical_clearance.cpp b/pcbnew/drc/drc_test_provider_mechanical_clearance.cpp index 0cc3817df1..1fc4956e00 100644 --- a/pcbnew/drc/drc_test_provider_mechanical_clearance.cpp +++ b/pcbnew/drc/drc_test_provider_mechanical_clearance.cpp @@ -516,7 +516,7 @@ void DRC_TEST_PROVIDER_MECHANICAL_CLEARANCE::testZoneLayer( ZONE* aZone, PCB_LAY { int epsilon = m_board->GetDesignSettings().GetDRCEpsilon(); int clearance = aConstraint.GetValue().Min(); - SHAPE_POLY_SET fill = *aZone->GetFilledPolysList( aLayer ); + SHAPE_POLY_SET fill = aZone->GetFilledPolysList( aLayer )->CloneDropTriangulation(); if( aConstraint.GetSeverity() == RPT_SEVERITY_IGNORE || clearance - epsilon <= 0 ) return; diff --git a/pcbnew/drc/drc_test_provider_sliver_checker.cpp b/pcbnew/drc/drc_test_provider_sliver_checker.cpp index be42b111de..451a0ec4f2 100644 --- a/pcbnew/drc/drc_test_provider_sliver_checker.cpp +++ b/pcbnew/drc/drc_test_provider_sliver_checker.cpp @@ -125,6 +125,7 @@ bool DRC_TEST_PROVIDER_SLIVER_CHECKER::Run() { PCB_LAYER_ID layer = copperLayers[i]; SHAPE_POLY_SET& poly = layerPolys[i]; + SHAPE_POLY_SET fill; forEachGeometryItem( s_allBasicItems, LSET().set( layer ), [&]( BOARD_ITEM* item ) -> bool @@ -135,11 +136,11 @@ bool DRC_TEST_PROVIDER_SLIVER_CHECKER::Run() if( !zone->GetIsRuleArea() ) { - SHAPE_POLY_SET layerPoly = *zone->GetFill( layer ); - layerPoly.Unfracture( SHAPE_POLY_SET::PM_FAST ); + fill = zone->GetFill( layer )->CloneDropTriangulation(); + fill.Unfracture( SHAPE_POLY_SET::PM_FAST ); - for( int jj = 0; jj < layerPoly.OutlineCount(); ++jj ) - poly.AddOutline( layerPoly.Outline( jj ) ); + for( int jj = 0; jj < fill.OutlineCount(); ++jj ) + poly.AddOutline( fill.Outline( jj ) ); // Report progress on board zones only. Everything // else is in the noise. diff --git a/pcbnew/drc/drc_test_provider_text_dims.cpp b/pcbnew/drc/drc_test_provider_text_dims.cpp index b97d4df0d3..681eb8f566 100644 --- a/pcbnew/drc/drc_test_provider_text_dims.cpp +++ b/pcbnew/drc/drc_test_provider_text_dims.cpp @@ -169,7 +169,7 @@ bool DRC_TEST_PROVIDER_TEXT_DIMS::Run() for( ii = 0; ii < outlineCount; ++ii ) holeCount += outlineGlyph->HoleCount( ii ); - SHAPE_POLY_SET poly = *outlineGlyph; + SHAPE_POLY_SET poly = outlineGlyph->CloneDropTriangulation(); poly.Deflate( constraint.Value().Min() / 2, 16 ); poly.Simplify( SHAPE_POLY_SET::PM_FAST ); diff --git a/pcbnew/exporters/export_hyperlynx.cpp b/pcbnew/exporters/export_hyperlynx.cpp index f407f7f17d..21f49166ec 100644 --- a/pcbnew/exporters/export_hyperlynx.cpp +++ b/pcbnew/exporters/export_hyperlynx.cpp @@ -485,45 +485,51 @@ bool HYPERLYNX_EXPORTER::writeNetObjects( const std::vector& aObjec for( PCB_LAYER_ID layer : zone->GetLayerSet().Seq() ) { const wxString layerName = m_board->GetLayerName( layer ); - SHAPE_POLY_SET filledShape = *zone->GetFilledPolysList( layer ); + SHAPE_POLY_SET fill = zone->GetFilledPolysList( layer )->CloneDropTriangulation(); - filledShape.Simplify( SHAPE_POLY_SET::PM_FAST ); + fill.Simplify( SHAPE_POLY_SET::PM_FAST ); - for( int i = 0; i < filledShape.OutlineCount(); i++ ) + for( int i = 0; i < fill.OutlineCount(); i++ ) { - const SHAPE_LINE_CHAIN& outl = filledShape.COutline( i ); + const SHAPE_LINE_CHAIN& outl = fill.COutline( i ); auto p0 = outl.CPoint( 0 ); m_out->Print( 1, "{POLYGON T=POUR L=\"%s\" ID=%d X=%.10f Y=%.10f\n", - (const char*) layerName.c_str(), m_polyId, iu2hyp( p0.x ), - iu2hyp( p0.y ) ); + (const char*) layerName.c_str(), + m_polyId, + iu2hyp( p0.x ), + iu2hyp( p0.y ) ); for( int v = 0; v < outl.PointCount(); v++ ) { - m_out->Print( 2, "(LINE X=%.10f Y=%.10f)\n", iu2hyp( outl.CPoint( v ).x ), - iu2hyp( outl.CPoint( v ).y ) ); + m_out->Print( 2, "(LINE X=%.10f Y=%.10f)\n", + iu2hyp( outl.CPoint( v ).x ), + iu2hyp( outl.CPoint( v ).y ) ); } m_out->Print( 2, "(LINE X=%.10f Y=%.10f)\n", iu2hyp( p0.x ), iu2hyp( p0.y ) ); m_out->Print( 1, "}\n" ); - for( int h = 0; h < filledShape.HoleCount( i ); h++ ) + for( int h = 0; h < fill.HoleCount( i ); h++ ) { - const SHAPE_LINE_CHAIN& holeShape = filledShape.CHole( i, h ); + const SHAPE_LINE_CHAIN& holeShape = fill.CHole( i, h ); VECTOR2I ph0 = holeShape.CPoint( 0 ); - m_out->Print( 1, "{POLYVOID ID=%d X=%.10f Y=%.10f\n", m_polyId, - iu2hyp( ph0.x ), iu2hyp( ph0.y ) ); + m_out->Print( 1, "{POLYVOID ID=%d X=%.10f Y=%.10f\n", + m_polyId, + iu2hyp( ph0.x ), + iu2hyp( ph0.y ) ); for( int v = 0; v < holeShape.PointCount(); v++ ) { m_out->Print( 2, "(LINE X=%.10f Y=%.10f)\n", - iu2hyp( holeShape.CPoint( v ).x ), - iu2hyp( holeShape.CPoint( v ).y ) ); + iu2hyp( holeShape.CPoint( v ).x ), + iu2hyp( holeShape.CPoint( v ).y ) ); } m_out->Print( 2, "(LINE X=%.10f Y=%.10f)\n", - iu2hyp( ph0.x ), iu2hyp( ph0.y ) ); + iu2hyp( ph0.x ), + iu2hyp( ph0.y ) ); m_out->Print( 1, "}\n" ); } diff --git a/pcbnew/footprint.cpp b/pcbnew/footprint.cpp index 70f6f23513..2a190e355d 100644 --- a/pcbnew/footprint.cpp +++ b/pcbnew/footprint.cpp @@ -894,7 +894,7 @@ SHAPE_POLY_SET FOOTPRINT::GetBoundingHull() const { for( PCB_LAYER_ID layer : zone->GetLayerSet().Seq() ) { - SHAPE_POLY_SET layerPoly = *zone->GetFilledPolysList( layer ); + const SHAPE_POLY_SET& layerPoly = *zone->GetFilledPolysList( layer ); for( int ii = 0; ii < layerPoly.OutlineCount(); ii++ ) { diff --git a/pcbnew/pcb_expr_evaluator.cpp b/pcbnew/pcb_expr_evaluator.cpp index 95545a63f3..23dc60118d 100644 --- a/pcbnew/pcb_expr_evaluator.cpp +++ b/pcbnew/pcb_expr_evaluator.cpp @@ -452,7 +452,7 @@ bool calcIsInsideArea( BOARD_ITEM* aItem, const EDA_RECT& aItemBBox, PCB_EXPR_CO // Collisions include touching, so we need to deflate outline by enough to exclude it. // This is particularly important for detecting copper fills as they will be exactly // touching along the entire exclusion border. - SHAPE_POLY_SET areaOutline = *aArea->Outline(); + SHAPE_POLY_SET areaOutline = aArea->Outline()->CloneDropTriangulation(); areaOutline.Deflate( board->GetDesignSettings().GetDRCEpsilon(), 0, SHAPE_POLY_SET::ALLOW_ACUTE_CORNERS ); @@ -498,7 +498,7 @@ bool calcIsInsideArea( BOARD_ITEM* aItem, const EDA_RECT& aItemBBox, PCB_EXPR_CO if( ( aArea->GetLayerSet() & LSET::FrontMask() ).any() ) { - SHAPE_POLY_SET courtyard = footprint->GetPolyCourtyard( F_CrtYd ); + const SHAPE_POLY_SET& courtyard = footprint->GetPolyCourtyard( F_CrtYd ); if( courtyard.OutlineCount() == 0 ) { @@ -515,7 +515,7 @@ bool calcIsInsideArea( BOARD_ITEM* aItem, const EDA_RECT& aItemBBox, PCB_EXPR_CO if( ( aArea->GetLayerSet() & LSET::BackMask() ).any() ) { - SHAPE_POLY_SET courtyard = footprint->GetPolyCourtyard( B_CrtYd ); + const SHAPE_POLY_SET& courtyard = footprint->GetPolyCourtyard( B_CrtYd ); if( courtyard.OutlineCount() == 0 ) { diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index a7205992cb..6ebf197bf2 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -546,7 +546,7 @@ bool PCB_PAINTER::Draw( const VIEW_ITEM* aItem, int aLayer ) if( fp ) { - SHAPE_POLY_SET convex = fp->GetBoundingHull(); + const SHAPE_POLY_SET& convex = fp->GetBoundingHull(); m_gal->DrawPolyline( convex.COutline( 0 ) ); } @@ -1953,7 +1953,7 @@ void PCB_PAINTER::draw( const FOOTPRINT* aFootprint, int aLayer ) m_gal->SetIsStroke( false ); m_gal->SetFillColor( color ); - SHAPE_POLY_SET poly = aFootprint->GetBoundingHull(); + const SHAPE_POLY_SET& poly = aFootprint->GetBoundingHull(); m_gal->DrawPolygon( poly ); } } diff --git a/pcbnew/plot_board_layers.cpp b/pcbnew/plot_board_layers.cpp index c9f88b15e3..272e734ced 100644 --- a/pcbnew/plot_board_layers.cpp +++ b/pcbnew/plot_board_layers.cpp @@ -614,7 +614,7 @@ void PlotStandardLayer( BOARD* aBoard, PLOTTER* aPlotter, LSET aLayerMask, if( !aLayerMask[layer] ) continue; - SHAPE_POLY_SET mainArea = *zone->GetFilledPolysList( layer ); + SHAPE_POLY_SET mainArea = zone->GetFilledPolysList( layer )->CloneDropTriangulation(); SHAPE_POLY_SET islands; for( int i = mainArea.OutlineCount() - 1; i >= 0; i-- ) diff --git a/pcbnew/plot_brditems_plotter.cpp b/pcbnew/plot_brditems_plotter.cpp index 0c586c7f71..366a5763a3 100644 --- a/pcbnew/plot_brditems_plotter.cpp +++ b/pcbnew/plot_brditems_plotter.cpp @@ -1013,7 +1013,7 @@ void BRDITEMS_PLOTTER::PlotPcbShape( const PCB_SHAPE* aShape ) // ( for the future or to show a non expected shape ) // This must be simplified and fractured to prevent overlapping polygons // from generating invalid Gerber files - SHAPE_POLY_SET tmpPoly = SHAPE_POLY_SET( aShape->GetPolyShape() ); + SHAPE_POLY_SET tmpPoly = aShape->GetPolyShape().CloneDropTriangulation(); tmpPoly.Fracture( SHAPE_POLY_SET::PM_FAST ); FILL_T fill = aShape->IsFilled() ? FILL_T::FILLED_SHAPE : FILL_T::NO_FILL; diff --git a/pcbnew/zone.cpp b/pcbnew/zone.cpp index 292ed91a0d..ac60d2a9a5 100644 --- a/pcbnew/zone.cpp +++ b/pcbnew/zone.cpp @@ -1060,7 +1060,7 @@ bool ZONE::BuildSmoothedPoly( SHAPE_POLY_SET& aSmoothedPoly, PCB_LAYER_ID aLayer // Processing of arc shapes in zones is not yet supported because Clipper can't do boolean // operations on them. The poly outline must be converted to segments first. - SHAPE_POLY_SET flattened = *m_Poly; + SHAPE_POLY_SET flattened = m_Poly->CloneDropTriangulation(); flattened.ClearArcs(); if( GetIsRuleArea() ) @@ -1132,22 +1132,19 @@ bool ZONE::BuildSmoothedPoly( SHAPE_POLY_SET& aSmoothedPoly, PCB_LAYER_ID aLayer for( ZONE* zone : interactingZones ) { - SHAPE_POLY_SET flattened_outline = *zone->Outline(); + SHAPE_POLY_SET flattened_outline = zone->Outline()->CloneDropTriangulation(); flattened_outline.ClearArcs(); aSmoothedPoly.BooleanAdd( flattened_outline, SHAPE_POLY_SET::PM_FAST ); } if( aBoardOutline ) - { - SHAPE_POLY_SET poly = *aBoardOutline; - aSmoothedPoly.BooleanIntersection( poly, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE ); - } + aSmoothedPoly.BooleanIntersection( *aBoardOutline, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE ); smooth( aSmoothedPoly ); if( aSmoothedPolyWithApron ) { - SHAPE_POLY_SET poly = *maxExtents; + SHAPE_POLY_SET poly = maxExtents->CloneDropTriangulation(); poly.Inflate( m_ZoneMinThickness, 64 ); *aSmoothedPolyWithApron = aSmoothedPoly; aSmoothedPolyWithApron->BooleanIntersection( poly, SHAPE_POLY_SET::PM_FAST ); diff --git a/pcbnew/zone_filler.cpp b/pcbnew/zone_filler.cpp index 75f4bf896b..6719a84553 100644 --- a/pcbnew/zone_filler.cpp +++ b/pcbnew/zone_filler.cpp @@ -921,7 +921,7 @@ void ZONE_FILLER::subtractHigherPriorityZones( const ZONE* aZone, PCB_LAYER_ID a // Processing of arc shapes in zones is not yet supported because Clipper // can't do boolean operations on them. The poly outline must be converted to // segments first. - SHAPE_POLY_SET outline = *aKnockout->Outline(); + SHAPE_POLY_SET outline = aKnockout->Outline()->CloneDropTriangulation(); outline.ClearArcs(); aRawFill.BooleanSubtract( outline, SHAPE_POLY_SET::PM_FAST ); @@ -1034,7 +1034,7 @@ bool ZONE_FILLER::fillCopperZone( const ZONE* aZone, PCB_LAYER_ID aLayer, PCB_LA // Create a temporary zone that we can hit-test spoke-ends against. It's only temporary // because the "real" subtract-clearance-holes has to be done after the spokes are added. static const bool USE_BBOX_CACHES = true; - SHAPE_POLY_SET testAreas = aFillPolys; + SHAPE_POLY_SET testAreas = aFillPolys.CloneDropTriangulation(); testAreas.BooleanSubtract( clearanceHoles, SHAPE_POLY_SET::PM_FAST ); DUMP_POLYS_TO_COPPER_LAYER( testAreas, In4_Cu, wxT( "minus-clearance-holes" ) ); @@ -1395,7 +1395,7 @@ bool ZONE_FILLER::addHatchFillTypeOnZone( const ZONE* aZone, PCB_LAYER_ID aLayer int linethickness = thickness - aZone->GetMinThickness(); int gridsize = thickness + aZone->GetHatchGap(); - SHAPE_POLY_SET filledPolys = aFillPolys; + SHAPE_POLY_SET filledPolys = aFillPolys.CloneDropTriangulation(); // Use a area that contains the rotated bbox by orientation, and after rotate the result // by -orientation. if( !aZone->GetHatchOrientation().IsZero() ) @@ -1517,12 +1517,12 @@ bool ZONE_FILLER::addHatchFillTypeOnZone( const ZONE* aZone, PCB_LAYER_ID aLayer // The fill has already been deflated to ensure GetMinThickness() so we just have to // account for anything beyond that. - SHAPE_POLY_SET deflatedFilledPolys = aFillPolys; + SHAPE_POLY_SET deflatedFilledPolys = aFillPolys.CloneDropTriangulation(); deflatedFilledPolys.Deflate( outline_margin - aZone->GetMinThickness(), 16 ); holes.BooleanIntersection( deflatedFilledPolys, SHAPE_POLY_SET::PM_FAST ); DUMP_POLYS_TO_COPPER_LAYER( holes, In11_Cu, wxT( "fill-clipped-hatch-holes" ) ); - SHAPE_POLY_SET deflatedOutline = *aZone->Outline(); + SHAPE_POLY_SET deflatedOutline = aZone->Outline()->CloneDropTriangulation(); deflatedOutline.Deflate( outline_margin, 16 ); holes.BooleanIntersection( deflatedOutline, SHAPE_POLY_SET::PM_FAST ); DUMP_POLYS_TO_COPPER_LAYER( holes, In12_Cu, wxT( "outline-clipped-hatch-holes" ) );