From b08280d00c9a150399916e9b59e0608a0efdd121 Mon Sep 17 00:00:00 2001 From: Tomasz Wlostowski Date: Fri, 4 Mar 2022 00:58:14 +0100 Subject: [PATCH] router: enable Hole Clearance rule only in Mark Obstacles mode (it will be brought back to Walk/Shove modes as soon as all the underlying issues are fixed) --- pcbnew/router/pns_item.cpp | 2 +- pcbnew/router/pns_node.cpp | 6 +++--- pcbnew/router/pns_node.h | 20 ++++++++++++++++++++ pcbnew/router/pns_router.cpp | 18 ++++++++++++++++++ pcbnew/router/pns_via.cpp | 28 +++++++++++++++++----------- 5 files changed, 59 insertions(+), 15 deletions(-) diff --git a/pcbnew/router/pns_item.cpp b/pcbnew/router/pns_item.cpp index 8de76802d5..f7ca5e48d9 100644 --- a/pcbnew/router/pns_item.cpp +++ b/pcbnew/router/pns_item.cpp @@ -88,7 +88,7 @@ bool ITEM::collideSimple( const ITEM* aOther, const NODE* aNode, bool aDifferent if( zoneB && Parent() && !checkKeepout( zoneB, Parent() ) ) return false; - if( holeA || holeB ) + if( aNode->GetCollisionQueryScope() == NODE::CQS_ALL_RULES && (holeA || holeB ) ) { int holeClearance = aNode->GetHoleClearance( this, aOther ); diff --git a/pcbnew/router/pns_node.cpp b/pcbnew/router/pns_node.cpp index f87a1fd559..d652d420f0 100644 --- a/pcbnew/router/pns_node.cpp +++ b/pcbnew/router/pns_node.cpp @@ -59,6 +59,7 @@ NODE::NODE() m_maxClearance = 800000; // fixme: depends on how thick traces are. m_ruleResolver = nullptr; m_index = new INDEX; + m_collisionQueryScope = CQS_ALL_RULES; #ifdef DEBUG allocNodes.insert( this ); @@ -146,6 +147,7 @@ NODE* NODE::Branch() child->m_ruleResolver = m_ruleResolver; child->m_root = isRoot() ? this : m_root; child->m_maxClearance = m_maxClearance; + child->m_collisionQueryScope = m_collisionQueryScope; // Immediate offspring of the root branch needs not copy anything. For the rest, deep-copy // joints, overridden item maps and pointers to stored items. @@ -385,7 +387,7 @@ NODE::OPT_OBSTACLE NODE::NearestObstacle( const LINE* aLine, int aKindMask, updateNearest( ip, obstacle.m_item, obstacleHull, false ); } - if( obstacle.m_item->Hole() ) + if( m_collisionQueryScope == CQS_ALL_RULES && obstacle.m_item->Hole() ) { clearance = GetHoleClearance( obstacle.m_item, aLine ) + aLine->Width() / 2; obstacleHull = obstacle.m_item->HoleHull( clearance + PNS_HULL_MARGIN, 0, layer ); @@ -428,8 +430,6 @@ NODE::OPT_OBSTACLE NODE::NearestObstacle( const LINE* aLine, int aKindMask, if( nearest.m_distFirst == INT_MAX ) nearest.m_item = obstacleList[0].m_item; - // debugDecorator->AddLine( nearest.m_hull, YELLOW, 60000, "obstacle-nearest-hull" ); - return nearest; } diff --git a/pcbnew/router/pns_node.h b/pcbnew/router/pns_node.h index d6388b3da2..d272dc66b1 100644 --- a/pcbnew/router/pns_node.h +++ b/pcbnew/router/pns_node.h @@ -146,6 +146,14 @@ protected: class NODE { public: + +///< Supported item types + enum COLLISION_QUERY_SCOPE + { + CQS_ALL_RULES = 1, ///< check all rules + CQS_IGNORE_HOLE_CLEARANCE = 2 ///< check everything except hole2hole / hole2copper + }; + typedef OPT OPT_OBSTACLE; typedef std::vector ITEM_VECTOR; typedef std::vector OBSTACLES; @@ -388,6 +396,16 @@ public: void FixupVirtualVias(); + void SetCollisionQueryScope( COLLISION_QUERY_SCOPE aScope ) + { + m_collisionQueryScope = aScope; + } + + COLLISION_QUERY_SCOPE GetCollisionQueryScope() const + { + return m_collisionQueryScope; + } + private: void Add( std::unique_ptr< ITEM > aItem, bool aAllowRedundant = false ); @@ -460,6 +478,8 @@ private: ///< inheritance chain) std::unordered_set m_garbageItems; + + COLLISION_QUERY_SCOPE m_collisionQueryScope; }; } diff --git a/pcbnew/router/pns_router.cpp b/pcbnew/router/pns_router.cpp index 88a96276cf..f94a8a4e63 100644 --- a/pcbnew/router/pns_router.cpp +++ b/pcbnew/router/pns_router.cpp @@ -157,6 +157,15 @@ bool ROUTER::StartDragging( const VECTOR2I& aP, ITEM_SET aStartItems, int aDragM if( aStartItems.Empty() ) return false; + if( Settings().Mode() == RM_MarkObstacles ) + { + m_world->SetCollisionQueryScope( NODE::CQS_ALL_RULES ); + } + else + { + m_world->SetCollisionQueryScope( NODE::CQS_IGNORE_HOLE_CLEARANCE ); + } + if( aStartItems.Count( ITEM::SOLID_T ) == aStartItems.Size() ) { m_dragger = std::make_unique( this ); @@ -372,6 +381,15 @@ bool ROUTER::isStartingPointRoutable( const VECTOR2I& aWhere, ITEM* aStartItem, bool ROUTER::StartRouting( const VECTOR2I& aP, ITEM* aStartItem, int aLayer ) { + if( Settings().Mode() == RM_MarkObstacles ) + { + m_world->SetCollisionQueryScope( NODE::CQS_ALL_RULES ); + } + else + { + m_world->SetCollisionQueryScope( NODE::CQS_IGNORE_HOLE_CLEARANCE ); + } + if( !isStartingPointRoutable( aP, aStartItem, aLayer ) ) return false; diff --git a/pcbnew/router/pns_via.cpp b/pcbnew/router/pns_via.cpp index 5f3a3f9572..dea030012e 100644 --- a/pcbnew/router/pns_via.cpp +++ b/pcbnew/router/pns_via.cpp @@ -32,23 +32,29 @@ namespace PNS { bool VIA::PushoutForce( NODE* aNode, const ITEM* aOther, VECTOR2I& aForce ) { int clearance = aNode->GetClearance( this, aOther ); - int holeClearance = aNode->GetHoleClearance( this, aOther ); - int hole2holeClearance = aNode->GetHoleToHoleClearance( this, aOther ); - VECTOR2I f[4], force; + VECTOR2I elementForces[4], force; + size_t nf = 0; - if( aOther->Hole() ) + if( aNode->GetCollisionQueryScope() == NODE::CQS_ALL_RULES ) { - aOther->Hole()->Collide( Shape(), holeClearance, &f[0] ); - aOther->Hole()->Collide( Hole(), hole2holeClearance, &f[1] ); + int holeClearance = aNode->GetHoleClearance( this, aOther ); + int hole2holeClearance = aNode->GetHoleToHoleClearance( this, aOther ); + + if( aOther->Hole() ) + { + aOther->Hole()->Collide( Shape(), holeClearance, &elementForces[nf++] ); + aOther->Hole()->Collide( Hole(), hole2holeClearance, &elementForces[nf++] ); + } + + aOther->Shape()->Collide( Hole(), holeClearance, &elementForces[nf++] ); } - aOther->Shape()->Collide( Shape(), clearance, &f[2] ); - aOther->Shape()->Collide( Hole(), holeClearance, &f[3] ); + aOther->Shape()->Collide( Shape(), clearance, &elementForces[nf++] ); - for( int i = 0; i < 4; i++ ) + for( size_t i = 0; i < nf; i++ ) { - if( f[i].SquaredEuclideanNorm() > force.SquaredEuclideanNorm() ) - force = f[i]; + if( elementForces[i].SquaredEuclideanNorm() > force.SquaredEuclideanNorm() ) + force = elementForces[i]; } aForce = force;