From e4b56ab7f12a97b0c7edfa6bb1c038e7cabcaa35 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Tue, 8 Mar 2022 23:54:34 +0000 Subject: [PATCH] Performance fixes for the board from hell.... --- libs/kimath/src/geometry/shape_poly_set.cpp | 2 +- pcbnew/drc/drc_rtree.h | 33 +++++++++++++++++++-- pcbnew/zone.cpp | 2 ++ 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/libs/kimath/src/geometry/shape_poly_set.cpp b/libs/kimath/src/geometry/shape_poly_set.cpp index e49e409b15..74c04b0f45 100644 --- a/libs/kimath/src/geometry/shape_poly_set.cpp +++ b/libs/kimath/src/geometry/shape_poly_set.cpp @@ -1518,7 +1518,7 @@ bool SHAPE_POLY_SET::Collide( const SHAPE* aShape, int aClearance, int* aActual, return false; } - const_cast( this )->CacheTriangulation( true ); + const_cast( this )->CacheTriangulation( false ); int actual = INT_MAX; VECTOR2I location; diff --git a/pcbnew/drc/drc_rtree.h b/pcbnew/drc/drc_rtree.h index 28de9192d9..64813ac8c3 100644 --- a/pcbnew/drc/drc_rtree.h +++ b/pcbnew/drc/drc_rtree.h @@ -320,11 +320,37 @@ public: */ bool QueryColliding( EDA_RECT aBox, SHAPE* aRefShape, PCB_LAYER_ID aLayer ) const { + SHAPE_POLY_SET* poly = dynamic_cast( aRefShape ); + int min[2] = { aBox.GetX(), aBox.GetY() }; int max[2] = { aBox.GetRight(), aBox.GetBottom() }; bool collision = false; - auto visit = + // Special case the polygon case. Otherwise we'll call its Collide() method which will + // triangulate it as well and then do triangle/triangle collisions. This ends up being + // slower than 4 calls to PointInside(). + auto polyVisitor = + [&]( ITEM_WITH_SHAPE* aItem ) -> bool + { + SHAPE* shape = aItem->shape; + wxASSERT( dynamic_cast( shape ) ); + auto tri = static_cast( shape ); + + const SHAPE_LINE_CHAIN& outline = poly->Outline( 0 ); + + if( outline.PointInside( tri->GetPoint( 0 ) ) + || outline.PointInside( tri->GetPoint( 1 ) ) + || outline.PointInside( tri->GetPoint( 2 ) ) + || tri->PointInside( outline.CPoint( 0 ) ) ) + { + collision = true; + return false; + } + + return true; + }; + + auto visitor = [&]( ITEM_WITH_SHAPE* aItem ) -> bool { if( aRefShape->Collide( aItem->shape, 0 ) ) @@ -336,7 +362,10 @@ public: return true; }; - this->m_tree[aLayer]->Search( min, max, visit ); + if( poly && poly->OutlineCount() == 1 ) + this->m_tree[aLayer]->Search( min, max, polyVisitor ); + else + this->m_tree[aLayer]->Search( min, max, visitor ); return collision; } diff --git a/pcbnew/zone.cpp b/pcbnew/zone.cpp index 55caca755a..65b171db04 100644 --- a/pcbnew/zone.cpp +++ b/pcbnew/zone.cpp @@ -997,6 +997,8 @@ void ZONE::CacheTriangulation( PCB_LAYER_ID aLayer ) { for( std::pair>& pair : m_FilledPolysList ) pair.second->CacheTriangulation(); + + m_Poly->CacheTriangulation( false ); } else {