router: provisional fix for 14926

This commit is contained in:
Tomasz Wlostowski 2023-06-22 00:33:10 +02:00
parent 206f66aee2
commit bd5954242e
2 changed files with 46 additions and 11 deletions

View File

@ -45,27 +45,48 @@ static void dumpObstacles( const PNS::NODE::OBSTACLES &obstacles )
}
// prune self-collisions, i.e. a via/pad annular ring with its own hole
static bool shouldWeConsiderHoleCollisions( const ITEM* aItem, const ITEM *aHead )
static bool shouldWeConsiderHoleCollisions( const ITEM* aItem, const ITEM* aHead )
{
const HOLE *hi = aItem->OfKind( ITEM::HOLE_T ) ? static_cast<const HOLE*>( aItem ) : nullptr;
const HOLE *hh = aHead->OfKind( ITEM::HOLE_T ) ? static_cast<const HOLE*>( aHead ) : nullptr;
const HOLE* holeI = aItem->OfKind( ITEM::HOLE_T ) ? static_cast<const HOLE*>( aItem ) : nullptr;
const HOLE* holeH = aHead->OfKind( ITEM::HOLE_T ) ? static_cast<const HOLE*>( aHead ) : nullptr;
if( hi && hh ) // hole-to-hole case
if( holeI && holeH ) // hole-to-hole case
{
if ( !hi->ParentPadVia() || !hh->ParentPadVia() )
const ITEM* parentI = holeI->ParentPadVia();
const ITEM* parentH = holeH->ParentPadVia();
if( !parentH || !parentI )
return true;
return hi->ParentPadVia() != hh->ParentPadVia();
const VIA* parentViaI = dyn_cast<const VIA*>( parentI );
const VIA* parentViaH = dyn_cast<const VIA*>( parentH );
// Note to self: the if() below is an ugly heuristic to determine if we aren't trying to check for collisions
// of the hole of the via with another (although identical) copy of it. Such case occurs when
// checking a LINE against a NODE where this LINE has been already added. LINE has no notion of
// ownership of it's via (it's just a copy) and before hole-to-hole clearance support has been introduced
// it didn't matter becasue we didn't consider collisions of the objects belonging to the same net anyway
// Now that hole clearance check doesn't care about the nets assigned to the parent vias/solids, I'll probably
// have to refactor the LINE class to manage ownership of its (optional) VIA. For the moment, we just treat
// via holes that are geometrically identical and belonging to the same net as non-colliding.
if( parentViaI && parentViaH && parentViaI->Pos() == parentViaH->Pos()
&& parentViaI->Diameter() == parentViaH->Diameter()
&& parentViaI->Net() == parentViaH->Net()
&& parentViaI->Drill() == parentViaH->Drill() )
return false;
return parentI != parentH;
}
if( hi )
return hi->ParentPadVia() != aHead;
else if( hh )
return hh->ParentPadVia() != aItem;
if( holeI )
return holeI->ParentPadVia() != aHead;
else if( holeH )
return holeH->ParentPadVia() != aItem;
else
return true;
}
bool ITEM::collideSimple( const ITEM* aHead, const NODE* aNode,
COLLISION_SEARCH_CONTEXT* aCtx ) const
{
@ -275,4 +296,13 @@ const std::string ITEM::Format() const
return ss.str();
}
const NODE* ITEM::OwningNode() const
{
if( ParentPadVia() )
return static_cast<const NODE*>( ParentPadVia()->Owner() );
else
return static_cast<const NODE*>( Owner() );
}
} // namespace PNS

View File

@ -50,7 +50,10 @@ class ITEM;
class HOLE;
struct COLLISION_SEARCH_CONTEXT;
class ITEM_OWNER {};
class ITEM_OWNER {
public:
virtual ~ITEM_OWNER() {};
};
class OWNABLE_ITEM
{
@ -266,6 +269,8 @@ public:
virtual const std::string Format() const;
virtual const NODE* OwningNode() const;
private:
bool collideSimple( const ITEM* aHead, const NODE* aNode,
COLLISION_SEARCH_CONTEXT* aCtx ) const;