KiCad PCB EDA Suite
PNS::NODE Class Reference

Keep the router "world" - i.e. More...

#include <pns_node.h>

Classes

struct  DEFAULT_OBSTACLE_VISITOR
 

Public Types

enum  COLLISION_QUERY_SCOPE { CQS_ALL_RULES = 1 , CQS_IGNORE_HOLE_CLEARANCE = 2 }
 < Supported item types More...
 
typedef std::optional< OBSTACLEOPT_OBSTACLE
 
typedef std::vector< ITEM * > ITEM_VECTOR
 
typedef std::vector< OBSTACLEOBSTACLES
 

Public Member Functions

 NODE ()
 
 ~NODE ()
 Return the expected clearance between items a and b. More...
 
int GetClearance (const ITEM *aA, const ITEM *aB, bool aUseClearanceEpsilon=true) const
 
int GetHoleClearance (const ITEM *aA, const ITEM *aB, bool aUseClearanceEpsilon=true) const
 
int GetHoleToHoleClearance (const ITEM *aA, const ITEM *aB, bool aUseClearanceEpsilon=true) const
 Return the pre-set worst case clearance between any pair of items. More...
 
int GetMaxClearance () const
 Set the worst-case clearance between any pair of items. More...
 
void SetMaxClearance (int aClearance)
 Assign a clearance resolution function object. More...
 
void SetRuleResolver (RULE_RESOLVER *aFunc)
 
RULE_RESOLVERGetRuleResolver () const
 Return the number of joints. More...
 
int JointCount () const
 Return the number of nodes in the inheritance chain (wrs to the root node). More...
 
int Depth () const
 
int QueryColliding (const ITEM *aItem, OBSTACLES &aObstacles, int aKindMask=ITEM::ANY_T, int aLimitCount=-1, bool aDifferentNetsOnly=true, int aOverrideClearance=-1)
 Find items colliding (closer than clearance) with the item aItem. More...
 
int QueryJoints (const BOX2I &aBox, std::vector< JOINT * > &aJoints, LAYER_RANGE aLayerMask=LAYER_RANGE::All(), int aKindMask=ITEM::ANY_T)
 
OPT_OBSTACLE NearestObstacle (const LINE *aLine, int aKindMask=ITEM::ANY_T, const std::set< ITEM * > *aRestrictedSet=nullptr, bool aUseClearanceEpsilon=true)
 Follow the line in search of an obstacle that is nearest to the starting to the line's starting point. More...
 
OPT_OBSTACLE CheckColliding (const ITEM *aItem, int aKindMask=ITEM::ANY_T)
 Check if the item collides with anything else in the world, and if found, returns the obstacle. More...
 
OPT_OBSTACLE CheckColliding (const ITEM_SET &aSet, int aKindMask=ITEM::ANY_T)
 Check if any item in the set collides with anything else in the world, and if found, returns the obstacle. More...
 
const ITEM_SET HitTest (const VECTOR2I &aPoint) const
 Find all items that contain the point aPoint. More...
 
bool Add (std::unique_ptr< SEGMENT > aSegment, bool aAllowRedundant=false)
 Add an item to the current node. More...
 
void Add (std::unique_ptr< SOLID > aSolid)
 
void Add (std::unique_ptr< VIA > aVia)
 
bool Add (std::unique_ptr< ARC > aArc, bool aAllowRedundant=false)
 
void Add (LINE &aLine, bool aAllowRedundant=false)
 
void AddEdgeExclusion (std::unique_ptr< SHAPE > aShape)
 
bool QueryEdgeExclusions (const VECTOR2I &aPos) const
 
void Remove (ARC *aArc)
 Remove an item from this branch. More...
 
void Remove (SOLID *aSolid)
 
void Remove (VIA *aVia)
 
void Remove (SEGMENT *aSegment)
 
void Remove (ITEM *aItem)
 
void Remove (LINE &aLine)
 Removes a line from this branch. More...
 
void Replace (ITEM *aOldItem, std::unique_ptr< ITEM > aNewItem)
 Replace an item with another one. More...
 
void Replace (LINE &aOldLine, LINE &aNewLine)
 
NODEBranch ()
 Create a lightweight copy (called branch) of self that tracks the changes (added/removed items) wrs to the root. More...
 
const LINE AssembleLine (LINKED_ITEM *aSeg, int *aOriginSegmentIndex=nullptr, bool aStopAtLockedJoints=false, bool aFollowLockedSegments=false)
 Follow the joint map to assemble a line connecting two non-trivial joints starting from segment aSeg. More...
 
void Dump (bool aLong=false)
 
void GetUpdatedItems (ITEM_VECTOR &aRemoved, ITEM_VECTOR &aAdded)
 Return the list of items removed and added in this branch with respect to the root branch. More...
 
void Commit (NODE *aNode)
 Apply the changes from a given branch (aNode) to the root branch. More...
 
JOINTFindJoint (const VECTOR2I &aPos, int aLayer, int aNet)
 Search for a joint at a given position, layer and belonging to given net. More...
 
void LockJoint (const VECTOR2I &aPos, const ITEM *aItem, bool aLock)
 
JOINTFindJoint (const VECTOR2I &aPos, const ITEM *aItem)
 Search for a joint at a given position, linked to given item. More...
 
int FindLinesBetweenJoints (const JOINT &aA, const JOINT &aB, std::vector< LINE > &aLines)
 Find the joints corresponding to the ends of line aLine. More...
 
void FindLineEnds (const LINE &aLine, JOINT &aA, JOINT &aB)
 Destroy all child nodes. Applicable only to the root node. More...
 
void KillChildren ()
 
void AllItemsInNet (int aNet, std::set< ITEM * > &aItems, int aKindMask=-1)
 
void ClearRanks (int aMarkerMask=MK_HEAD|MK_VIOLATION|MK_HOLE)
 
void RemoveByMarker (int aMarker)
 
ITEMFindItemByParent (const BOARD_ITEM *aParent)
 
bool HasChildren () const
 
NODEGetParent () const
 Check if this branch contains an updated version of the m_item from the root branch. More...
 
bool Overrides (ITEM *aItem) const
 
void FixupVirtualVias ()
 
void SetCollisionQueryScope (COLLISION_QUERY_SCOPE aScope)
 
COLLISION_QUERY_SCOPE GetCollisionQueryScope () const
 
void Add (std::unique_ptr< ITEM > aItem, bool aAllowRedundant=false)
 

Private Types

typedef std::unordered_multimap< JOINT::HASH_TAG, JOINT, JOINT::JOINT_TAG_HASHJOINT_MAP
 
typedef JOINT_MAP::value_type TagJointPair
 

Private Member Functions

 NODE (const NODE &aB)
 nodes are not copyable More...
 
NODEoperator= (const NODE &aB)
 Try to find matching joint and creates a new one if not found. More...
 
JOINTtouchJoint (const VECTOR2I &aPos, const LAYER_RANGE &aLayers, int aNet)
 Touch a joint and links it to an m_item. More...
 
void linkJoint (const VECTOR2I &aPos, const LAYER_RANGE &aLayers, int aNet, ITEM *aWhere)
 Unlink an item from a joint. More...
 
void unlinkJoint (const VECTOR2I &aPos, const LAYER_RANGE &aLayers, int aNet, ITEM *aWhere)
 Helpers for adding/removing items. More...
 
void addSolid (SOLID *aSeg)
 
void addSegment (SEGMENT *aSeg)
 
void addVia (VIA *aVia)
 
void addArc (ARC *aVia)
 
void removeSolidIndex (SOLID *aSeg)
 
void removeSegmentIndex (SEGMENT *aSeg)
 
void removeViaIndex (VIA *aVia)
 
void removeArcIndex (ARC *aVia)
 
void doRemove (ITEM *aItem)
 
void unlinkParent ()
 
void releaseChildren ()
 
void releaseGarbage ()
 
void rebuildJoint (JOINT *aJoint, ITEM *aItem)
 
bool isRoot () const
 
SEGMENTfindRedundantSegment (const VECTOR2I &A, const VECTOR2I &B, const LAYER_RANGE &lr, int aNet)
 
SEGMENTfindRedundantSegment (SEGMENT *aSeg)
 
ARCfindRedundantArc (const VECTOR2I &A, const VECTOR2I &B, const LAYER_RANGE &lr, int aNet)
 
ARCfindRedundantArc (ARC *aSeg)
 Scan the joint map, forming a line starting from segment (current). More...
 
void followLine (LINKED_ITEM *aCurrent, bool aScanDirection, int &aPos, int aLimit, VECTOR2I *aCorners, LINKED_ITEM **aSegments, bool *aArcReversed, bool &aGuardHit, bool aStopAtLockedJoints, bool aFollowLockedSegments)
 

Private Attributes

JOINT_MAP m_joints
 hash table with the joints, linking the items. More...
 
NODEm_parent
 node this node was branched from More...
 
NODEm_root
 root node of the whole hierarchy More...
 
std::set< NODE * > m_children
 list of nodes branched from this one More...
 
std::unordered_set< ITEM * > m_override
 hash of root's items that have been changed in this node More...
 
int m_maxClearance
 worst case item-item clearance More...
 
RULE_RESOLVERm_ruleResolver
 Design rules resolver. More...
 
INDEXm_index
 Geometric/Net index of the items. More...
 
int m_depth
 depth of the node (number of parent nodes in the inheritance chain) More...
 
std::vector< std::unique_ptr< SHAPE > > m_edgeExclusions
 
std::unordered_set< ITEM * > m_garbageItems
 
COLLISION_QUERY_SCOPE m_collisionQueryScope
 

Detailed Description

Keep the router "world" - i.e.

all the tracks, vias, solids in a hierarchical and indexed way.

Features:

  • spatial-indexed container for PCB item shapes.
  • collision search & clearance checking.
  • assembly of lines connecting joints, finding loops and unique paths.
  • lightweight cloning/branching (for recursive optimization and shove springback).

Definition at line 155 of file pns_node.h.

Member Typedef Documentation

◆ ITEM_VECTOR

typedef std::vector<ITEM*> PNS::NODE::ITEM_VECTOR

Definition at line 167 of file pns_node.h.

◆ JOINT_MAP

typedef std::unordered_multimap<JOINT::HASH_TAG, JOINT, JOINT::JOINT_TAG_HASH> PNS::NODE::JOINT_MAP
private

Definition at line 479 of file pns_node.h.

◆ OBSTACLES

typedef std::vector<OBSTACLE> PNS::NODE::OBSTACLES

Definition at line 168 of file pns_node.h.

◆ OPT_OBSTACLE

typedef std::optional<OBSTACLE> PNS::NODE::OPT_OBSTACLE

Definition at line 166 of file pns_node.h.

◆ TagJointPair

typedef JOINT_MAP::value_type PNS::NODE::TagJointPair
private

Definition at line 480 of file pns_node.h.

Member Enumeration Documentation

◆ COLLISION_QUERY_SCOPE

< Supported item types

Enumerator
CQS_ALL_RULES 

check all rules

CQS_IGNORE_HOLE_CLEARANCE 

check everything except hole2hole / hole2copper

Definition at line 160 of file pns_node.h.

161 {
162 CQS_ALL_RULES = 1,
164 };
@ CQS_IGNORE_HOLE_CLEARANCE
check everything except hole2hole / hole2copper
Definition: pns_node.h:163
@ CQS_ALL_RULES
check all rules
Definition: pns_node.h:162

Constructor & Destructor Documentation

◆ NODE() [1/2]

PNS::NODE::NODE ( )

Definition at line 54 of file pns_node.cpp.

55{
56 m_depth = 0;
57 m_root = this;
58 m_parent = nullptr;
59 m_maxClearance = 800000; // fixme: depends on how thick traces are.
60 m_ruleResolver = nullptr;
61 m_index = new INDEX;
63
64#ifdef DEBUG
65 allocNodes.insert( this );
66#endif
67}
NODE * m_root
root node of the whole hierarchy
Definition: pns_node.h:486
COLLISION_QUERY_SCOPE m_collisionQueryScope
Definition: pns_node.h:502
INDEX * m_index
Geometric/Net index of the items.
Definition: pns_node.h:494
int m_maxClearance
worst case item-item clearance
Definition: pns_node.h:492
int m_depth
depth of the node (number of parent nodes in the inheritance chain)
Definition: pns_node.h:495
NODE * m_parent
node this node was branched from
Definition: pns_node.h:485
RULE_RESOLVER * m_ruleResolver
Design rules resolver.
Definition: pns_node.h:493

References CQS_ALL_RULES, m_collisionQueryScope, m_depth, m_index, m_maxClearance, m_parent, m_root, and m_ruleResolver.

Referenced by Branch().

◆ ~NODE()

PNS::NODE::~NODE ( )

Return the expected clearance between items a and b.

Definition at line 70 of file pns_node.cpp.

71{
72 if( !m_children.empty() )
73 {
74 wxLogTrace( wxT( "PNS" ), wxT( "attempting to free a node that has kids." ) );
75 assert( false );
76 }
77
78#ifdef DEBUG
79 if( allocNodes.find( this ) == allocNodes.end() )
80 {
81 wxLogTrace( wxT( "PNS" ), wxT( "attempting to free an already-free'd node." ) );
82 assert( false );
83 }
84
85 allocNodes.erase( this );
86#endif
87
88 m_joints.clear();
89
90 for( ITEM* item : *m_index )
91 {
92 if( item->BelongsTo( this ) )
93 delete item;
94 }
95
98
99 delete m_index;
100}
void releaseGarbage()
Definition: pns_node.cpp:1424
std::set< NODE * > m_children
list of nodes branched from this one
Definition: pns_node.h:487
JOINT_MAP m_joints
hash table with the joints, linking the items.
Definition: pns_node.h:482
void unlinkParent()
Definition: pns_node.cpp:176

References m_children, m_index, m_joints, releaseGarbage(), and unlinkParent().

◆ NODE() [2/2]

PNS::NODE::NODE ( const NODE aB)
private

nodes are not copyable

Member Function Documentation

◆ Add() [1/6]

void PNS::NODE::Add ( LINE aLine,
bool  aAllowRedundant = false 
)

Definition at line 603 of file pns_node.cpp.

604{
605 assert( !aLine.IsLinked() );
606
607 SHAPE_LINE_CHAIN& l = aLine.Line();
608
609 for( size_t i = 0; i < l.ArcCount(); i++ )
610 {
611 auto s = l.Arc( i );
612 ARC* rarc;
613
614 if( !aAllowRedundant && ( rarc = findRedundantArc( s.GetP0(), s.GetP1(), aLine.Layers(),
615 aLine.Net() ) ) )
616 {
617 aLine.Link( rarc );
618 }
619 else
620 {
621 auto newarc = std::make_unique< ARC >( aLine, s );
622 aLine.Link( newarc.get() );
623 Add( std::move( newarc ), true );
624 }
625 }
626
627 for( int i = 0; i < l.SegmentCount(); i++ )
628 {
629 if( l.IsArcSegment( i ) )
630 continue;
631
632 SEG s = l.CSegment( i );
633
634 if( s.A != s.B )
635 {
636 SEGMENT* rseg;
637
638 if( !aAllowRedundant && ( rseg = findRedundantSegment( s.A, s.B, aLine.Layers(),
639 aLine.Net() ) ) )
640 {
641 // another line could be referencing this segment too :(
642 aLine.Link( rseg );
643 }
644 else
645 {
646 std::unique_ptr<SEGMENT> newseg = std::make_unique<SEGMENT>( aLine, s );
647 aLine.Link( newseg.get() );
648 Add( std::move( newseg ), true );
649 }
650 }
651 }
652}
bool Add(std::unique_ptr< SEGMENT > aSegment, bool aAllowRedundant=false)
Add an item to the current node.
Definition: pns_node.cpp:664
ARC * findRedundantArc(const VECTOR2I &A, const VECTOR2I &B, const LAYER_RANGE &lr, int aNet)
Definition: pns_node.cpp:1554
SEGMENT * findRedundantSegment(const VECTOR2I &A, const VECTOR2I &B, const LAYER_RANGE &lr, int aNet)
Definition: pns_node.cpp:1519
Definition: seg.h:42
VECTOR2I A
Definition: seg.h:49
VECTOR2I B
Definition: seg.h:50
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
const SHAPE_ARC & Arc(size_t aArc) const
int SegmentCount() const
Return the number of segments in this line chain.
size_t ArcCount() const
const SEG CSegment(int aIndex) const
Return a constant copy of the aIndex segment in the line chain.
bool IsArcSegment(size_t aSegment) const

References SEG::A, Add(), SHAPE_LINE_CHAIN::Arc(), SHAPE_LINE_CHAIN::ArcCount(), SEG::B, SHAPE_LINE_CHAIN::CSegment(), findRedundantArc(), findRedundantSegment(), SHAPE_LINE_CHAIN::IsArcSegment(), PNS::LINK_HOLDER::IsLinked(), PNS::ITEM::Layers(), PNS::LINE::Line(), PNS::LINK_HOLDER::Link(), PNS::ITEM::Net(), and SHAPE_LINE_CHAIN::SegmentCount().

◆ Add() [2/6]

bool PNS::NODE::Add ( std::unique_ptr< ARC aArc,
bool  aAllowRedundant = false 
)

Definition at line 692 of file pns_node.cpp.

693{
694 const SHAPE_ARC& arc = aArc->CArc();
695
696 if( !aAllowRedundant && findRedundantArc( arc.GetP0(), arc.GetP1(), aArc->Layers(),
697 aArc->Net() ) )
698 {
699 return false;
700 }
701
702 aArc->SetOwner( this );
703 addArc( aArc.release() );
704 return true;
705}
void addArc(ARC *aVia)
Definition: pns_node.cpp:683
const VECTOR2I & GetP1() const
Definition: shape_arc.h:113
const VECTOR2I & GetP0() const
Definition: shape_arc.h:112

References addArc(), findRedundantArc(), SHAPE_ARC::GetP0(), and SHAPE_ARC::GetP1().

◆ Add() [3/6]

void PNS::NODE::Add ( std::unique_ptr< ITEM aItem,
bool  aAllowRedundant = false 
)

Definition at line 708 of file pns_node.cpp.

709{
710 switch( aItem->Kind() )
711 {
712 case ITEM::SOLID_T: Add( ItemCast<SOLID>( std::move( aItem ) ) ); break;
713 case ITEM::SEGMENT_T: Add( ItemCast<SEGMENT>( std::move( aItem ) ), aAllowRedundant ); break;
714 case ITEM::VIA_T: Add( ItemCast<VIA>( std::move( aItem ) ) ); break;
715
716 case ITEM::ARC_T:
717 //todo(snh): Add redundant search
718 Add( ItemCast<ARC>( std::move( aItem ) ) );
719 break;
720
721 case ITEM::LINE_T:
722 default:
723 assert( false );
724 }
725}
@ SOLID_T
Definition: pns_item.h:63
@ LINE_T
Definition: pns_item.h:64
@ SEGMENT_T
Definition: pns_item.h:66

References Add(), PNS::ITEM::ARC_T, PNS::ITEM::LINE_T, PNS::ITEM::SEGMENT_T, PNS::ITEM::SOLID_T, and PNS::ITEM::VIA_T.

◆ Add() [4/6]

bool PNS::NODE::Add ( std::unique_ptr< SEGMENT aSegment,
bool  aAllowRedundant = false 
)

Add an item to the current node.

Parameters
aSegmentitem to add.
aAllowRedundantif true, duplicate items are allowed (e.g. a segment or via at the same coordinates as an existing one).
Returns
true if added

Definition at line 664 of file pns_node.cpp.

665{
666 if( aSegment->Seg().A == aSegment->Seg().B )
667 {
668 wxLogTrace( wxT( "PNS" ),
669 wxT( "attempting to add a segment with same end coordinates, ignoring." ) );
670 return false;
671 }
672
673 if( !aAllowRedundant && findRedundantSegment( aSegment.get() ) )
674 return false;
675
676 aSegment->SetOwner( this );
677 addSegment( aSegment.release() );
678
679 return true;
680}
void addSegment(SEGMENT *aSeg)
Definition: pns_node.cpp:655

References addSegment(), and findRedundantSegment().

Referenced by Add(), Commit(), PNS::COMPONENT_DRAGGER::Drag(), PNS::DRAGGER::dragMarkObstacles(), PNS::DRAGGER::dragShove(), PNS::DRAGGER::dragViaMarkObstacles(), PNS::DRAGGER::dragViaWalkaround(), PNS::DIFF_PAIR_PLACER::FixRoute(), PNS::LINE_PLACER::FixRoute(), PNS::DP_MEANDER_PLACER::FixRoute(), PNS::MEANDER_PLACER::FixRoute(), FixupVirtualVias(), PNS::DRAGGER::optimizeAndUpdateDraggedLine(), PNS::LINE_PLACER::removeLoops(), Replace(), PNS::SHOVE::ShoveLines(), PNS::SHOVE::ShoveMultiLines(), PNS::TOPOLOGY::SimplifyLine(), PNS::LINE_PLACER::simplifyNewLine(), PNS::LINE_PLACER::SplitAdjacentSegments(), PNS_KICAD_IFACE_BASE::syncGraphicalItem(), PNS_KICAD_IFACE_BASE::syncTextItem(), PNS_KICAD_IFACE_BASE::SyncWorld(), and PNS_KICAD_IFACE_BASE::syncZone().

◆ Add() [5/6]

void PNS::NODE::Add ( std::unique_ptr< SOLID aSolid)

Definition at line 581 of file pns_node.cpp.

582{
583 aSolid->SetOwner( this );
584 addSolid( aSolid.release() );
585}
void addSolid(SOLID *aSeg)
Definition: pns_node.cpp:572

References addSolid().

◆ Add() [6/6]

void PNS::NODE::Add ( std::unique_ptr< VIA aVia)

Definition at line 596 of file pns_node.cpp.

597{
598 aVia->SetOwner( this );
599 addVia( aVia.release() );
600}
void addVia(VIA *aVia)
Definition: pns_node.cpp:588

References addVia().

◆ addArc()

void PNS::NODE::addArc ( ARC aVia)
private

Definition at line 683 of file pns_node.cpp.

684{
685 linkJoint( aArc->Anchor( 0 ), aArc->Layers(), aArc->Net(), aArc );
686 linkJoint( aArc->Anchor( 1 ), aArc->Layers(), aArc->Net(), aArc );
687
688 m_index->Add( aArc );
689}
void Add(ITEM *aItem)
Adds item to the spatial index.
Definition: pns_index.cpp:28
void linkJoint(const VECTOR2I &aPos, const LAYER_RANGE &aLayers, int aNet, ITEM *aWhere)
Unlink an item from a joint.
Definition: pns_node.cpp:1288

References PNS::INDEX::Add(), PNS::ARC::Anchor(), PNS::ITEM::Layers(), linkJoint(), m_index, and PNS::ITEM::Net().

Referenced by Add().

◆ AddEdgeExclusion()

void PNS::NODE::AddEdgeExclusion ( std::unique_ptr< SHAPE aShape)

Definition at line 728 of file pns_node.cpp.

729{
730 m_edgeExclusions.push_back( std::move( aShape ) );
731}
std::vector< std::unique_ptr< SHAPE > > m_edgeExclusions
Definition: pns_node.h:498

References m_edgeExclusions.

Referenced by PNS_KICAD_IFACE_BASE::SyncWorld().

◆ addSegment()

void PNS::NODE::addSegment ( SEGMENT aSeg)
private

Definition at line 655 of file pns_node.cpp.

656{
657 linkJoint( aSeg->Seg().A, aSeg->Layers(), aSeg->Net(), aSeg );
658 linkJoint( aSeg->Seg().B, aSeg->Layers(), aSeg->Net(), aSeg );
659
660 m_index->Add( aSeg );
661}

References SEG::A, PNS::INDEX::Add(), SEG::B, PNS::ITEM::Layers(), linkJoint(), m_index, PNS::ITEM::Net(), and PNS::SEGMENT::Seg().

Referenced by Add().

◆ addSolid()

void PNS::NODE::addSolid ( SOLID aSeg)
private

Definition at line 572 of file pns_node.cpp.

573{
574 if( aSolid->IsRoutable() )
575 linkJoint( aSolid->Pos(), aSolid->Layers(), aSolid->Net(), aSolid );
576
577 m_index->Add( aSolid );
578}

References PNS::INDEX::Add(), PNS::ITEM::IsRoutable(), PNS::ITEM::Layers(), linkJoint(), m_index, PNS::ITEM::Net(), and PNS::SOLID::Pos().

Referenced by Add().

◆ addVia()

void PNS::NODE::addVia ( VIA aVia)
private

Definition at line 588 of file pns_node.cpp.

589{
590 linkJoint( aVia->Pos(), aVia->Layers(), aVia->Net(), aVia );
591
592 m_index->Add( aVia );
593}

References PNS::INDEX::Add(), PNS::ITEM::Layers(), linkJoint(), m_index, PNS::ITEM::Net(), and PNS::VIA::Pos().

Referenced by Add().

◆ AllItemsInNet()

void PNS::NODE::AllItemsInNet ( int  aNet,
std::set< ITEM * > &  aItems,
int  aKindMask = -1 
)

Definition at line 1465 of file pns_node.cpp.

1466{
1468
1469 if( l_cur )
1470 {
1471 for( ITEM* item : *l_cur )
1472 {
1473 if( item->OfKind( aKindMask ) && item->IsRoutable() )
1474 aItems.insert( item );
1475 }
1476 }
1477
1478 if( !isRoot() )
1479 {
1481
1482 if( l_root )
1483 {
1484 for( ITEM* item : *l_root )
1485 {
1486 if( !Overrides( item ) && item->OfKind( aKindMask ) && item->IsRoutable() )
1487 aItems.insert( item );
1488 }
1489 }
1490 }
1491}
std::list< ITEM * > NET_ITEMS_LIST
Definition: pns_index.h:48
NET_ITEMS_LIST * GetItemsForNet(int aNet)
Returns list of all items in a given net.
Definition: pns_index.cpp:71
bool Overrides(ITEM *aItem) const
Definition: pns_node.h:409
bool isRoot() const
Definition: pns_node.h:460

References PNS::INDEX::GetItemsForNet(), isRoot(), m_index, m_root, and Overrides().

Referenced by PNS::TOPOLOGY::AssembleDiffPair(), PNS::DIFF_PAIR_PLACER::FindDpPrimitivePair(), and PNS::TOPOLOGY::NearestUnconnectedItem().

◆ AssembleLine()

const LINE PNS::NODE::AssembleLine ( LINKED_ITEM aSeg,
int *  aOriginSegmentIndex = nullptr,
bool  aStopAtLockedJoints = false,
bool  aFollowLockedSegments = false 
)

Follow the joint map to assemble a line connecting two non-trivial joints starting from segment aSeg.

Parameters
aSegthe initial segment.
aOriginSegmentIndexindex of aSeg in the resulting line.
aStopAtLockedJointswill terminate the line at the first locked joint encountered
aFollowLockedSegmentswill consider a joint between a locked segment and an unlocked segment of the same width as a trivial joint.
Returns
the line Print the contents and joints structure.

Definition at line 991 of file pns_node.cpp.

993{
994 const int MaxVerts = 1024 * 16;
995
996 std::array<VECTOR2I, MaxVerts + 1> corners;
997 std::array<LINKED_ITEM*, MaxVerts + 1> segs;
998 std::array<bool, MaxVerts + 1> arcReversed;
999
1000 LINE pl;
1001 bool guardHit = false;
1002
1003 int i_start = MaxVerts / 2;
1004 int i_end = i_start + 1;
1005
1006 pl.SetWidth( aSeg->Width() );
1007 pl.SetLayers( aSeg->Layers() );
1008 pl.SetNet( aSeg->Net() );
1009 pl.SetOwner( this );
1010
1011 followLine( aSeg, false, i_start, MaxVerts, corners.data(), segs.data(), arcReversed.data(),
1012 guardHit, aStopAtLockedJoints, aFollowLockedSegments );
1013
1014 if( !guardHit )
1015 {
1016 followLine( aSeg, true, i_end, MaxVerts, corners.data(), segs.data(), arcReversed.data(),
1017 guardHit, aStopAtLockedJoints, aFollowLockedSegments );
1018 }
1019
1020 int n = 0;
1021
1022 LINKED_ITEM* prev_seg = nullptr;
1023 bool originSet = false;
1024
1025 SHAPE_LINE_CHAIN& line = pl.Line();
1026
1027 for( int i = i_start + 1; i < i_end; i++ )
1028 {
1029 const VECTOR2I& p = corners[i];
1030 LINKED_ITEM* li = segs[i];
1031
1032 if( !li || li->Kind() != ITEM::ARC_T )
1033 line.Append( p );
1034
1035 if( li && prev_seg != li )
1036 {
1037 if( li->Kind() == ITEM::ARC_T )
1038 {
1039 const ARC* arc = static_cast<const ARC*>( li );
1040 const SHAPE_ARC* sa = static_cast<const SHAPE_ARC*>( arc->Shape() );
1041
1042 int nSegs = line.PointCount();
1043 VECTOR2I last = nSegs ? line.CPoint( -1 ) : VECTOR2I();
1044 ssize_t lastShape = nSegs ? line.ArcIndex( static_cast<ssize_t>( nSegs ) - 1 ) : -1;
1045
1046 line.Append( arcReversed[i] ? sa->Reversed() : *sa );
1047 }
1048
1049 pl.Link( li );
1050
1051 // latter condition to avoid loops
1052 if( li == aSeg && aOriginSegmentIndex && !originSet )
1053 {
1054 wxASSERT( n < line.SegmentCount() ||
1055 ( n == line.SegmentCount() && li->Kind() == ITEM::SEGMENT_T ) );
1056 *aOriginSegmentIndex = line.PointCount() - 1;
1057 originSet = true;
1058 }
1059 }
1060
1061 prev_seg = li;
1062 }
1063
1064 // Remove duplicate verts, but do NOT remove colinear segments here!
1065 pl.Line().Simplify( false );
1066
1067 // TODO: maintain actual segment index under simplifcation system
1068 if( aOriginSegmentIndex && *aOriginSegmentIndex >= pl.SegmentCount() )
1069 *aOriginSegmentIndex = pl.SegmentCount() - 1;
1070
1071 assert( pl.SegmentCount() != 0 );
1072
1073 return pl;
1074}
void followLine(LINKED_ITEM *aCurrent, bool aScanDirection, int &aPos, int aLimit, VECTOR2I *aCorners, LINKED_ITEM **aSegments, bool *aArcReversed, bool &aGuardHit, bool aStopAtLockedJoints, bool aFollowLockedSegments)
Definition: pns_node.cpp:942
SHAPE_ARC Reversed() const
Definition: shape_arc.cpp:581
int PointCount() const
Return the number of points (vertices) in this line chain.
ssize_t ArcIndex(size_t aSegment) const
Return the arc index for the given segment index.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
VECTOR2< int > VECTOR2I
Definition: vector2d.h:618

References SHAPE_LINE_CHAIN::Append(), PNS::ITEM::ARC_T, SHAPE_LINE_CHAIN::ArcIndex(), SHAPE_LINE_CHAIN::CPoint(), followLine(), PNS::ITEM::Kind(), PNS::ITEM::Layers(), PNS::LINE::Line(), PNS::LINK_HOLDER::Link(), PNS::ITEM::Net(), SHAPE_LINE_CHAIN::PointCount(), SHAPE_ARC::Reversed(), PNS::ITEM::SEGMENT_T, SHAPE_LINE_CHAIN::SegmentCount(), PNS::LINE::SegmentCount(), PNS::ITEM::SetLayers(), PNS::ITEM::SetNet(), PNS::ITEM::SetOwner(), PNS::LINE::SetWidth(), PNS::ARC::Shape(), SHAPE_LINE_CHAIN::Simplify(), and PNS::LINKED_ITEM::Width().

Referenced by PNS::TOPOLOGY::AssembleDiffPair(), PNS::SHOVE::assembleLine(), PNS::TOPOLOGY::AssembleTrivialPath(), Dump(), FindLinesBetweenJoints(), PNS::DRAGGER::findViaFanoutByHandle(), PNS::TOPOLOGY::followTrivialPath(), PNS::LINE_PLACER::removeLoops(), PNS::TOPOLOGY::SimplifyLine(), PNS::LINE_PLACER::simplifyNewLine(), PNS::MEANDER_PLACER::Start(), PNS::MEANDER_SKEW_PLACER::Start(), PNS::COMPONENT_DRAGGER::Start(), PNS::DRAGGER::startDragArc(), and PNS::DRAGGER::startDragSegment().

◆ Branch()

NODE * PNS::NODE::Branch ( )

Create a lightweight copy (called branch) of self that tracks the changes (added/removed items) wrs to the root.

Note
If there are any branches in use, their parents must not be deleted.
Returns
the new branch.

Definition at line 139 of file pns_node.cpp.

140{
141 NODE* child = new NODE;
142
143 m_children.insert( child );
144
145 child->m_depth = m_depth + 1;
146 child->m_parent = this;
147 child->m_ruleResolver = m_ruleResolver;
148 child->m_root = isRoot() ? this : m_root;
150 child->m_collisionQueryScope = m_collisionQueryScope;
151
152 // Immediate offspring of the root branch needs not copy anything. For the rest, deep-copy
153 // joints, overridden item maps and pointers to stored items.
154 if( !isRoot() )
155 {
156 JOINT_MAP::iterator j;
157
158 for( ITEM* item : *m_index )
159 child->m_index->Add( item );
160
161 child->m_joints = m_joints;
162 child->m_override = m_override;
163 }
164
165#if 0
166 wxLogTrace( wxT( "PNS" ), wxT( "%d items, %d joints, %d overrides" ),
167 child->m_index->Size(),
168 (int) child->m_joints.size(),
169 (int) child->m_override.size() );
170#endif
171
172 return child;
173}
std::unordered_set< ITEM * > m_override
hash of root's items that have been changed in this node
Definition: pns_node.h:489

References PNS::INDEX::Add(), isRoot(), m_children, m_collisionQueryScope, m_depth, m_index, m_joints, m_maxClearance, m_override, m_parent, m_root, m_ruleResolver, NODE(), and PNS::INDEX::Size().

Referenced by PNS::MEANDER_PLACER::doMove(), PNS::COMPONENT_DRAGGER::Drag(), PNS::DRAGGER::dragMarkObstacles(), PNS::DRAGGER::dragWalkaround(), PNS::LINE_PLACER::FixRoute(), PNS::ROUTER::GetUpdatedItems(), PNS::DIFF_PAIR_PLACER::initPlacement(), PNS::LINE_PLACER::initPlacement(), PNS::DIFF_PAIR_PLACER::Move(), PNS::DP_MEANDER_PLACER::Move(), PNS::LINE_PLACER::Move(), PNS::TOPOLOGY::NearestUnconnectedAnchorPoint(), PNS::SHOVE::SetInitialLine(), PNS::SHOVE::ShoveDraggingVia(), PNS::SHOVE::ShoveLines(), PNS::SHOVE::ShoveMultiLines(), PNS::DP_MEANDER_PLACER::Start(), PNS::MEANDER_PLACER::Start(), PNS::MEANDER_SKEW_PLACER::Start(), PNS::DIFF_PAIR_PLACER::tryWalkDp(), and PNS::LINE_PLACER::UnfixRoute().

◆ CheckColliding() [1/2]

NODE::OPT_OBSTACLE PNS::NODE::CheckColliding ( const ITEM aItem,
int  aKindMask = ITEM::ANY_T 
)

Check if the item collides with anything else in the world, and if found, returns the obstacle.

Parameters
aItemthe item to find collisions with
aKindMaskmask of obstacle types to take into account
Returns
the obstacle, if found, otherwise empty.

Definition at line 472 of file pns_node.cpp.

473{
474 OBSTACLES obs;
475
476 obs.reserve( 100 );
477
478 if( aItemA->Kind() == ITEM::LINE_T )
479 {
480 int n = 0;
481 const LINE* line = static_cast<const LINE*>( aItemA );
482 const SHAPE_LINE_CHAIN& l = line->CLine();
483
484 for( int i = 0; i < l.SegmentCount(); i++ )
485 {
486 // Note: Clearances between &s and other items are cached,
487 // which means they'll be the same for all segments in the line.
488 // Disabling the cache will lead to slowness.
489
490 const SEGMENT s( *line, l.CSegment( i ) );
491 n += QueryColliding( &s, obs, aKindMask, 1 );
492
493 if( n )
494 return OPT_OBSTACLE( obs[0] );
495 }
496
497 if( line->EndsWithVia() )
498 {
499 n += QueryColliding( &line->Via(), obs, aKindMask, 1 );
500
501 if( n )
502 return OPT_OBSTACLE( obs[0] );
503 }
504 }
505 else if( QueryColliding( aItemA, obs, aKindMask, 1 ) > 0 )
506 {
507 return OPT_OBSTACLE( obs[0] );
508 }
509
510 return OPT_OBSTACLE();
511}
int QueryColliding(const ITEM *aItem, OBSTACLES &aObstacles, int aKindMask=ITEM::ANY_T, int aLimitCount=-1, bool aDifferentNetsOnly=true, int aOverrideClearance=-1)
Find items colliding (closer than clearance) with the item aItem.
Definition: pns_node.cpp:271
std::optional< OBSTACLE > OPT_OBSTACLE
Definition: pns_node.h:166
std::vector< OBSTACLE > OBSTACLES
Definition: pns_node.h:168

References PNS::LINE::CLine(), SHAPE_LINE_CHAIN::CSegment(), PNS::LINE::EndsWithVia(), PNS::ITEM::Kind(), PNS::ITEM::LINE_T, QueryColliding(), SHAPE_LINE_CHAIN::SegmentCount(), and PNS::LINE::Via().

Referenced by PNS::DIFF_PAIR_PLACER::attemptWalk(), CheckColliding(), PNS::OPTIMIZER::checkColliding(), PNS::checkDpColliding(), PNS::DP_MEANDER_PLACER::CheckFit(), PNS::MEANDER_PLACER::CheckFit(), PNS::LINE_PLACER::clipAndCheckCollisions(), PNS::DRAGGER::dragMarkObstacles(), PNS::DRAGGER::dragViaWalkaround(), PNS::DRAGGER::dragWalkaround(), PNS::OPTIMIZER::fanoutCleanup(), PNS::COMPONENT_DRAGGER::FixRoute(), PNS::LINE_PLACER::FixRoute(), PNS::DIFF_PAIR_PLACER::propagateDpHeadForces(), PNS::VIA::PushoutForce(), PNS::SHOVE::reduceSpringback(), PNS::LINE_PLACER::reduceTail(), PNS::DIFF_PAIR_PLACER::rhMarkObstacles(), PNS::DIFF_PAIR_PLACER::rhShoveOnly(), PNS::LINE_PLACER::rhWalkOnly(), PNS::WALKAROUND::Route(), PNS::SHOVE::ShoveLines(), PNS::tightenSegment(), and PNS::verifyDpBypass().

◆ CheckColliding() [2/2]

NODE::OPT_OBSTACLE PNS::NODE::CheckColliding ( const ITEM_SET aSet,
int  aKindMask = ITEM::ANY_T 
)

Check if any item in the set collides with anything else in the world, and if found, returns the obstacle.

Parameters
aSetset of items to find collisions with.
aKindMaskmask of obstacle types to take into account.
Returns
the obstacle, if found, otherwise empty.

Definition at line 458 of file pns_node.cpp.

459{
460 for( const ITEM* item : aSet.CItems() )
461 {
462 OPT_OBSTACLE obs = CheckColliding( item, aKindMask );
463
464 if( obs )
465 return obs;
466 }
467
468 return OPT_OBSTACLE();
469}
OPT_OBSTACLE CheckColliding(const ITEM *aItem, int aKindMask=ITEM::ANY_T)
Check if the item collides with anything else in the world, and if found, returns the obstacle.
Definition: pns_node.cpp:472

References CheckColliding(), and PNS::ITEM_SET::CItems().

◆ ClearRanks()

void PNS::NODE::ClearRanks ( int  aMarkerMask = MK_HEAD | MK_VIOLATION | MK_HOLE)

Definition at line 1494 of file pns_node.cpp.

1495{
1496 for( ITEM* item : *m_index )
1497 {
1498 item->SetRank( -1 );
1499 item->Mark( item->Marker() & ~aMarkerMask );
1500 }
1501}

References m_index.

Referenced by PNS::SHOVE::ShoveDraggingVia(), PNS::SHOVE::ShoveLines(), and PNS::SHOVE::ShoveMultiLines().

◆ Commit()

void PNS::NODE::Commit ( NODE aNode)

Apply the changes from a given branch (aNode) to the root branch.

Calling on a non-root branch will fail. Calling commit also kills all children nodes of the root branch.

Parameters
aNodenode to commit changes from.

Definition at line 1439 of file pns_node.cpp.

1440{
1441 if( aNode->isRoot() )
1442 return;
1443
1444 for( ITEM* item : aNode->m_override )
1445 Remove( item );
1446
1447 for( ITEM* item : *aNode->m_index )
1448 {
1449 item->SetRank( -1 );
1450 item->Unmark();
1451 Add( std::unique_ptr<ITEM>( item ) );
1452 }
1453
1456}
void releaseChildren()
Definition: pns_node.cpp:1411
void Remove(ARC *aArc)
Remove an item from this branch.
Definition: pns_node.cpp:881

References Add(), isRoot(), m_index, m_override, releaseChildren(), releaseGarbage(), Remove(), PNS::ITEM::SetRank(), and PNS::ITEM::Unmark().

◆ Depth()

int PNS::NODE::Depth ( ) const
inline

Definition at line 209 of file pns_node.h.

210 {
211 return m_depth;
212 }

References m_depth.

Referenced by PNS::LINE_PLACER::Move().

◆ doRemove()

void PNS::NODE::doRemove ( ITEM aItem)
private

Definition at line 746 of file pns_node.cpp.

747{
748 // case 1: removing an item that is stored in the root node from any branch:
749 // mark it as overridden, but do not remove
750 if( aItem->BelongsTo( m_root ) && !isRoot() )
751 m_override.insert( aItem );
752
753 // case 2: the item belongs to this branch or a parent, non-root branch,
754 // or the root itself and we are the root: remove from the index
755 else if( !aItem->BelongsTo( m_root ) || isRoot() )
756 m_index->Remove( aItem );
757
758 // the item belongs to this particular branch: un-reference it
759 if( aItem->BelongsTo( this ) )
760 {
761 aItem->SetOwner( nullptr );
762 m_root->m_garbageItems.insert( aItem );
763 }
764}
void Remove(ITEM *aItem)
Removes an item from the spatial index.
Definition: pns_index.cpp:46
std::unordered_set< ITEM * > m_garbageItems
Definition: pns_node.h:500

References PNS::ITEM::BelongsTo(), isRoot(), m_garbageItems, m_index, m_override, m_root, PNS::INDEX::Remove(), and PNS::ITEM::SetOwner().

Referenced by Remove().

◆ Dump()

void PNS::NODE::Dump ( bool  aLong = false)

Definition at line 1305 of file pns_node.cpp.

1306{
1307#if 0
1308 std::unordered_set<SEGMENT*> all_segs;
1310
1311 for( i = m_items.begin(); i != m_items.end(); i++ )
1312 {
1313 if( (*i)->GetKind() == ITEM::SEGMENT_T )
1314 all_segs.insert( static_cast<SEGMENT*>( *i ) );
1315 }
1316
1317 if( !isRoot() )
1318 {
1319 for( i = m_root->m_items.begin(); i != m_root->m_items.end(); i++ )
1320 {
1321 if( (*i)->GetKind() == ITEM::SEGMENT_T && !overrides( *i ) )
1322 all_segs.insert( static_cast<SEGMENT*>(*i) );
1323 }
1324 }
1325
1326 JOINT_MAP::iterator j;
1327
1328 if( aLong )
1329 {
1330 for( j = m_joints.begin(); j != m_joints.end(); ++j )
1331 {
1332 wxLogTrace( wxT( "PNS" ), wxT( "joint : %s, links : %d\n" ),
1333 j->second.GetPos().Format().c_str(), j->second.LinkCount() );
1334 JOINT::LINKED_ITEMS::const_iterator k;
1335
1336 for( k = j->second.GetLinkList().begin(); k != j->second.GetLinkList().end(); ++k )
1337 {
1338 const ITEM* m_item = *k;
1339
1340 switch( m_item->GetKind() )
1341 {
1342 case ITEM::SEGMENT_T:
1343 {
1344 const SEGMENT* seg = static_cast<const SEGMENT*>( m_item );
1345 wxLogTrace( wxT( "PNS" ), wxT( " -> seg %s %s\n" ),
1346 seg->GetSeg().A.Format().c_str(),
1347 seg->GetSeg().B.Format().c_str() );
1348 break;
1349 }
1350
1351 default:
1352 break;
1353 }
1354 }
1355 }
1356 }
1357
1358 int lines_count = 0;
1359
1360 while( !all_segs.empty() )
1361 {
1362 SEGMENT* s = *all_segs.begin();
1363 LINE* l = AssembleLine( s );
1364
1365 LINE::LinkedSegments* seg_refs = l->GetLinkedSegments();
1366
1367 if( aLong )
1368 {
1369 wxLogTrace( wxT( "PNS" ), wxT( "Line: %s, net %d " ),
1370 l->GetLine().Format().c_str(), l->GetNet() );
1371 }
1372
1373 for( std::vector<SEGMENT*>::iterator j = seg_refs->begin(); j != seg_refs->end(); ++j )
1374 {
1375 wxLogTrace( wxT( "PNS" ), wxT( "%s " ), (*j)->GetSeg().A.Format().c_str() );
1376
1377 if( j + 1 == seg_refs->end() )
1378 wxLogTrace( wxT( "PNS" ), wxT( "%s\n" ), (*j)->GetSeg().B.Format().c_str() );
1379
1380 all_segs.erase( *j );
1381 }
1382
1383 lines_count++;
1384 }
1385
1386 wxLogTrace( wxT( "PNS" ), wxT( "Local joints: %d, lines : %d \n" ),
1387 m_joints.size(), lines_count );
1388#endif
1389}
const LINE AssembleLine(LINKED_ITEM *aSeg, int *aOriginSegmentIndex=nullptr, bool aStopAtLockedJoints=false, bool aFollowLockedSegments=false)
Follow the joint map to assemble a line connecting two non-trivial joints starting from segment aSeg.
Definition: pns_node.cpp:991

References AssembleLine(), PNS::ITEM::Format(), PNS::SEGMENT::Format(), isRoot(), m_joints, m_root, and PNS::ITEM::SEGMENT_T.

◆ FindItemByParent()

ITEM * PNS::NODE::FindItemByParent ( const BOARD_ITEM aParent)

Definition at line 1627 of file pns_node.cpp.

1628{
1629 if( aParent->IsConnected() )
1630 {
1631 const BOARD_CONNECTED_ITEM* cItem = static_cast<const BOARD_CONNECTED_ITEM*>( aParent );
1632
1634
1635 if( l_cur )
1636 {
1637 for( ITEM* item : *l_cur )
1638 {
1639 if( item->Parent() == aParent )
1640 return item;
1641 }
1642 }
1643 }
1644
1645 return nullptr;
1646}
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
virtual bool IsConnected() const
Returns information if the object is derived from BOARD_CONNECTED_ITEM.
Definition: board_item.h:115

References PNS::INDEX::GetItemsForNet(), BOARD_CONNECTED_ITEM::GetNetCode(), BOARD_ITEM::IsConnected(), and m_index.

Referenced by ROUTER_TOOL::InlineBreakTrack(), ROUTER_TOOL::InlineDrag(), and ROUTER_TOOL::RouteSelected().

◆ FindJoint() [1/2]

JOINT * PNS::NODE::FindJoint ( const VECTOR2I aPos,
const ITEM aItem 
)
inline

Search for a joint at a given position, linked to given item.

Returns
the joint, if found, otherwise empty. Find all lines between a pair of joints. Used by the loop removal procedure.

Definition at line 376 of file pns_node.h.

References FindJoint(), PNS::ITEM::Layers(), PNS::ITEM::Net(), and LAYER_RANGE::Start().

◆ FindJoint() [2/2]

JOINT * PNS::NODE::FindJoint ( const VECTOR2I aPos,
int  aLayer,
int  aNet 
)

Search for a joint at a given position, layer and belonging to given net.

Returns
the joint, if found, otherwise empty.

Definition at line 1189 of file pns_node.cpp.

1190{
1191 JOINT::HASH_TAG tag;
1192
1193 tag.net = aNet;
1194 tag.pos = aPos;
1195
1196 JOINT_MAP::iterator f = m_joints.find( tag ), end = m_joints.end();
1197
1198 if( f == end && !isRoot() )
1199 {
1200 end = m_root->m_joints.end();
1201 f = m_root->m_joints.find( tag ); // m_root->FindJoint(aPos, aLayer, aNet);
1202 }
1203
1204 if( f == end )
1205 return nullptr;
1206
1207 while( f != end )
1208 {
1209 if( f->second.Layers().Overlaps( aLayer ) )
1210 return &f->second;
1211
1212 ++f;
1213 }
1214
1215 return nullptr;
1216}

References isRoot(), m_joints, m_root, PNS::JOINT::HASH_TAG::net, and PNS::JOINT::HASH_TAG::pos.

Referenced by PNS::TOPOLOGY::AssembleTrivialPath(), PNS::DRAGGER::checkVirtualVia(), PNS::TOPOLOGY::ConnectedJoints(), FindJoint(), FindLineEnds(), PNS::OPTIMIZER::findPadOrVia(), findRedundantArc(), findRedundantSegment(), PNS::findViaByHandle(), PNS::DRAGGER::findViaFanoutByHandle(), PNS::SHOVE::fixupViaCollisions(), followLine(), PNS::TOPOLOGY::followTrivialPath(), PNS::getDanglingAnchor(), PNS::ROUTER::getNearestRatnestAnchor(), PNS::SHOVE::onCollidingSolid(), PNS::SHOVE::onReverseCollidingVia(), PNS::SHOVE::pushOrShoveVia(), removeSolidIndex(), removeViaIndex(), PNS::SHOVE::shoveLineToHullSet(), PNS::LINE_PLACER::simplifyNewLine(), PNS::LINE_PLACER::SplitAdjacentSegments(), and PNS::COMPONENT_DRAGGER::Start().

◆ FindLineEnds()

void PNS::NODE::FindLineEnds ( const LINE aLine,
JOINT aA,
JOINT aB 
)

Destroy all child nodes. Applicable only to the root node.

Definition at line 1077 of file pns_node.cpp.

1078{
1079 aA = *FindJoint( aLine.CPoint( 0 ), &aLine );
1080 aB = *FindJoint( aLine.CPoint( -1 ), &aLine );
1081}
JOINT * FindJoint(const VECTOR2I &aPos, int aLayer, int aNet)
Search for a joint at a given position, layer and belonging to given net.
Definition: pns_node.cpp:1189

References PNS::LINE::CPoint(), and FindJoint().

Referenced by FindLinesBetweenJoints(), PNS::MEANDER_PLACER_BASE::GetTotalPadToDieLength(), and PNS::LINE_PLACER::removeLoops().

◆ FindLinesBetweenJoints()

int PNS::NODE::FindLinesBetweenJoints ( const JOINT aA,
const JOINT aB,
std::vector< LINE > &  aLines 
)

Find the joints corresponding to the ends of line aLine.

Definition at line 1084 of file pns_node.cpp.

1085{
1086 for( ITEM* item : aA.LinkList() )
1087 {
1088 if( item->Kind() == ITEM::SEGMENT_T || item->Kind() == ITEM::ARC_T )
1089 {
1090 LINKED_ITEM* li = static_cast<LINKED_ITEM*>( item );
1091 LINE line = AssembleLine( li );
1092
1093 if( !line.Layers().Overlaps( aB.Layers() ) )
1094 continue;
1095
1096 JOINT j_start, j_end;
1097
1098 FindLineEnds( line, j_start, j_end );
1099
1100 int id_start = line.CLine().Find( aA.Pos() );
1101 int id_end = line.CLine().Find( aB.Pos() );
1102
1103 if( id_end < id_start )
1104 std::swap( id_end, id_start );
1105
1106 if( id_start >= 0 && id_end >= 0 )
1107 {
1108 line.ClipVertexRange( id_start, id_end );
1109 aLines.push_back( line );
1110 }
1111 }
1112 }
1113
1114 return 0;
1115}
void FindLineEnds(const LINE &aLine, JOINT &aA, JOINT &aB)
Destroy all child nodes. Applicable only to the root node.
Definition: pns_node.cpp:1077

References PNS::ITEM::ARC_T, AssembleLine(), PNS::LINE::CLine(), PNS::LINE::ClipVertexRange(), SHAPE_LINE_CHAIN::Find(), FindLineEnds(), PNS::ITEM::Layers(), PNS::JOINT::LinkList(), LAYER_RANGE::Overlaps(), PNS::JOINT::Pos(), and PNS::ITEM::SEGMENT_T.

Referenced by PNS::LINE_PLACER::removeLoops().

◆ findRedundantArc() [1/2]

ARC * PNS::NODE::findRedundantArc ( ARC aSeg)
private

Scan the joint map, forming a line starting from segment (current).

Definition at line 1583 of file pns_node.cpp.

1584{
1585 return findRedundantArc( aArc->Anchor( 0 ), aArc->Anchor( 1 ), aArc->Layers(), aArc->Net() );
1586}

References PNS::ARC::Anchor(), findRedundantArc(), PNS::ITEM::Layers(), and PNS::ITEM::Net().

◆ findRedundantArc() [2/2]

ARC * PNS::NODE::findRedundantArc ( const VECTOR2I A,
const VECTOR2I B,
const LAYER_RANGE lr,
int  aNet 
)
private

Definition at line 1554 of file pns_node.cpp.

1556{
1557 JOINT* jtStart = FindJoint( A, lr.Start(), aNet );
1558
1559 if( !jtStart )
1560 return nullptr;
1561
1562 for( ITEM* item : jtStart->LinkList() )
1563 {
1564 if( item->OfKind( ITEM::ARC_T ) )
1565 {
1566 ARC* seg2 = static_cast<ARC*>( item );
1567
1568 const VECTOR2I a2( seg2->Anchor( 0 ) );
1569 const VECTOR2I b2( seg2->Anchor( 1 ) );
1570
1571 if( seg2->Layers().Start() == lr.Start()
1572 && ( ( A == a2 && B == b2 ) || ( A == b2 && B == a2 ) ) )
1573 {
1574 return seg2;
1575 }
1576 }
1577 }
1578
1579 return nullptr;
1580}
int Start() const
Definition: pns_layerset.h:82

References PNS::ARC::Anchor(), PNS::ITEM::ARC_T, FindJoint(), PNS::ITEM::Layers(), PNS::JOINT::LinkList(), and LAYER_RANGE::Start().

Referenced by Add(), and findRedundantArc().

◆ findRedundantSegment() [1/2]

SEGMENT * PNS::NODE::findRedundantSegment ( const VECTOR2I A,
const VECTOR2I B,
const LAYER_RANGE lr,
int  aNet 
)
private

Definition at line 1519 of file pns_node.cpp.

1521{
1522 JOINT* jtStart = FindJoint( A, lr.Start(), aNet );
1523
1524 if( !jtStart )
1525 return nullptr;
1526
1527 for( ITEM* item : jtStart->LinkList() )
1528 {
1529 if( item->OfKind( ITEM::SEGMENT_T ) )
1530 {
1531 SEGMENT* seg2 = (SEGMENT*)item;
1532
1533 const VECTOR2I a2( seg2->Seg().A );
1534 const VECTOR2I b2( seg2->Seg().B );
1535
1536 if( seg2->Layers().Start() == lr.Start()
1537 && ( ( A == a2 && B == b2 ) || ( A == b2 && B == a2 ) ) )
1538 {
1539 return seg2;
1540 }
1541 }
1542 }
1543
1544 return nullptr;
1545}

References SEG::A, SEG::B, FindJoint(), PNS::ITEM::Layers(), PNS::JOINT::LinkList(), PNS::SEGMENT::Seg(), PNS::ITEM::SEGMENT_T, and LAYER_RANGE::Start().

Referenced by Add(), and findRedundantSegment().

◆ findRedundantSegment() [2/2]

SEGMENT * PNS::NODE::findRedundantSegment ( SEGMENT aSeg)
private

Definition at line 1548 of file pns_node.cpp.

1549{
1550 return findRedundantSegment( aSeg->Seg().A, aSeg->Seg().B, aSeg->Layers(), aSeg->Net() );
1551}

References SEG::A, SEG::B, findRedundantSegment(), PNS::ITEM::Layers(), PNS::ITEM::Net(), and PNS::SEGMENT::Seg().

◆ FixupVirtualVias()

void PNS::NODE::FixupVirtualVias ( )

Definition at line 1118 of file pns_node.cpp.

1119{
1120 SEGMENT* locked_seg = nullptr;
1121 std::vector<VVIA*> vvias;
1122
1123 for( auto& jointPair : m_joints )
1124 {
1125 JOINT joint = jointPair.second;
1126
1127 if( joint.Layers().IsMultilayer() )
1128 continue;
1129
1130 int n_seg = 0, n_solid = 0, n_vias = 0;
1131 int prev_w = -1;
1132 int max_w = -1;
1133 bool is_width_change = false;
1134 bool is_locked = false;
1135
1136 for( const auto& lnk : joint.LinkList() )
1137 {
1138 if( lnk.item->OfKind( ITEM::VIA_T ) )
1139 {
1140 n_vias++;
1141 }
1142 else if( lnk.item->OfKind( ITEM::SOLID_T ) )
1143 {
1144 n_solid++;
1145 }
1146 else if( const auto t = dyn_cast<PNS::SEGMENT*>( lnk.item ) )
1147 {
1148 int w = t->Width();
1149
1150 if( prev_w >= 0 && w != prev_w )
1151 {
1152 is_width_change = true;
1153 }
1154
1155 max_w = std::max( w, max_w );
1156 prev_w = w;
1157
1158 is_locked = t->IsLocked();
1159 locked_seg = t;
1160 }
1161 }
1162
1163 if( ( is_width_change || n_seg >= 3 || is_locked ) && n_solid == 0 && n_vias == 0 )
1164 {
1165 // fixme: the hull margin here is an ugly temporary workaround. The real fix
1166 // is to use octagons for via force propagation.
1167 vvias.push_back( new VVIA( joint.Pos(), joint.Layers().Start(),
1168 max_w + 2 * PNS_HULL_MARGIN, joint.Net() ) );
1169 }
1170
1171 if( is_locked )
1172 {
1173 const VECTOR2I& secondPos = ( locked_seg->Seg().A == joint.Pos() ) ?
1174 locked_seg->Seg().B :
1175 locked_seg->Seg().A;
1176
1177 vvias.push_back( new VVIA( secondPos, joint.Layers().Start(),
1178 max_w + 2 * PNS_HULL_MARGIN, joint.Net() ) );
1179 }
1180 }
1181
1182 for( auto vvia : vvias )
1183 {
1184 Add( ItemCast<VIA>( std::move( std::unique_ptr<VVIA>( vvia ) ) ) );
1185 }
1186}
#define PNS_HULL_MARGIN
Definition: pns_line.h:44

References SEG::A, Add(), SEG::B, LAYER_RANGE::IsMultilayer(), PNS::ITEM::Layers(), PNS::JOINT::LinkList(), m_joints, PNS::JOINT::Net(), PNS_HULL_MARGIN, PNS::JOINT::Pos(), PNS::SEGMENT::Seg(), PNS::ITEM::SOLID_T, LAYER_RANGE::Start(), and PNS::ITEM::VIA_T.

◆ followLine()

void PNS::NODE::followLine ( LINKED_ITEM aCurrent,
bool  aScanDirection,
int &  aPos,
int  aLimit,
VECTOR2I aCorners,
LINKED_ITEM **  aSegments,
bool *  aArcReversed,
bool &  aGuardHit,
bool  aStopAtLockedJoints,
bool  aFollowLockedSegments 
)
private

Definition at line 942 of file pns_node.cpp.

945{
946 bool prevReversed = false;
947
948 const VECTOR2I guard = aCurrent->Anchor( aScanDirection );
949
950 for( int count = 0 ; ; ++count )
951 {
952 const VECTOR2I p = aCurrent->Anchor( aScanDirection ^ prevReversed );
953 const JOINT* jt = FindJoint( p, aCurrent );
954
955 assert( jt );
956
957 aCorners[aPos] = jt->Pos();
958 aSegments[aPos] = aCurrent;
959 aArcReversed[aPos] = false;
960
961 if( aCurrent->Kind() == ITEM::ARC_T )
962 {
963 if( ( aScanDirection && jt->Pos() == aCurrent->Anchor( 0 ) )
964 || ( !aScanDirection && jt->Pos() == aCurrent->Anchor( 1 ) ) )
965 aArcReversed[aPos] = true;
966 }
967
968 aPos += ( aScanDirection ? 1 : -1 );
969
970 if( count && guard == p )
971 {
972 if( aPos >= 0 && aPos < aLimit )
973 aSegments[aPos] = nullptr;
974
975 aGuardHit = true;
976 break;
977 }
978
979 bool locked = aStopAtLockedJoints ? jt->IsLocked() : false;
980
981 if( locked || !jt->IsLineCorner( aFollowLockedSegments ) || aPos < 0 || aPos == aLimit )
982 break;
983
984 aCurrent = jt->NextSegment( aCurrent, aFollowLockedSegments );
985
986 prevReversed = ( aCurrent && jt->Pos() == aCurrent->Anchor( aScanDirection ) );
987 }
988}

References PNS::ITEM::Anchor(), PNS::ITEM::ARC_T, FindJoint(), PNS::JOINT::IsLineCorner(), PNS::JOINT::IsLocked(), PNS::ITEM::Kind(), locked, PNS::JOINT::NextSegment(), and PNS::JOINT::Pos().

Referenced by AssembleLine().

◆ GetClearance()

int PNS::NODE::GetClearance ( const ITEM aA,
const ITEM aB,
bool  aUseClearanceEpsilon = true 
) const

Definition at line 103 of file pns_node.cpp.

104{
105 if( !m_ruleResolver )
106 return 100000;
107
108 if( aA->IsVirtual() || aB->IsVirtual() )
109 return 0;
110
111 return m_ruleResolver->Clearance( aA, aB, aUseClearanceEpsilon );
112}
virtual int Clearance(const ITEM *aA, const ITEM *aB, bool aUseClearanceEpsilon=true)=0

References PNS::RULE_RESOLVER::Clearance(), PNS::ITEM::IsVirtual(), and m_ruleResolver.

Referenced by PNS::ITEM::collideSimple(), PNS::SHOVE::getClearance(), PNS::ROUTER::markViolations(), NearestObstacle(), PNS::DIFF_PAIR_PLACER::propagateDpHeadForces(), PNS::VIA::PushoutForce(), and PNS::LINE_PLACER::rhMarkObstacles().

◆ GetCollisionQueryScope()

COLLISION_QUERY_SCOPE PNS::NODE::GetCollisionQueryScope ( ) const
inline

Definition at line 421 of file pns_node.h.

422 {
424 }

References m_collisionQueryScope.

Referenced by PNS::ITEM::collideSimple(), and PNS::VIA::PushoutForce().

◆ GetHoleClearance()

int PNS::NODE::GetHoleClearance ( const ITEM aA,
const ITEM aB,
bool  aUseClearanceEpsilon = true 
) const

Definition at line 115 of file pns_node.cpp.

116{
117 if( !m_ruleResolver )
118 return 0;
119
120 if( aA->IsVirtual() || aB->IsVirtual() )
121 return 0;
122
123 return m_ruleResolver->HoleClearance( aA, aB, aUseClearanceEpsilon );
124}
virtual int HoleClearance(const ITEM *aA, const ITEM *aB, bool aUseClearanceEpsilon=true)=0

References PNS::RULE_RESOLVER::HoleClearance(), PNS::ITEM::IsVirtual(), and m_ruleResolver.

Referenced by PNS::ITEM::collideSimple(), PNS::SHOVE::getHoleClearance(), PNS::ROUTER::markViolations(), NearestObstacle(), and PNS::VIA::PushoutForce().

◆ GetHoleToHoleClearance()

int PNS::NODE::GetHoleToHoleClearance ( const ITEM aA,
const ITEM aB,
bool  aUseClearanceEpsilon = true 
) const

Return the pre-set worst case clearance between any pair of items.

Definition at line 127 of file pns_node.cpp.

128{
129 if( !m_ruleResolver )
130 return 0;
131
132 if( aA->IsVirtual() || aB->IsVirtual() )
133 return 0;
134
135 return m_ruleResolver->HoleToHoleClearance( aA, aB, aUseClearanceEpsilon );
136}
virtual int HoleToHoleClearance(const ITEM *aA, const ITEM *aB, bool aUseClearanceEpsilon=true)=0

References PNS::RULE_RESOLVER::HoleToHoleClearance(), PNS::ITEM::IsVirtual(), and m_ruleResolver.

Referenced by PNS::ITEM::collideSimple(), NearestObstacle(), and PNS::VIA::PushoutForce().

◆ GetMaxClearance()

int PNS::NODE::GetMaxClearance ( ) const
inline

Set the worst-case clearance between any pair of items.

Definition at line 180 of file pns_node.h.

References m_maxClearance.

◆ GetParent()

NODE * PNS::NODE::GetParent ( void  ) const
inline

Check if this branch contains an updated version of the m_item from the root branch.

Definition at line 403 of file pns_node.h.

References m_parent.

◆ GetRuleResolver()

RULE_RESOLVER * PNS::NODE::GetRuleResolver ( ) const
inline

Return the number of joints.

Definition at line 197 of file pns_node.h.

References m_ruleResolver.

Referenced by PNS::TOPOLOGY::AssembleDiffPair(), PNS::ITEM::collideSimple(), and PNS::DIFF_PAIR_PLACER::FindDpPrimitivePair().

◆ GetUpdatedItems()

void PNS::NODE::GetUpdatedItems ( ITEM_VECTOR aRemoved,
ITEM_VECTOR aAdded 
)

Return the list of items removed and added in this branch with respect to the root branch.

Parameters
aRemovedremoved items.
aAddedadded items.

Definition at line 1392 of file pns_node.cpp.

1393{
1394 if( isRoot() )
1395 return;
1396
1397 if( m_override.size() )
1398 aRemoved.reserve( m_override.size() );
1399
1400 if( m_index->Size() )
1401 aAdded.reserve( m_index->Size() );
1402
1403 for( ITEM* item : m_override )
1404 aRemoved.push_back( item );
1405
1406 for( INDEX::ITEM_SET::iterator i = m_index->begin(); i != m_index->end(); ++i )
1407 aAdded.push_back( *i );
1408}
int Size() const
Returns number of items stored in the index.
Definition: pns_index.h:115
ITEM_SET::iterator end()
Definition: pns_index.h:118
ITEM_SET::iterator begin()
Definition: pns_index.h:117

References PNS::INDEX::begin(), PNS::INDEX::end(), isRoot(), m_index, m_override, and PNS::INDEX::Size().

Referenced by PNS::ROUTER::CommitRouting(), PNS::LINE_PLACER::FixRoute(), PNS_LOG_PLAYER::ReplayLog(), PNS::LINE_PLACER::simplifyNewLine(), and PNS::ROUTER::updateView().

◆ HasChildren()

bool PNS::NODE::HasChildren ( ) const
inline

Definition at line 398 of file pns_node.h.

399 {
400 return !m_children.empty();
401 }

References m_children.

◆ HitTest()

const ITEM_SET PNS::NODE::HitTest ( const VECTOR2I aPoint) const

Find all items that contain the point aPoint.

Parameters
aPointthe point.
Returns
the items.

Definition at line 543 of file pns_node.cpp.

544{
545 ITEM_SET items;
546
547 // fixme: we treat a point as an infinitely small circle - this is inefficient.
548 SHAPE_CIRCLE s( aPoint, 0 );
549 HIT_VISITOR visitor( items, aPoint );
550 visitor.SetWorld( this, nullptr );
551
552 m_index->Query( &s, m_maxClearance, visitor );
553
554 if( !isRoot() ) // fixme: could be made cleaner
555 {
556 ITEM_SET items_root;
557 visitor.SetWorld( m_root, nullptr );
558 HIT_VISITOR visitor_root( items_root, aPoint );
559 m_root->m_index->Query( &s, m_maxClearance, visitor_root );
560
561 for( ITEM* item : items_root.Items() )
562 {
563 if( !Overrides( item ) )
564 items.Add( item );
565 }
566 }
567
568 return items;
569}
int Query(const ITEM *aItem, int aMinDistance, Visitor &aVisitor) const
Searches items in the index that are in proximity of aItem.
Definition: pns_index.h:141

References PNS::ITEM_SET::Add(), isRoot(), PNS::ITEM_SET::Items(), m_index, m_maxClearance, m_root, Overrides(), PNS::INDEX::Query(), and PNS::OBSTACLE_VISITOR::SetWorld().

◆ isRoot()

bool PNS::NODE::isRoot ( ) const
inlineprivate

Definition at line 460 of file pns_node.h.

461 {
462 return m_parent == nullptr;
463 }

References m_parent.

Referenced by AllItemsInNet(), Branch(), Commit(), doRemove(), Dump(), FindJoint(), GetUpdatedItems(), HitTest(), QueryColliding(), QueryJoints(), releaseGarbage(), touchJoint(), and unlinkParent().

◆ JointCount()

int PNS::NODE::JointCount ( ) const
inline

Return the number of nodes in the inheritance chain (wrs to the root node).

Definition at line 203 of file pns_node.h.

References m_joints.

Referenced by PNS::SHOVE::shoveMainLoop().

◆ KillChildren()

◆ linkJoint()

void PNS::NODE::linkJoint ( const VECTOR2I aPos,
const LAYER_RANGE aLayers,
int  aNet,
ITEM aWhere 
)
private

Unlink an item from a joint.

Definition at line 1288 of file pns_node.cpp.

1289{
1290 JOINT& jt = touchJoint( aPos, aLayers, aNet );
1291
1292 jt.Link( aWhere );
1293}
JOINT & touchJoint(const VECTOR2I &aPos, const LAYER_RANGE &aLayers, int aNet)
Touch a joint and links it to an m_item.
Definition: pns_node.cpp:1226

References PNS::JOINT::Link(), and touchJoint().

Referenced by addArc(), addSegment(), addSolid(), addVia(), and rebuildJoint().

◆ LockJoint()

void PNS::NODE::LockJoint ( const VECTOR2I aPos,
const ITEM aItem,
bool  aLock 
)

Definition at line 1219 of file pns_node.cpp.

1220{
1221 JOINT& jt = touchJoint( aPos, aItem->Layers(), aItem->Net() );
1222 jt.Lock( aLock );
1223}

References PNS::ITEM::Layers(), PNS::JOINT::Lock(), PNS::ITEM::Net(), and touchJoint().

Referenced by PNS::SHOVE::ShoveLines().

◆ NearestObstacle()

NODE::OPT_OBSTACLE PNS::NODE::NearestObstacle ( const LINE aLine,
int  aKindMask = ITEM::ANY_T,
const std::set< ITEM * > *  aRestrictedSet = nullptr,
bool  aUseClearanceEpsilon = true 
)

Follow the line in search of an obstacle that is nearest to the starting to the line's starting point.

Parameters
aLinethe item to find collisions with
aKindMaskmask of obstacle types to take into account
aRestrictedSetis an optional set of items that should be considered as obstacles
aUseClearanceEpsilondetermines if the epsilon is subtracted from the hull size
Returns
the obstacle, if found, otherwise empty.

Definition at line 301 of file pns_node.cpp.

304{
305 OBSTACLES obstacleList;
306 obstacleList.reserve( 100 );
307
308 for( int i = 0; i < aLine->CLine().SegmentCount(); i++ )
309 {
310 // Note: Clearances between &s and other items are cached,
311 // which means they'll be the same for all segments in the line.
312 // Disabling the cache will lead to slowness.
313
314 const SEGMENT s( *aLine, aLine->CLine().CSegment( i ) );
315 QueryColliding( &s, obstacleList, aKindMask );
316 }
317
318 if( aLine->EndsWithVia() )
319 QueryColliding( &aLine->Via(), obstacleList, aKindMask );
320
321 if( obstacleList.empty() )
322 return OPT_OBSTACLE();
323
324 OBSTACLE nearest;
325 nearest.m_item = nullptr;
326 nearest.m_distFirst = INT_MAX;
327
328 auto updateNearest =
329 [&]( const SHAPE_LINE_CHAIN::INTERSECTION& pt, ITEM* obstacle,
330 const SHAPE_LINE_CHAIN& hull, bool isHole )
331 {
332 int dist = aLine->CLine().PathLength( pt.p, pt.index_their );
333
334 if( dist < nearest.m_distFirst )
335 {
336 nearest.m_distFirst = dist;
337 nearest.m_ipFirst = pt.p;
338 nearest.m_item = obstacle;
339 nearest.m_hull = hull;
340
341 obstacle->Mark( isHole ? obstacle->Marker() | MK_HOLE
342 : obstacle->Marker() & ~MK_HOLE );
343 }
344 };
345
346 SHAPE_LINE_CHAIN obstacleHull;
347 DEBUG_DECORATOR* debugDecorator = ROUTER::GetInstance()->GetInterface()->GetDebugDecorator();
348 std::vector<SHAPE_LINE_CHAIN::INTERSECTION> intersectingPts;
349 int layer = aLine->Layer();
350
351
352 for( const OBSTACLE& obstacle : obstacleList )
353 {
354 if( aRestrictedSet && aRestrictedSet->find( obstacle.m_item ) == aRestrictedSet->end() )
355 continue;
356
357 int clearance =
358 GetClearance( obstacle.m_item, aLine, aUseClearanceEpsilon ) + aLine->Width() / 2;
359
360 obstacleHull = obstacle.m_item->Hull( clearance, 0, layer );
361 //debugDecorator->AddLine( obstacleHull, 2, 40000, "obstacle-hull-test" );
362 //debugDecorator->AddLine( aLine->CLine(), 5, 40000, "obstacle-test-line" );
363
364 intersectingPts.clear();
365 HullIntersection( obstacleHull, aLine->CLine(), intersectingPts );
366
367 for( const auto& ip : intersectingPts )
368 {
369 //debugDecorator->AddPoint( ip.p, ip.valid?3:6, 100000, (const char *) wxString::Format("obstacle-isect-point-%d" ).c_str() );
370 if( ip.valid )
371 updateNearest( ip, obstacle.m_item, obstacleHull, false );
372 }
373
374 if( aLine->EndsWithVia() )
375 {
376 const VIA& via = aLine->Via();
377 // Don't use via.Drill(); it doesn't include the plating thickness
378
379 int viaHoleRadius = static_cast<const SHAPE_CIRCLE*>( via.Hole() )->GetRadius();
380
381 int viaClearance = GetClearance( obstacle.m_item, &via, aUseClearanceEpsilon )
382 + via.Diameter() / 2;
383 int holeClearance =
384 GetHoleClearance( obstacle.m_item, &via, aUseClearanceEpsilon ) + viaHoleRadius;
385
386 if( holeClearance > viaClearance )
387 viaClearance = holeClearance;
388
389 obstacleHull = obstacle.m_item->Hull( viaClearance, 0, layer );
390 //debugDecorator->AddLine( obstacleHull, 3 );
391
392 intersectingPts.clear();
393 HullIntersection( obstacleHull, aLine->CLine(), intersectingPts );
394
395 // obstacleHull.Intersect( aLine->CLine(), intersectingPts, true );
396
397 for( const SHAPE_LINE_CHAIN::INTERSECTION& ip : intersectingPts )
398 updateNearest( ip, obstacle.m_item, obstacleHull, false );
399 }
400
402 || !ROUTER::GetInstance()->GetInterface()->IsFlashedOnLayer( obstacle.m_item,
403 layer ) )
404 && obstacle.m_item->Hole() )
405 {
406 clearance = GetHoleClearance( obstacle.m_item, aLine, aUseClearanceEpsilon );
407 int copperClearance = GetClearance( obstacle.m_item, aLine, aUseClearanceEpsilon );
408
409 clearance = std::max( clearance, copperClearance );
410
411 obstacleHull = obstacle.m_item->HoleHull( clearance, aLine->Width(), layer );
412
413 intersectingPts.clear();
414 HullIntersection( obstacleHull, aLine->CLine(), intersectingPts );
415
416 for( const SHAPE_LINE_CHAIN::INTERSECTION& ip : intersectingPts )
417 updateNearest( ip, obstacle.m_item, obstacleHull, true );
418
419 if( aLine->EndsWithVia() )
420 {
421 const VIA& via = aLine->Via();
422 // Don't use via.Drill(); it doesn't include the plating thickness
423 int viaHoleRadius = static_cast<const SHAPE_CIRCLE*>( via.Hole() )->GetRadius();
424
425 int viaClearance = GetClearance( obstacle.m_item, &via, aUseClearanceEpsilon )
426 + via.Diameter() / 2;
427 int holeClearance = GetHoleClearance( obstacle.m_item, &via, aUseClearanceEpsilon )
428 + viaHoleRadius;
429 int holeToHole =
430 GetHoleToHoleClearance( obstacle.m_item, &via, aUseClearanceEpsilon )
431 + viaHoleRadius;
432
433 if( holeClearance > viaClearance )
434 viaClearance = holeClearance;
435
436 if( holeToHole > viaClearance )
437 viaClearance = holeToHole;
438
439 obstacleHull = obstacle.m_item->Hull( viaClearance, 0, layer );
440 //debugDecorator->AddLine( obstacleHull, 5 );
441
442 intersectingPts.clear();
443 HullIntersection( obstacleHull, aLine->CLine(), intersectingPts );
444
445 for( const SHAPE_LINE_CHAIN::INTERSECTION& ip : intersectingPts )
446 updateNearest( ip, obstacle.m_item, obstacleHull, true );
447 }
448 }
449 }
450
451 if( nearest.m_distFirst == INT_MAX )
452 nearest.m_item = obstacleList[0].m_item;
453
454 return nearest;
455}
int GetClearance(const ITEM *aA, const ITEM *aB, bool aUseClearanceEpsilon=true) const
Definition: pns_node.cpp:103
int GetHoleToHoleClearance(const ITEM *aA, const ITEM *aB, bool aUseClearanceEpsilon=true) const
Return the pre-set worst case clearance between any pair of items.
Definition: pns_node.cpp:127
int GetHoleClearance(const ITEM *aA, const ITEM *aB, bool aUseClearanceEpsilon=true) const
Definition: pns_node.cpp:115
virtual DEBUG_DECORATOR * GetDebugDecorator()=0
ROUTER_IFACE * GetInterface() const
Definition: pns_router.h:211
static ROUTER * GetInstance()
Definition: pns_router.cpp:78
void HullIntersection(const SHAPE_LINE_CHAIN &hull, const SHAPE_LINE_CHAIN &line, SHAPE_LINE_CHAIN::INTERSECTIONS &ips)
Definition: pns_utils.cpp:379
@ MK_HOLE
Definition: pns_item.h:45
@ VIA
Normal via.
Definition: router_tool.cpp:89
Represent an intersection between two line segments.
VECTOR2I p
< Point of intersection between our and their.
int index_their
When true, the corner [index_our] of the 'our' line lies exactly on 'their' line.

References PNS::LINE::CLine(), CQS_ALL_RULES, SHAPE_LINE_CHAIN::CSegment(), PNS::LINE::EndsWithVia(), GetClearance(), PNS::ROUTER_IFACE::GetDebugDecorator(), GetHoleClearance(), GetHoleToHoleClearance(), PNS::ROUTER::GetInstance(), PNS::ROUTER::GetInterface(), PNS::HullIntersection(), SHAPE_LINE_CHAIN::INTERSECTION::index_their, PNS::ITEM::Layer(), m_collisionQueryScope, PNS::OBSTACLE::m_distFirst, PNS::OBSTACLE::m_hull, PNS::OBSTACLE::m_ipFirst, PNS::OBSTACLE::m_item, PNS::MK_HOLE, SHAPE_LINE_CHAIN::INTERSECTION::p, SHAPE_LINE_CHAIN::PathLength(), QueryColliding(), via, PNS::LINE::Via(), and PNS::LINE::Width().

Referenced by PNS::LINE::ClipToNearestObstacle(), PNS::WALKAROUND::nearestObstacle(), PNS::LINE_PLACER::rhMarkObstacles(), and PNS::SHOVE::shoveIteration().

◆ operator=()

NODE & PNS::NODE::operator= ( const NODE aB)
private

Try to find matching joint and creates a new one if not found.

◆ Overrides()

bool PNS::NODE::Overrides ( ITEM aItem) const
inline

Definition at line 409 of file pns_node.h.

410 {
411 return m_override.find( aItem ) != m_override.end();
412 }

References m_override.

Referenced by AllItemsInNet(), HitTest(), QueryJoints(), and PNS::OBSTACLE_VISITOR::visit().

◆ QueryColliding()

int PNS::NODE::QueryColliding ( const ITEM aItem,
NODE::OBSTACLES aObstacles,
int  aKindMask = ITEM::ANY_T,
int  aLimitCount = -1,
bool  aDifferentNetsOnly = true,
int  aOverrideClearance = -1 
)

Find items colliding (closer than clearance) with the item aItem.

Parameters
aItemitem to check collisions against
aObstaclesset of colliding objects found
aKindMaskmask of obstacle types to take into account
aLimitCountstop looking for collisions after finding this number of colliding items
Returns
number of obstacles found

By default, virtual items cannot collide

Definition at line 271 of file pns_node.cpp.

273{
275 if( aItem->IsVirtual() )
276 return 0;
277
278 DEFAULT_OBSTACLE_VISITOR visitor( aObstacles, aItem, aKindMask, aDifferentNetsOnly, aOverrideClearance );
279
280#ifdef DEBUG
281 assert( allocNodes.find( this ) != allocNodes.end() );
282#endif
283
284 visitor.SetCountLimit( aLimitCount );
285 visitor.SetWorld( this, nullptr );
286
287 // first, look for colliding items in the local index
288 m_index->Query( aItem, m_maxClearance, visitor );
289
290 // if we haven't found enough items, look in the root branch as well.
291 if( !isRoot() && ( visitor.m_matchCount < aLimitCount || aLimitCount < 0 ) )
292 {
293 visitor.SetWorld( m_root, this );
294 m_root->m_index->Query( aItem, m_maxClearance, visitor );
295 }
296
297 return aObstacles.size();
298}

References isRoot(), PNS::ITEM::IsVirtual(), m_index, PNS::NODE::DEFAULT_OBSTACLE_VISITOR::m_matchCount, m_maxClearance, m_root, PNS::INDEX::Query(), PNS::NODE::DEFAULT_OBSTACLE_VISITOR::SetCountLimit(), and PNS::OBSTACLE_VISITOR::SetWorld().

Referenced by PNS::TOPOLOGY::AssembleCluster(), CheckColliding(), PNS::ROUTER::markViolations(), and NearestObstacle().

◆ QueryEdgeExclusions()

bool PNS::NODE::QueryEdgeExclusions ( const VECTOR2I aPos) const

Definition at line 734 of file pns_node.cpp.

735{
736 for( const std::unique_ptr<SHAPE>& edgeExclusion : m_edgeExclusions )
737 {
738 if( edgeExclusion->Collide( aPos ) )
739 return true;
740 }
741
742 return false;
743}

References m_edgeExclusions.

Referenced by PNS::ITEM::collideSimple().

◆ QueryJoints()

int PNS::NODE::QueryJoints ( const BOX2I aBox,
std::vector< JOINT * > &  aJoints,
LAYER_RANGE  aLayerMask = LAYER_RANGE::All(),
int  aKindMask = ITEM::ANY_T 
)

Definition at line 1589 of file pns_node.cpp.

1591{
1592 int n = 0;
1593
1594 aJoints.clear();
1595
1596 for( JOINT_MAP::value_type& j : m_joints )
1597 {
1598 if( !j.second.Layers().Overlaps( aLayerMask ) )
1599 continue;
1600
1601 if( aBox.Contains( j.second.Pos() ) && j.second.LinkCount( aKindMask ) )
1602 {
1603 aJoints.push_back( &j.second );
1604 n++;
1605 }
1606 }
1607
1608 if( isRoot() )
1609 return n;
1610
1611 for( JOINT_MAP::value_type& j : m_root->m_joints )
1612 {
1613 if( !Overrides( &j.second ) && j.second.Layers().Overlaps( aLayerMask ) )
1614 {
1615 if( aBox.Contains( j.second.Pos() ) && j.second.LinkCount( aKindMask ) )
1616 {
1617 aJoints.push_back( &j.second );
1618 n++;
1619 }
1620 }
1621 }
1622
1623 return n;
1624}
bool Contains(const Vec &aPoint) const
Definition: box2.h:141

References BOX2< Vec >::Contains(), isRoot(), m_joints, m_root, and Overrides().

Referenced by PNS::KEEP_TOPOLOGY_CONSTRAINT::Check(), and PNS::COMPONENT_DRAGGER::Start().

◆ rebuildJoint()

void PNS::NODE::rebuildJoint ( JOINT aJoint,
ITEM aItem 
)
private

Definition at line 781 of file pns_node.cpp.

782{
783 // We have to split a single joint (associated with a via or a pad, binding together multiple
784 // layers) into multiple independent joints. As I'm a lazy bastard, I simply delete the
785 // via/solid and all its links and re-insert them.
786
787 JOINT::LINKED_ITEMS links( aJoint->LinkList() );
788 JOINT::HASH_TAG tag;
789 int net = aItem->Net();
790
791 tag.net = net;
792 tag.pos = aJoint->Pos();
793
794 bool split;
795
796 do
797 {
798 split = false;
799 auto range = m_joints.equal_range( tag );
800
801 if( range.first == m_joints.end() )
802 break;
803
804 // find and remove all joints containing the via to be removed
805
806 for( auto f = range.first; f != range.second; ++f )
807 {
808 if( aItem->LayersOverlap( &f->second ) )
809 {
810 m_joints.erase( f );
811 split = true;
812 break;
813 }
814 }
815 } while( split );
816
817 // and re-link them, using the former via's link list
818 for( ITEM* link : links )
819 {
820 if( link != aItem )
821 linkJoint( tag.pos, link->Layers(), net, link );
822 }
823}
ITEM_SET::ENTRIES LINKED_ITEMS
Joints are hashed by their position, layers and net.
Definition: pns_joint.h:45
static std::vector< std::string > split(const std::string &aStr, const std::string &aDelim)
Split the input string into a vector of output strings.
Definition: string_utils.h:296

References PNS::ITEM::LayersOverlap(), linkJoint(), PNS::JOINT::LinkList(), m_joints, PNS::ITEM::Net(), PNS::JOINT::HASH_TAG::net, PNS::JOINT::HASH_TAG::pos, PNS::JOINT::Pos(), and split().

Referenced by removeSolidIndex(), and removeViaIndex().

◆ releaseChildren()

void PNS::NODE::releaseChildren ( )
private

Definition at line 1411 of file pns_node.cpp.

1412{
1413 // copy the kids as the NODE destructor erases the item from the parent node.
1414 std::set<NODE*> kids = m_children;
1415
1416 for( NODE* node : kids )
1417 {
1418 node->releaseChildren();
1419 delete node;
1420 }
1421}

References m_children.

Referenced by Commit(), and KillChildren().

◆ releaseGarbage()

void PNS::NODE::releaseGarbage ( )
private

Definition at line 1424 of file pns_node.cpp.

1425{
1426 if( !isRoot() )
1427 return;
1428
1429 for( ITEM* item : m_garbageItems )
1430 {
1431 if( !item->BelongsTo( this ) )
1432 delete item;
1433 }
1434
1435 m_garbageItems.clear();
1436}

References isRoot(), and m_garbageItems.

Referenced by Commit(), and ~NODE().

◆ Remove() [1/6]

◆ Remove() [2/6]

void PNS::NODE::Remove ( ITEM aItem)

Definition at line 888 of file pns_node.cpp.

889{
890 switch( aItem->Kind() )
891 {
892 case ITEM::ARC_T:
893 Remove( static_cast<ARC*>( aItem ) );
894 break;
895
896 case ITEM::SOLID_T:
897 Remove( static_cast<SOLID*>( aItem ) );
898 break;
899
900 case ITEM::SEGMENT_T:
901 Remove( static_cast<SEGMENT*>( aItem ) );
902 break;
903
904 case ITEM::LINE_T:
905 {
906 LINE* l = static_cast<LINE*>( aItem );
907
908 for ( LINKED_ITEM* s : l->Links() )
909 Remove( s );
910
911 break;
912 }
913
914 case ITEM::VIA_T:
915 Remove( static_cast<VIA*>( aItem ) );
916 break;
917
918 default:
919 break;
920 }
921}

References PNS::ITEM::ARC_T, PNS::ITEM::Kind(), PNS::ITEM::LINE_T, PNS::LINK_HOLDER::Links(), Remove(), PNS::ITEM::SEGMENT_T, PNS::ITEM::SOLID_T, and PNS::ITEM::VIA_T.

◆ Remove() [3/6]

void PNS::NODE::Remove ( LINE aLine)

Removes a line from this branch.

Parameters
aLineitem to remove

Definition at line 924 of file pns_node.cpp.

925{
926 // LINE does not have a separate remover, as LINEs are never truly a member of the tree
927 std::vector<LINKED_ITEM*>& segRefs = aLine.Links();
928
929 for( LINKED_ITEM* li : segRefs )
930 {
931 if( li->OfKind( ITEM::SEGMENT_T ) )
932 Remove( static_cast<SEGMENT*>( li ) );
933 else if( li->OfKind( ITEM::ARC_T ) )
934 Remove( static_cast<ARC*>( li ) );
935 }
936
937 aLine.SetOwner( nullptr );
938 aLine.ClearLinks();
939}

References PNS::ITEM::ARC_T, PNS::LINK_HOLDER::ClearLinks(), PNS::LINK_HOLDER::Links(), Remove(), PNS::ITEM::SEGMENT_T, and PNS::ITEM::SetOwner().

◆ Remove() [4/6]

void PNS::NODE::Remove ( SEGMENT aSegment)

Definition at line 874 of file pns_node.cpp.

875{
876 removeSegmentIndex( aSegment );
877 doRemove( aSegment );
878}
void removeSegmentIndex(SEGMENT *aSeg)
Definition: pns_node.cpp:767

References doRemove(), and removeSegmentIndex().

◆ Remove() [5/6]

void PNS::NODE::Remove ( SOLID aSolid)

Definition at line 860 of file pns_node.cpp.

861{
862 removeSolidIndex( aSolid );
863 doRemove( aSolid );
864}
void removeSolidIndex(SOLID *aSeg)
Definition: pns_node.cpp:834

References doRemove(), and removeSolidIndex().

◆ Remove() [6/6]

void PNS::NODE::Remove ( VIA aVia)

Definition at line 867 of file pns_node.cpp.

868{
869 removeViaIndex( aVia );
870 doRemove( aVia );
871}
void removeViaIndex(VIA *aVia)
Definition: pns_node.cpp:826

References doRemove(), and removeViaIndex().

◆ removeArcIndex()

void PNS::NODE::removeArcIndex ( ARC aVia)
private

Definition at line 774 of file pns_node.cpp.

775{
776 unlinkJoint( aArc->Anchor( 0 ), aArc->Layers(), aArc->Net(), aArc );
777 unlinkJoint( aArc->Anchor( 1 ), aArc->Layers(), aArc->Net(), aArc );
778}
void unlinkJoint(const VECTOR2I &aPos, const LAYER_RANGE &aLayers, int aNet, ITEM *aWhere)
Helpers for adding/removing items.
Definition: pns_node.cpp:1296

References PNS::ARC::Anchor(), PNS::ITEM::Layers(), PNS::ITEM::Net(), and unlinkJoint().

Referenced by Remove().

◆ RemoveByMarker()

void PNS::NODE::RemoveByMarker ( int  aMarker)

Definition at line 1504 of file pns_node.cpp.

1505{
1506 std::vector<ITEM*> garbage;
1507
1508 for( ITEM* item : *m_index )
1509 {
1510 if( item->Marker() & aMarker )
1511 garbage.emplace_back( item );
1512 }
1513
1514 for( ITEM* item : garbage )
1515 Remove( item );
1516}

References m_index, and Remove().

Referenced by PNS::SHOVE::ShoveLines(), and PNS::SHOVE::ShoveMultiLines().

◆ removeSegmentIndex()

void PNS::NODE::removeSegmentIndex ( SEGMENT aSeg)
private

Definition at line 767 of file pns_node.cpp.

768{
769 unlinkJoint( aSeg->Seg().A, aSeg->Layers(), aSeg->Net(), aSeg );
770 unlinkJoint( aSeg->Seg().B, aSeg->Layers(), aSeg->Net(), aSeg );
771}

References SEG::A, SEG::B, PNS::ITEM::Layers(), PNS::ITEM::Net(), PNS::SEGMENT::Seg(), and unlinkJoint().

Referenced by Remove().

◆ removeSolidIndex()

void PNS::NODE::removeSolidIndex ( SOLID aSeg)
private

Definition at line 834 of file pns_node.cpp.

835{
836 if( !aSolid->IsRoutable() )
837 return;
838
839 // fixme: redundant code
840 JOINT* jt = FindJoint( aSolid->Pos(), aSolid->Layers().Start(), aSolid->Net() );
841 assert( jt );
842 rebuildJoint( jt, aSolid );
843}
void rebuildJoint(JOINT *aJoint, ITEM *aItem)
Definition: pns_node.cpp:781

References FindJoint(), PNS::ITEM::IsRoutable(), PNS::ITEM::Layers(), PNS::ITEM::Net(), PNS::SOLID::Pos(), rebuildJoint(), and LAYER_RANGE::Start().

Referenced by Remove().

◆ removeViaIndex()

void PNS::NODE::removeViaIndex ( VIA aVia)
private

Definition at line 826 of file pns_node.cpp.

827{
828 JOINT* jt = FindJoint( aVia->Pos(), aVia->Layers().Start(), aVia->Net() );
829 assert( jt );
830 rebuildJoint( jt, aVia );
831}

References FindJoint(), PNS::ITEM::Layers(), PNS::ITEM::Net(), PNS::VIA::Pos(), rebuildJoint(), and LAYER_RANGE::Start().

Referenced by Remove().

◆ Replace() [1/2]

void PNS::NODE::Replace ( ITEM aOldItem,
std::unique_ptr< ITEM aNewItem 
)

Replace an item with another one.

Parameters
aOldItemitem to be removed
aNewItemitem add instead

Definition at line 846 of file pns_node.cpp.

847{
848 Remove( aOldItem );
849 Add( std::move( aNewItem ) );
850}

References Add(), and Remove().

Referenced by PNS::SHOVE::replaceItems(), and PNS::SHOVE::replaceLine().

◆ Replace() [2/2]

void PNS::NODE::Replace ( LINE aOldLine,
LINE aNewLine 
)

Definition at line 853 of file pns_node.cpp.

854{
855 Remove( aOldLine );
856 Add( aNewLine );
857}

References Add(), and Remove().

◆ SetCollisionQueryScope()

void PNS::NODE::SetCollisionQueryScope ( COLLISION_QUERY_SCOPE  aScope)
inline

Definition at line 416 of file pns_node.h.

417 {
418 m_collisionQueryScope = aScope;
419 }

References m_collisionQueryScope.

◆ SetMaxClearance()

void PNS::NODE::SetMaxClearance ( int  aClearance)
inline

Assign a clearance resolution function object.

Definition at line 186 of file pns_node.h.

References m_maxClearance.

Referenced by PNS_KICAD_IFACE_BASE::SyncWorld().

◆ SetRuleResolver()

void PNS::NODE::SetRuleResolver ( RULE_RESOLVER aFunc)
inline

Definition at line 192 of file pns_node.h.

193 {
194 m_ruleResolver = aFunc;
195 }

References m_ruleResolver.

Referenced by PNS_KICAD_IFACE_BASE::SyncWorld().

◆ touchJoint()

JOINT & PNS::NODE::touchJoint ( const VECTOR2I aPos,
const LAYER_RANGE aLayers,
int  aNet 
)
private

Touch a joint and links it to an m_item.

Definition at line 1226 of file pns_node.cpp.

1227{
1228 JOINT::HASH_TAG tag;
1229
1230 tag.pos = aPos;
1231 tag.net = aNet;
1232
1233 // try to find the joint in this node.
1234 JOINT_MAP::iterator f = m_joints.find( tag );
1235
1236 std::pair<JOINT_MAP::iterator, JOINT_MAP::iterator> range;
1237
1238 // not found and we are not root? find in the root and copy results here.
1239 if( f == m_joints.end() && !isRoot() )
1240 {
1241 range = m_root->m_joints.equal_range( tag );
1242
1243 for( f = range.first; f != range.second; ++f )
1244 m_joints.insert( *f );
1245 }
1246
1247 // now insert and combine overlapping joints
1248 JOINT jt( aPos, aLayers, aNet );
1249
1250 bool merged;
1251
1252 do
1253 {
1254 merged = false;
1255 range = m_joints.equal_range( tag );
1256
1257 if( range.first == m_joints.end() )
1258 break;
1259
1260 for( f = range.first; f != range.second; ++f )
1261 {
1262 if( aLayers.Overlaps( f->second.Layers() ) )
1263 {
1264 jt.Merge( f->second );
1265 m_joints.erase( f );
1266 merged = true;
1267 break;
1268 }
1269 }
1270 }
1271 while( merged );
1272
1273 return m_joints.insert( TagJointPair( tag, jt ) )->second;
1274}
bool Overlaps(const LAYER_RANGE &aOther) const
Definition: pns_layerset.h:67
JOINT_MAP::value_type TagJointPair
Definition: pns_node.h:480

References isRoot(), m_joints, m_root, PNS::JOINT::Merge(), PNS::JOINT::HASH_TAG::net, LAYER_RANGE::Overlaps(), and PNS::JOINT::HASH_TAG::pos.

Referenced by linkJoint(), LockJoint(), and unlinkJoint().

◆ unlinkJoint()

void PNS::NODE::unlinkJoint ( const VECTOR2I aPos,
const LAYER_RANGE aLayers,
int  aNet,
ITEM aWhere 
)
private

Helpers for adding/removing items.

Definition at line 1296 of file pns_node.cpp.

1297{
1298 // fixme: remove dangling joints
1299 JOINT& jt = touchJoint( aPos, aLayers, aNet );
1300
1301 jt.Unlink( aWhere );
1302}

References touchJoint(), and PNS::JOINT::Unlink().

Referenced by removeArcIndex(), and removeSegmentIndex().

◆ unlinkParent()

void PNS::NODE::unlinkParent ( )
private

Definition at line 176 of file pns_node.cpp.

177{
178 if( isRoot() )
179 return;
180
181 m_parent->m_children.erase( this );
182}

References isRoot(), m_children, and m_parent.

Referenced by ~NODE().

Member Data Documentation

◆ m_children

std::set<NODE*> PNS::NODE::m_children
private

list of nodes branched from this one

Definition at line 487 of file pns_node.h.

Referenced by Branch(), HasChildren(), releaseChildren(), unlinkParent(), and ~NODE().

◆ m_collisionQueryScope

COLLISION_QUERY_SCOPE PNS::NODE::m_collisionQueryScope
private

◆ m_depth

int PNS::NODE::m_depth
private

depth of the node (number of parent nodes in the inheritance chain)

Definition at line 495 of file pns_node.h.

Referenced by Branch(), Depth(), and NODE().

◆ m_edgeExclusions

std::vector< std::unique_ptr<SHAPE> > PNS::NODE::m_edgeExclusions
private

Definition at line 498 of file pns_node.h.

Referenced by AddEdgeExclusion(), and QueryEdgeExclusions().

◆ m_garbageItems

std::unordered_set<ITEM*> PNS::NODE::m_garbageItems
private

Definition at line 500 of file pns_node.h.

Referenced by doRemove(), and releaseGarbage().

◆ m_index

INDEX* PNS::NODE::m_index
private

◆ m_joints

JOINT_MAP PNS::NODE::m_joints
private

hash table with the joints, linking the items.

Joints are hashed by their position, layer set and net.

Definition at line 482 of file pns_node.h.

Referenced by Branch(), Dump(), FindJoint(), FixupVirtualVias(), JointCount(), QueryJoints(), rebuildJoint(), touchJoint(), and ~NODE().

◆ m_maxClearance

int PNS::NODE::m_maxClearance
private

worst case item-item clearance

Definition at line 492 of file pns_node.h.

Referenced by Branch(), GetMaxClearance(), HitTest(), NODE(), QueryColliding(), and SetMaxClearance().

◆ m_override

std::unordered_set<ITEM*> PNS::NODE::m_override
private

hash of root's items that have been changed in this node

Definition at line 489 of file pns_node.h.

Referenced by Branch(), Commit(), doRemove(), GetUpdatedItems(), and Overrides().

◆ m_parent

NODE* PNS::NODE::m_parent
private

node this node was branched from

Definition at line 485 of file pns_node.h.

Referenced by Branch(), GetParent(), isRoot(), NODE(), and unlinkParent().

◆ m_root

NODE* PNS::NODE::m_root
private

root node of the whole hierarchy

Definition at line 486 of file pns_node.h.

Referenced by AllItemsInNet(), Branch(), doRemove(), Dump(), FindJoint(), HitTest(), NODE(), QueryColliding(), QueryJoints(), and touchJoint().

◆ m_ruleResolver

RULE_RESOLVER* PNS::NODE::m_ruleResolver
private

Design rules resolver.

Definition at line 493 of file pns_node.h.

Referenced by Branch(), GetClearance(), GetHoleClearance(), GetHoleToHoleClearance(), GetRuleResolver(), NODE(), and SetRuleResolver().


The documentation for this class was generated from the following files: