52static std::unordered_set<const NODE*> allocNodes;
 
   65    allocNodes.insert( 
this );
 
 
   74        wxLogTrace( wxT( 
"PNS" ), wxT( 
"attempting to free a node that has kids." ) );
 
   79    if( allocNodes.find( 
this ) == allocNodes.end() )
 
   81        wxLogTrace( wxT( 
"PNS" ), wxT( 
"attempting to free an already-free'd node." ) );
 
   85    allocNodes.erase( 
this );
 
   90    std::vector<const ITEM*> toDelete;
 
   92    toDelete.reserve( 
m_index->Size() );
 
   96        if( item->BelongsTo( 
this ) && item->OfKind( 
ITEM::HOLE_T ) )
 
   99            HOLE* hole = 
static_cast<HOLE*
>( item );
 
  107            toDelete.push_back( item );
 
  111    for( 
const ITEM* item : toDelete )
 
  113        wxLogTrace( wxT( 
"PNS" ), wxT( 
"del item %p type %s" ), item, item->KindStr().c_str() );
 
 
  137    int cl = 
m_ruleResolver->Clearance( aA, aB, aUseClearanceEpsilon );
 
 
  159        JOINT_MAP::iterator j;
 
  169    wxLogTrace( wxT( 
"PNS" ), wxT( 
"%d items, %d joints, %d overrides" ),
 
 
  231        if( !aCandidate->
OfKind( 
m_ctx->options.m_kindMask ) )
 
  235        if( 
m_item == aCandidate )
 
  238        if( 
m_ctx->options.m_filter && !
m_ctx->options.m_filter( aCandidate ) )
 
  241        if( 
visit( aCandidate ) )
 
  247        if( 
m_ctx->options.m_limitCount > 0 && 
m_ctx->obstacles.size() >= 
m_ctx->options.m_limitCount )
 
 
 
  267    assert( allocNodes.find( 
this ) != allocNodes.end() );
 
  282    return aObstacles.size();
 
 
  293    for( 
int i = 0; i < aLine->
CLine().SegmentCount(); i++ )
 
  306    if( obstacleList.empty() )
 
  330    std::vector<SHAPE_LINE_CHAIN::INTERSECTION> intersectingPts;
 
  331    int layer = aLine->
Layer();
 
  333    for( 
const OBSTACLE& obstacle : obstacleList )
 
  336                            + aLine->
Width() / 2;
 
  338        obstacleHull = obstacle.m_item->Hull( 
clearance, 0, layer );
 
  343            obstacleHull.
Clear();
 
  352        intersectingPts.clear();
 
  355        for( 
const auto& ip : intersectingPts )
 
  359                updateNearest( ip, obstacle );
 
  366                               + 
via.Diameter( aLine->
Layer() ) / 2;
 
  368            obstacleHull = obstacle.m_item->Hull( viaClearance, 0, layer );
 
  373                obstacleHull.
Clear();
 
  381            intersectingPts.clear();
 
  385                updateNearest( ip, obstacle );
 
  390        nearest = (*obstacleList.begin());
 
 
  427        const LINE* line = 
static_cast<const LINE*
>( aItemA );
 
 
  537    aSolid->SetOwner( 
this );
 
 
  578    switch( aItem->
Kind() )
 
 
  607    for( 
size_t i = 0; i < l.
ArcCount(); i++ )
 
  619            auto newarc = std::make_unique< ARC >( aLine, s );
 
  620            aLine.
Link( newarc.get() );
 
  621            Add( std::move( newarc ), 
true );
 
  645                std::unique_ptr<SEGMENT> newseg = std::make_unique<SEGMENT>( aLine, s );
 
  646                aLine.
Link( newseg.get() );
 
  647                Add( std::move( newseg ), 
true );
 
 
  665bool NODE::Add( std::unique_ptr< SEGMENT > aSegment, 
bool aAllowRedundant )
 
  667    if( aSegment->Seg().A == aSegment->Seg().B )
 
  669        wxLogTrace( wxT( 
"PNS" ),
 
  670                    wxT( 
"attempting to add a segment with same end coordinates, ignoring." ) );
 
 
  694bool NODE::Add( std::unique_ptr< ARC > aArc, 
bool aAllowRedundant )
 
 
  719        if( edgeExclusion->Collide( aPos ) )
 
 
  729    bool holeRemoved = 
false; 
 
  758        m_root->m_garbageItems.insert( aItem );
 
 
  797    std::vector<ITEM*> links( aJoint->
LinkList() );
 
  809        auto range = 
m_joints.equal_range( tag );
 
  816        for( 
auto f = range.first; f != range.second; ++f )
 
  827    bool completelyErased = 
false;
 
  834        completelyErased = 
true;
 
  839    for( 
ITEM* link : links )
 
  843        else if( !completelyErased )
 
 
  872    add( aNewItem.release() );
 
 
  879    Add( aNewLine, aAllowRedundantSegments );
 
 
  918    switch( aItem->
Kind() )
 
  944        LINE* l = 
static_cast<LINE*
>( aItem );
 
  959            via->Hole()->SetOwner( 
via );
 
 
  975    std::vector<LINKED_ITEM*>& segRefs = aLine.
Links();
 
 
  994                       bool& aGuardHit, 
bool aStopAtLockedJoints, 
bool aFollowLockedSegments )
 
  996    bool prevReversed = 
false;
 
 1000    for( 
int count = 0 ; ; ++count )
 
 1002        const VECTOR2I p  = aCurrent->
Anchor( aScanDirection ^ prevReversed );
 
 1008        aCorners[aPos]     = jt->
Pos();
 
 1009        aSegments[aPos]    = aCurrent;
 
 1010        aArcReversed[aPos] = 
false;
 
 1014            if( ( aScanDirection && jt->
Pos() == aCurrent->
Anchor( 0 ) )
 
 1015                    || ( !aScanDirection && jt->
Pos() == aCurrent->
Anchor( 1 ) ) )
 
 1017                aArcReversed[aPos] = 
true;
 
 1021        aPos += ( aScanDirection ? 1 : -1 );
 
 1023        if( count && guard == p )
 
 1025            if( aPos >= 0 && aPos < aLimit )
 
 1026                aSegments[aPos] = 
nullptr;
 
 1034        if( 
locked || aPos < 0 || aPos == aLimit )
 
 1037        aCurrent = jt->
NextSegment( aCurrent, aFollowLockedSegments );
 
 1042        prevReversed = ( aCurrent && jt->
Pos() == aCurrent->
Anchor( aScanDirection ) );
 
 
 1048                               bool aFollowLockedSegments, 
bool aAllowSegmentSizeMismatch )
 
 1050    const int MaxVerts = 1024 * 16;
 
 1052    std::array<VECTOR2I, MaxVerts + 1> corners;
 
 1053    std::array<LINKED_ITEM*, MaxVerts + 1> segs;
 
 1054    std::array<bool, MaxVerts + 1> arcReversed;
 
 1057    bool guardHit = 
false;
 
 1059    int i_start = MaxVerts / 2;
 
 1060    int i_end   = i_start + 1;
 
 1069    followLine( aSeg, 
false, i_start, MaxVerts, corners.data(), segs.data(), arcReversed.data(),
 
 1070                guardHit, aStopAtLockedJoints, aFollowLockedSegments );
 
 1074        followLine( aSeg, 
true, i_end, MaxVerts, corners.data(), segs.data(), arcReversed.data(),
 
 1075                    guardHit, aStopAtLockedJoints, aFollowLockedSegments );
 
 1081    bool originSet = 
false;
 
 1085    for( 
int i = i_start + 1; i < i_end; i++ )
 
 1090        if( !aAllowSegmentSizeMismatch && ( li && li->
Width() != aSeg->
Width() ) )
 
 1096        if( li && prev_seg != li )
 
 1100                const ARC*       arc = 
static_cast<const ARC*
>( li );
 
 1105                ssize_t lastShape = nSegs ? line.
ArcIndex( 
static_cast<ssize_t
>( nSegs ) - 1 ) : -1;
 
 1113            if( li == aSeg && aOriginSegmentIndex && !originSet )
 
 1117                *aOriginSegmentIndex = line.
PointCount() - 1;
 
 1129    if( aOriginSegmentIndex && *aOriginSegmentIndex >= pl.
SegmentCount() )
 
 1132    wxASSERT_MSG( pl.
SegmentCount() != 0, 
"assembled line should never be empty" );
 
 
 1157            JOINT j_start, j_end;
 
 1164            if( id_end < id_start )
 
 1165                std::swap( id_end, id_start );
 
 1167            if( id_start >= 0 && id_end >= 0 )
 
 1170                aLines.push_back( line );
 
 
 1181    const SEGMENT* locked_seg = 
nullptr;
 
 1182    std::vector<VVIA*> vvias;
 
 1186        JOINT joint = jointPair.second;
 
 1195        bool               prev_mask = 
false;
 
 1196        std::optional<int> prev_mask_margin;
 
 1198        bool               is_width_change = 
false;
 
 1199        bool               is_locked       = 
false;
 
 1215                std::optional<int> mask_margin;
 
 1219                    mask = track->HasSolderMask();
 
 1220                    mask_margin = track->GetLocalSolderMaskMargin();
 
 1227                    prev_mask_margin = mask_margin;
 
 1229                else if( w != prev_w || mask != prev_mask || mask_margin != prev_mask_margin )
 
 1231                    is_width_change = 
true;
 
 1234                max_w = std::max( w, max_w );
 
 1237                is_locked  = t->IsLocked();
 
 1242        if( ( is_width_change || n_seg >= 3 || is_locked ) && n_solid == 0 && n_vias == 0 )
 
 1253                                        locked_seg->
Seg().
B :
 
 1254                                        locked_seg->
Seg().
A;
 
 1261    for( 
auto vvia : vvias )
 
 
 1280        f = 
m_root->m_joints.find( tag );    
 
 1285        if( f->second.Pos() == aPos && f->second.Net() == aNet && f->second.Layers().Overlaps( aLayer ) )
 
 
 1310    JOINT_MAP::iterator f = 
m_joints.find( tag );
 
 1312    std::pair<JOINT_MAP::iterator, JOINT_MAP::iterator> range;
 
 1317        range = 
m_root->m_joints.equal_range( tag );
 
 1319        for( f = range.first; f != range.second; ++f )
 
 1324    JOINT jt( aPos, aLayers, aNet );
 
 1331        range   = 
m_joints.equal_range( tag );
 
 1333        if( range.first == 
m_joints.end() )
 
 1336        for( f = range.first; f != range.second; ++f )
 
 1338            if( aLayers.
Overlaps( f->second.Layers() ) )
 
 1340                jt.
Merge( f->second );
 
 
 1354    wxLogTrace( wxT( 
"PNS" ), wxT( 
"joint layers %d-%d, net %d, pos %s, links: %d" ),
 
 1358                m_tag.pos.Format().c_str(),
 
 
 1385    std::unordered_set<SEGMENT*> all_segs;
 
 1388    for( i = m_items.begin(); i != m_items.end(); i++ )
 
 1391            all_segs.insert( 
static_cast<SEGMENT*
>( *i ) );
 
 1396        for( i = 
m_root->m_items.begin(); i != 
m_root->m_items.end(); i++ )
 
 1399                all_segs.insert( 
static_cast<SEGMENT*
>(*i) );
 
 1403    JOINT_MAP::iterator j;
 
 1409            wxLogTrace( wxT( 
"PNS" ), wxT( 
"joint : %s, links : %d\n" ),
 
 1410                        j->second.GetPos().Format().c_str(), j->second.LinkCount() );
 
 1411            JOINT::LINKED_ITEMS::const_iterator k;
 
 1413            for( k = j->second.GetLinkList().begin(); k != j->second.GetLinkList().end(); ++k )
 
 1415                const ITEM* m_item = *k;
 
 1417                switch( m_item->GetKind() )
 
 1422                        wxLogTrace( wxT( 
"PNS" ), wxT( 
" -> seg %s %s\n" ),
 
 1423                                    seg->GetSeg().A.
Format().c_str(),
 
 1424                                    seg->GetSeg().B.
Format().c_str() );
 
 1435    int lines_count = 0;
 
 1437    while( !all_segs.empty() )
 
 1439        SEGMENT* s = *all_segs.begin();
 
 1442        LINE::LinkedSegments* seg_refs = l->GetLinkedSegments();
 
 1446            wxLogTrace( wxT( 
"PNS" ), wxT( 
"Line: %s, net %d " ),
 
 1447                        l->GetLine().
Format().c_str(), l->GetNet() );
 
 1450        for( std::vector<SEGMENT*>::iterator j = seg_refs->begin(); j != seg_refs->end(); ++j )
 
 1452            wxLogTrace( wxT( 
"PNS" ), wxT( 
"%s " ), (*j)->GetSeg().A.Format().c_str() );
 
 1454            if( j + 1 == seg_refs->end() )
 
 1455                wxLogTrace( wxT( 
"PNS" ), wxT( 
"%s\n" ), (*j)->GetSeg().B.Format().c_str() );
 
 1457            all_segs.erase( *j );
 
 1463    wxLogTrace( wxT( 
"PNS" ), wxT( 
"Local joints: %d, lines : %d \n" ),
 
 
 1478        aAdded.reserve( 
m_index->Size() );
 
 1481        aRemoved.push_back( item );
 
 1484        aAdded.push_back( item );
 
 
 1493    for( 
NODE* node : kids )
 
 1495        node->releaseChildren();
 
 
 1506    std::vector<const ITEM*> cacheCheckItems;
 
 1511        if( !item->BelongsTo( 
this ) )
 
 
 1561        for( 
ITEM* item : *l_cur )
 
 1563            if( item->OfKind( aKindMask ) && item->IsRoutable() )
 
 1564                aItems.insert( item );
 
 1574            for( 
ITEM* item : *l_root )
 
 1576                if( !
Overrides( item ) && item->OfKind( aKindMask ) && item->IsRoutable() )
 
 1577                    aItems.insert( item );
 
 
 1588        item->SetRank( -1 );
 
 1589        item->Mark( item->Marker() & ~aMarkerMask );
 
 
 1596    std::vector<ITEM*> garbage;
 
 1600        if( item->Marker() & aMarker )
 
 1601            garbage.emplace_back( item );
 
 1604    for( 
ITEM* item : garbage )
 
 
 1627                    && ( ( 
A == a2 && 
B == b2 ) || ( 
A == b2 && 
B == a2 ) ) )
 
 
 1656            ARC* seg2 = 
static_cast<ARC*
>( item );
 
 1662                    && ( ( 
A == a2 && 
B == b2 ) || ( 
A == b2 && 
B == a2 ) ) )
 
 
 1686    for( JOINT_MAP::value_type& j : 
m_joints )
 
 1688        if( !j.second.Layers().Overlaps( aLayerMask ) )
 
 1691        if( aBox.
Contains( j.second.Pos() ) && j.second.LinkCount( aKindMask ) )
 
 1693            aJoints.push_back( &j.second );
 
 1701    for( JOINT_MAP::value_type& j : 
m_root->m_joints )
 
 1703        if( !
Overrides( &j.second ) && j.second.Layers().Overlaps( aLayerMask ) )
 
 1705            if( aBox.
Contains( j.second.Pos() ) && j.second.LinkCount( aKindMask ) )
 
 1707                aJoints.push_back( &j.second );
 
 
 1726            for( 
ITEM* item : *l_cur )
 
 1728                if( item->Parent() == aParent )
 
 
 1740    std::vector<ITEM*> ret;
 
 1744        if( item->Parent() == aParent )
 
 1745            ret.push_back( item );
 
 
 1763            if( item->Net() == handle.
net && item->Layers().Overlaps(handle.
layers) )
 
 1764                return static_cast<VIA*
>( item );
 
 
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
 
NETINFO_ITEM * GetNet() const
Return #NET_INFO object for a given item.
 
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
 
virtual bool IsConnected() const
Returns information if the object is derived from BOARD_CONNECTED_ITEM.
 
constexpr coord_type GetLeft() const
 
constexpr bool Contains(const Vec &aPoint) const
 
constexpr coord_type GetRight() const
 
constexpr coord_type GetTop() const
 
constexpr coord_type GetBottom() const
 
@ ROUNDED_90
H/V with filleted corners.
 
@ MITERED_90
H/V only (90-degree corners)
 
virtual VECTOR2I Anchor(int n) const override
 
const SHAPE * Shape(int aLayer) const override
Return the geometrical shape of the item.
 
ITEM * ParentPadVia() const override
 
std::list< ITEM * > NET_ITEMS_LIST
 
int Size() const
Returns number of items stored in the index.
 
void Add(ITEM *aItem)
Adds item to the spatial index.
 
void Add(const LINE &aLine)
 
std::vector< ITEM * > & Items()
 
const std::vector< ITEM * > & CItems() const
 
Base class for PNS router board items.
 
void SetLayers(const PNS_LAYER_RANGE &aLayers)
 
virtual const std::string Format() const
 
virtual void Unmark(int aMarker=-1) const
 
virtual const SHAPE * Shape(int aLayer) const
Return the geometrical shape of the item.
 
void SetSourceItem(BOARD_ITEM *aSourceItem)
 
const PNS_LAYER_RANGE & Layers() const
 
virtual NET_HANDLE Net() const
 
PnsKind Kind() const
Return the type (kind) of the item.
 
void SetNet(NET_HANDLE aNet)
 
BOARD_ITEM * GetSourceItem() const
 
virtual void SetRank(int aRank)
 
virtual int Layer() const
 
void SetParent(BOARD_ITEM *aParent)
 
bool Collide(const ITEM *aHead, const NODE *aNode, int aLayer, COLLISION_SEARCH_CONTEXT *aCtx=nullptr) const
Check for a collision (clearance violation) with between us and item aOther.
 
bool OfKind(int aKindMask) const
 
virtual VECTOR2I Anchor(int n) const
 
bool LayersOverlap(const ITEM *aOther) const
Return true if the set of layers spanned by aOther overlaps our layers.
 
virtual HOLE * Hole() const
 
virtual bool HasHole() const
 
A 2D point on a given set of layers and belonging to a certain net, that links together a number of b...
 
const std::vector< ITEM * > & LinkList() const
 
NET_HANDLE Net() const override
 
int LinkCount(int aMask=-1) const
 
void Lock(bool aLock=true)
 
void Link(ITEM *aItem)
Unlink a given board item from the joint (upon its removal from a NODE)
 
LINKED_ITEM * NextSegment(LINKED_ITEM *aCurrent, bool aAllowLockedSegs=false) const
 
HASH_TAG m_tag
< hash tag for unordered_multimap
 
void Merge(const JOINT &aJoint)
 
bool Unlink(ITEM *aItem)
For trivial joints, return the segment adjacent to (aCurrent).
 
const VECTOR2I & Pos() const
 
Represents a track on a PCB, connecting two non-trivial joints (that is, vias, pads,...
 
void ClipVertexRange(int aStart, int aEnd)
Return the number of corners of angles specified by mask aAngles.
 
const VECTOR2I & CPoint(int aIdx) const
 
const SHAPE_LINE_CHAIN & CLine() const
 
const VECTOR2I & CLastPoint() const
 
SHAPE_LINE_CHAIN & Line()
 
void SetWidth(int aWidth)
Return line width.
 
int Width() const
Return true if the line is geometrically identical as line aOther.
 
virtual int Width() const
 
void Link(LINKED_ITEM *aLink)
 
bool IsLinked() const
Check if the segment aLink is a part of the line.
 
bool ContainsLink(const LINKED_ITEM *aItem) const
 
std::vector< LINKED_ITEM * > & Links()
 
virtual void ClearLinks()
Return the number of segments that were assembled together to form this line.
 
Keep the router "world" - i.e.
 
NODE * Branch()
Create a lightweight copy (called branch) of self that tracks the changes (added/removed items) wrs t...
 
void RemoveByMarker(int aMarker)
 
NODE * m_root
root node of the whole hierarchy
 
int FindLinesBetweenJoints(const JOINT &aA, const JOINT &aB, std::vector< LINE > &aLines)
Find the joints corresponding to the ends of line aLine.
 
std::vector< ITEM * > ITEM_VECTOR
 
int GetClearance(const ITEM *aA, const ITEM *aB, bool aUseClearanceEpsilon=true) const
Return the pre-set worst case clearance between any pair of items.
 
void followLine(LINKED_ITEM *aCurrent, bool aScanDirection, int &aPos, int aLimit, VECTOR2I *aCorners, LINKED_ITEM **aSegments, bool *aArcReversed, bool &aGuardHit, bool aStopAtLockedJoints, bool aFollowLockedSegments)
 
void addSolid(SOLID *aSeg)
 
void Replace(ITEM *aOldItem, std::unique_ptr< ITEM > aNewItem)
Replace an item with another one.
 
bool Overrides(ITEM *aItem) const
 
void removeSegmentIndex(SEGMENT *aSeg)
 
void rebuildJoint(const JOINT *aJoint, const ITEM *aItem)
 
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.
 
void addSegment(SEGMENT *aSeg)
 
std::vector< std::unique_ptr< SHAPE > > m_edgeExclusions
 
ARC * findRedundantArc(const VECTOR2I &A, const VECTOR2I &B, const PNS_LAYER_RANGE &lr, NET_HANDLE aNet)
 
JOINT_MAP::value_type TagJointPair
 
bool QueryEdgeExclusions(const VECTOR2I &aPos) const
 
void doRemove(ITEM *aItem)
 
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.
 
const JOINT * FindJoint(const VECTOR2I &aPos, int aLayer, NET_HANDLE aNet) const
Search for a joint at a given position, layer and belonging to given net.
 
void addHole(HOLE *aHole)
 
std::optional< OBSTACLE > OPT_OBSTACLE
 
void unlinkJoint(const VECTOR2I &aPos, const PNS_LAYER_RANGE &aLayers, NET_HANDLE aNet, ITEM *aWhere)
Helpers for adding/removing items.
 
std::unordered_set< ITEM * > m_garbageItems
 
void Dump(bool aLong=false)
 
void FindLineEnds(const LINE &aLine, JOINT &aA, JOINT &aB)
Destroy all child nodes. Applicable only to the root node.
 
RULE_RESOLVER * GetRuleResolver() const
Return the number of joints.
 
JOINT & touchJoint(const VECTOR2I &aPos, const PNS_LAYER_RANGE &aLayers, NET_HANDLE aNet)
Touch a joint and links it to an m_item.
 
bool Add(std::unique_ptr< SEGMENT > aSegment, bool aAllowRedundant=false)
Add an item to the current node.
 
int QueryJoints(const BOX2I &aBox, std::vector< JOINT * > &aJoints, PNS_LAYER_RANGE aLayerMask=PNS_LAYER_RANGE::All(), int aKindMask=ITEM::ANY_T)
 
std::set< OBSTACLE > OBSTACLES
 
const LINE AssembleLine(LINKED_ITEM *aSeg, int *aOriginSegmentIndex=nullptr, bool aStopAtLockedJoints=false, bool aFollowLockedSegments=false, bool aAllowSegmentSizeMismatch=true)
Follow the joint map to assemble a line connecting two non-trivial joints starting from segment aSeg.
 
INDEX * m_index
Geometric/Net index of the items.
 
std::unordered_set< ITEM * > m_override
hash of root's items that have been changed in this node
 
void AllItemsInNet(NET_HANDLE aNet, std::set< ITEM * > &aItems, int aKindMask=-1)
 
OPT_OBSTACLE NearestObstacle(const LINE *aLine, const COLLISION_SEARCH_OPTIONS &aOpts=COLLISION_SEARCH_OPTIONS())
Follow the line in search of an obstacle that is nearest to the starting to the line's starting point...
 
void LockJoint(const VECTOR2I &aPos, const ITEM *aItem, bool aLock)
 
void removeArcIndex(ARC *aVia)
 
void AddEdgeExclusion(std::unique_ptr< SHAPE > aShape)
 
int QueryColliding(const ITEM *aItem, OBSTACLES &aObstacles, const COLLISION_SEARCH_OPTIONS &aOpts=COLLISION_SEARCH_OPTIONS()) const
Find items colliding (closer than clearance) with the item aItem.
 
int m_maxClearance
worst case item-item clearance
 
VIA * FindViaByHandle(const VIA_HANDLE &handle) const
 
void removeViaIndex(VIA *aVia)
 
void add(ITEM *aItem, bool aAllowRedundant=false)
 
void removeSolidIndex(SOLID *aSeg)
 
int m_depth
depth of the node (number of parent nodes in the inheritance chain)
 
std::set< NODE * > m_children
list of nodes branched from this one
 
ITEM * FindItemByParent(const BOARD_ITEM *aParent)
 
JOINT_MAP m_joints
hash table with the joints, linking the items.
 
std::vector< ITEM * > FindItemsByParent(const BOARD_ITEM *aParent)
 
NODE * m_parent
node this node was branched from
 
void ClearRanks(int aMarkerMask=MK_HEAD|MK_VIOLATION)
 
void Remove(ARC *aArc)
Remove an item from this branch.
 
void Commit(NODE *aNode)
Apply the changes from a given branch (aNode) to the root branch.
 
RULE_RESOLVER * m_ruleResolver
Design rules resolver.
 
~NODE()
Return the expected clearance between items a and b.
 
SEGMENT * findRedundantSegment(const VECTOR2I &A, const VECTOR2I &B, const PNS_LAYER_RANGE &lr, NET_HANDLE aNet)
 
void linkJoint(const VECTOR2I &aPos, const PNS_LAYER_RANGE &aLayers, NET_HANDLE aNet, ITEM *aWhere)
Unlink an item from a joint.
 
const ITEM_SET HitTest(const VECTOR2I &aPoint) const
Find all items that contain the point aPoint.
 
OBSTACLE_VISITOR(const ITEM *aItem)
 
const NODE * m_node
node we are searching in (either root or a branch)
 
const ITEM * m_item
the item we are looking for collisions with
 
bool visit(ITEM *aCandidate)
 
std::optional< int > m_layerContext
 
void SetWorld(const NODE *aNode, const NODE *aOverride=nullptr)
 
const NODE * m_override
node that overrides root entries
 
void SetOwner(const ITEM_OWNER *aOwner)
Set the node that owns this item.
 
bool BelongsTo(const ITEM_OWNER *aNode) const
 
const ITEM_OWNER * Owner() const
Return the owner of this item, or NULL if there's none.
 
virtual DEBUG_DECORATOR * GetDebugDecorator()=0
 
ROUTER_IFACE * GetInterface() const
 
ROUTING_SETTINGS & Settings()
 
static ROUTER * GetInstance()
 
DIRECTION_45::CORNER_MODE GetCornerMode() const
 
virtual int ClearanceEpsilon() const
 
virtual const std::string Format() const override
 
virtual bool HasHole() const override
 
virtual HOLE * Hole() const override
 
const VECTOR2I & Pos() const
 
const VECTOR2I & Pos() const
 
virtual HOLE * Hole() const override
 
virtual bool HasHole() const override
 
Represent a contiguous set of PCB layers.
 
bool Overlaps(const PNS_LAYER_RANGE &aOther) const
 
bool IsMultilayer() const
 
SHAPE_ARC Reversed() const
 
const VECTOR2I & GetP1() const
 
const VECTOR2I & GetP0() const
 
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 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 Clear()
Remove all points from the line chain.
 
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
 
int SegmentCount() const
Return the number of segments in this line chain.
 
int PathLength(const VECTOR2I &aP, int aIndex=-1) const
Compute the walk path length from the beginning of the line chain and the point aP belonging to our l...
 
const VECTOR2I & CLastPoint() const
Return the last point in the line chain.
 
void RemoveDuplicatePoints()
Remove the duplicate points from the line chain.
 
const SEG CSegment(int aIndex) const
Return a constant copy of the aIndex segment in the line chain.
 
bool IsArcSegment(size_t aSegment) const
 
int Find(const VECTOR2I &aP, int aThreshold=0) const
Search for point aP.
 
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
 
virtual bool Collide(const VECTOR2I &aP, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const
Check if the boundary of shape (this) lies closer to the point aP than aClearance,...
 
Push and Shove diff pair dimensions (gap) settings dialog.
 
void HullIntersection(const SHAPE_LINE_CHAIN &hull, const SHAPE_LINE_CHAIN &line, SHAPE_LINE_CHAIN::INTERSECTIONS &ips)
 
std::unique_ptr< T > ItemCast(std::unique_ptr< S > aPtr)
 
static std::vector< std::string > split(const std::string &aStr, const std::string &aDelim)
Split the input string into a vector of output strings.
 
std::set< OBSTACLE > & obstacles
 
bool m_useClearanceEpsilon
 
bool operator()(ITEM *aItem) override
 
HIT_VISITOR(ITEM_SET &aTab, const VECTOR2I &aPoint)
 
< Joints are hashed by their position, layers and net.
 
bool operator()(ITEM *aCandidate) override
 
COLLISION_SEARCH_CONTEXT * m_ctx
 
DEFAULT_OBSTACLE_VISITOR(COLLISION_SEARCH_CONTEXT *aCtx, const ITEM *aItem)
 
virtual ~DEFAULT_OBSTACLE_VISITOR()
 
Hold an object colliding with another object, along with some useful data about the collision.
 
int m_distFirst
... and the distance thereof
 
int m_maxFanoutWidth
worst case (largest) width of the tracks connected to the item
 
ITEM * m_head
Line we search collisions against.
 
VECTOR2I m_ipFirst
First intersection between m_head and m_hull.
 
ITEM * m_item
Item found to be colliding with m_head.
 
Represent an intersection between two line segments.
 
VECTOR2I p
Point of intersection between our and their.
 
int index_their
index of the intersecting corner/segment in the 'their' (Intersect() method parameter) line.
 
Casted dyn_cast(From aObject)
A lightweight dynamic downcast.
 
VECTOR2< int32_t > VECTOR2I