51 static std::unordered_set<NODE*> allocNodes;
64 allocNodes.insert(
this );
73 wxLogTrace( wxT(
"PNS" ), wxT(
"attempting to free a node that has kids." ) );
78 if( allocNodes.find(
this ) == allocNodes.end() )
80 wxLogTrace( wxT(
"PNS" ), wxT(
"attempting to free an already-free'd node." ) );
84 allocNodes.erase(
this );
91 if( item->BelongsTo(
this ) )
154 JOINT_MAP::iterator j;
164 wxLogTrace( wxT(
"PNS" ), wxT(
"%d items, %d joints, %d overrides" ),
186 m_override( nullptr )
220 bool aDifferentNetsOnly ) :
244 if(
visit( aCandidate ) )
255 m_tab.push_back( obs );
268 int aLimitCount,
bool aDifferentNetsOnly )
277 assert( allocNodes.find(
this ) != allocNodes.end() );
293 return aObstacles.size();
298 const std::set<ITEM*>* aRestrictedSet,
299 bool aUseClearanceEpsilon )
302 obstacleList.reserve( 100 );
313 if( obstacleList.empty() )
330 nearest.
m_item = obstacle;
333 obstacle->Mark( isHole ? obstacle->Marker() |
MK_HOLE 334 : obstacle->Marker() & ~
MK_HOLE );
340 std::vector<SHAPE_LINE_CHAIN::INTERSECTION> intersectingPts;
341 int layer = aLine->
Layer();
344 for(
const OBSTACLE& obstacle : obstacleList )
346 if( aRestrictedSet && aRestrictedSet->find( obstacle.m_item ) == aRestrictedSet->end() )
350 GetClearance( obstacle.m_item, aLine, aUseClearanceEpsilon ) + aLine->
Width() / 2;
352 obstacleHull = obstacle.m_item->Hull( clearance, 0, layer );
356 intersectingPts.clear();
359 for(
const auto& ip : intersectingPts )
363 updateNearest( ip, obstacle.m_item, obstacleHull,
false );
371 int viaHoleRadius = static_cast<const SHAPE_CIRCLE*>(
via.Hole() )->GetRadius();
373 int viaClearance =
GetClearance( obstacle.m_item, &
via, aUseClearanceEpsilon )
374 +
via.Diameter() / 2;
378 if( holeClearance > viaClearance )
379 viaClearance = holeClearance;
381 obstacleHull = obstacle.m_item->Hull( viaClearance, 0, layer );
384 intersectingPts.clear();
390 updateNearest( ip, obstacle.m_item, obstacleHull,
false );
393 if( obstacle.m_item->Hole() )
395 clearance =
GetHoleClearance( obstacle.m_item, aLine, aUseClearanceEpsilon );
396 int copperClearance =
GetClearance( obstacle.m_item, aLine, aUseClearanceEpsilon );
398 clearance = std::max( clearance, copperClearance );
400 obstacleHull = obstacle.m_item->HoleHull( clearance, aLine->
Width(), layer );
402 intersectingPts.clear();
406 updateNearest( ip, obstacle.m_item, obstacleHull,
true );
412 int viaHoleRadius = static_cast<const SHAPE_CIRCLE*>(
via.Hole() )->GetRadius();
414 int viaClearance =
GetClearance( obstacle.m_item, &
via, aUseClearanceEpsilon )
415 +
via.Diameter() / 2;
422 if( holeClearance > viaClearance )
423 viaClearance = holeClearance;
425 if( holeToHole > viaClearance )
426 viaClearance = holeToHole;
428 obstacleHull = obstacle.m_item->Hull( viaClearance, 0, layer );
431 intersectingPts.clear();
435 updateNearest( ip, obstacle.m_item, obstacleHull,
true );
441 nearest.
m_item = obstacleList[0].m_item;
472 const LINE* line = static_cast<const LINE*>( aItemA );
570 aSolid->SetOwner(
this );
585 aVia->SetOwner(
this );
596 for(
size_t i = 0; i < l.ArcCount(); i++ )
608 auto newarc = std::make_unique< ARC >( aLine, s );
609 aLine.
Link( newarc.get() );
610 Add( std::move( newarc ),
true );
614 for(
int i = 0; i < l.SegmentCount(); i++ )
616 if( l.IsArcSegment( i ) )
619 SEG s = l.CSegment( i );
633 std::unique_ptr<SEGMENT> newseg = std::make_unique<SEGMENT>( aLine, s );
634 aLine.
Link( newseg.get() );
635 Add( std::move( newseg ),
true );
651 bool NODE::Add( std::unique_ptr< SEGMENT > aSegment,
bool aAllowRedundant )
653 if( aSegment->Seg().A == aSegment->Seg().B )
655 wxLogTrace( wxT(
"PNS" ),
656 wxT(
"attempting to add a segment with same end coordinates, ignoring." ) );
663 aSegment->SetOwner(
this );
679 bool NODE::Add( std::unique_ptr< ARC > aArc,
bool aAllowRedundant )
689 aArc->SetOwner(
this );
695 void NODE::Add( std::unique_ptr< ITEM > aItem,
bool aAllowRedundant )
697 switch( aItem->Kind() )
700 case ITEM::SEGMENT_T:
Add( ItemCast<SEGMENT>( std::move( aItem ) ), aAllowRedundant );
break;
701 case ITEM::VIA_T:
Add( ItemCast<VIA>( std::move( aItem ) ) );
break;
705 Add( ItemCast<ARC>( std::move( aItem ) ) );
758 int net = aItem->
Net();
761 tag.pos = aJoint->
Pos();
768 auto range =
m_joints.equal_range( tag );
775 for(
auto f = range.first; f != range.second; ++f )
787 for(
ITEM* link : links )
790 linkJoint( tag.pos, link->Layers(), net, link );
818 Add( std::move( aNewItem ) );
859 switch( aItem->
Kind() )
862 Remove( static_cast<ARC*>( aItem ) );
866 Remove( static_cast<SOLID*>( aItem ) );
870 Remove( static_cast<SEGMENT*>( aItem ) );
875 LINE* l = static_cast<LINE*>( aItem );
884 Remove( static_cast<VIA*>( aItem ) );
896 std::vector<LINKED_ITEM*>& segRefs = aLine.
Links();
901 Remove( static_cast<SEGMENT*>( li ) );
903 Remove( static_cast<ARC*>( li ) );
913 bool& aGuardHit,
bool aStopAtLockedJoints,
bool aFollowLockedSegments )
915 bool prevReversed =
false;
919 for(
int count = 0 ; ; ++count )
921 const VECTOR2I p = aCurrent->
Anchor( aScanDirection ^ prevReversed );
926 aCorners[aPos] = jt->
Pos();
927 aSegments[aPos] = aCurrent;
928 aArcReversed[aPos] =
false;
932 if( ( aScanDirection && jt->
Pos() == aCurrent->
Anchor( 0 ) )
933 || ( !aScanDirection && jt->
Pos() == aCurrent->
Anchor( 1 ) ) )
934 aArcReversed[aPos] =
true;
937 aPos += ( aScanDirection ? 1 : -1 );
939 if( count && guard == p )
941 if( aPos >= 0 && aPos < aLimit )
942 aSegments[aPos] =
nullptr;
950 if(
locked || !jt->
IsLineCorner( aFollowLockedSegments ) || aPos < 0 || aPos == aLimit )
953 aCurrent = jt->
NextSegment( aCurrent, aFollowLockedSegments );
955 prevReversed = ( aCurrent && jt->
Pos() == aCurrent->
Anchor( aScanDirection ) );
961 bool aStopAtLockedJoints,
bool aFollowLockedSegments )
963 const int MaxVerts = 1024 * 16;
965 std::array<VECTOR2I, MaxVerts + 1> corners;
966 std::array<LINKED_ITEM*, MaxVerts + 1> segs;
967 std::array<bool, MaxVerts + 1> arcReversed;
970 bool guardHit =
false;
972 int i_start = MaxVerts / 2;
973 int i_end = i_start + 1;
980 followLine( aSeg,
false, i_start, MaxVerts, corners.data(), segs.data(), arcReversed.data(),
981 guardHit, aStopAtLockedJoints, aFollowLockedSegments );
985 followLine( aSeg,
true, i_end, MaxVerts, corners.data(), segs.data(), arcReversed.data(),
986 guardHit, aStopAtLockedJoints, aFollowLockedSegments );
992 bool originSet =
false;
996 for(
int i = i_start + 1; i < i_end; i++ )
1004 if( li && prev_seg != li )
1008 const ARC* arc = static_cast<const ARC*>( li );
1009 const SHAPE_ARC* sa = static_cast<const SHAPE_ARC*>( arc->
Shape() );
1013 ssize_t lastShape = nSegs ? line.
ArcIndex( static_cast<ssize_t>( nSegs ) - 1 ) : -1;
1021 if( li == aSeg && aOriginSegmentIndex && !originSet )
1025 *aOriginSegmentIndex = line.
PointCount() - 1;
1055 LINKED_ITEM* li = static_cast<LINKED_ITEM*>( item );
1061 JOINT j_start, j_end;
1068 if( id_end < id_start )
1069 std::swap( id_end, id_start );
1071 if( id_start >= 0 && id_end >= 0 )
1074 aLines.push_back( line );
1085 SEGMENT* locked_seg =
nullptr;
1086 std::vector<VVIA*> vvias;
1090 JOINT joint = jointPair.second;
1095 int n_seg = 0, n_solid = 0, n_vias = 0;
1098 bool is_width_change =
false;
1099 bool is_locked =
false;
1101 for(
const auto& lnk : joint.
LinkList() )
1111 else if(
const auto t = dyn_cast<PNS::SEGMENT*>( lnk.item ) )
1115 if( prev_w >= 0 && w != prev_w )
1117 is_width_change =
true;
1120 max_w = std::max( w, max_w );
1123 is_locked = t->IsLocked();
1128 if( ( is_width_change || n_seg >= 3 || is_locked ) && n_solid == 0 && n_vias == 0 )
1139 locked_seg->
Seg().
B :
1140 locked_seg->
Seg().
A;
1147 for(
auto vvia : vvias )
1149 Add( ItemCast<VIA>( std::move( std::unique_ptr<VVIA>( vvia ) ) ) );
1163 if( f == end && !
isRoot() )
1174 if( f->second.Layers().Overlaps( aLayer ) )
1199 JOINT_MAP::iterator f =
m_joints.find( tag );
1201 std::pair<JOINT_MAP::iterator, JOINT_MAP::iterator> range;
1208 for( f = range.first; f != range.second; ++f )
1213 JOINT jt( aPos, aLayers, aNet );
1220 range =
m_joints.equal_range( tag );
1222 if( range.first ==
m_joints.end() )
1225 for( f = range.first; f != range.second; ++f )
1227 if( aLayers.
Overlaps( f->second.Layers() ) )
1229 jt.
Merge( f->second );
1244 wxLogTrace( wxT(
"PNS" ), wxT(
"joint layers %d-%d, net %d, pos %s, links: %d" ),
1273 std::unordered_set<SEGMENT*> all_segs;
1276 for( i = m_items.begin(); i != m_items.end(); i++ )
1279 all_segs.insert( static_cast<SEGMENT*>( *i ) );
1284 for( i =
m_root->m_items.begin(); i !=
m_root->m_items.end(); i++ )
1287 all_segs.insert( static_cast<SEGMENT*>(*i) );
1291 JOINT_MAP::iterator j;
1297 wxLogTrace( wxT(
"PNS" ), wxT(
"joint : %s, links : %d\n" ),
1298 j->second.GetPos().Format().c_str(), j->second.LinkCount() );
1299 JOINT::LINKED_ITEMS::const_iterator k;
1301 for( k = j->second.GetLinkList().begin(); k != j->second.GetLinkList().end(); ++k )
1303 const ITEM* m_item = *k;
1305 switch( m_item->GetKind() )
1309 const SEGMENT* seg = static_cast<const SEGMENT*>( m_item );
1310 wxLogTrace( wxT(
"PNS" ), wxT(
" -> seg %s %s\n" ),
1311 seg->GetSeg().A.Format().c_str(),
1312 seg->GetSeg().B.Format().c_str() );
1323 int lines_count = 0;
1325 while( !all_segs.empty() )
1327 SEGMENT* s = *all_segs.begin();
1330 LINE::LinkedSegments* seg_refs = l->GetLinkedSegments();
1334 wxLogTrace( wxT(
"PNS" ), wxT(
"Line: %s, net %d " ),
1335 l->GetLine().Format().c_str(), l->GetNet() );
1338 for( std::vector<SEGMENT*>::iterator j = seg_refs->begin(); j != seg_refs->end(); ++j )
1340 wxLogTrace( wxT(
"PNS" ), wxT(
"%s " ), (*j)->GetSeg().A.Format().c_str() );
1342 if( j + 1 == seg_refs->end() )
1343 wxLogTrace( wxT(
"PNS" ), wxT(
"%s\n" ), (*j)->GetSeg().B.Format().c_str() );
1345 all_segs.erase( *j );
1351 wxLogTrace( wxT(
"PNS" ), wxT(
"Local joints: %d, lines : %d \n" ),
1369 aRemoved.push_back( item );
1372 aAdded.push_back( *i );
1381 for(
NODE* node : kids )
1383 node->releaseChildren();
1396 if( !item->BelongsTo(
this ) )
1416 Add( std::unique_ptr<ITEM>( item ) );
1436 for(
ITEM* item : *l_cur )
1438 if( item->OfKind( aKindMask ) && item->IsRoutable() )
1439 aItems.insert( item );
1449 for(
ITEM* item : *l_root )
1451 if( !
Overrides( item ) && item->OfKind( aKindMask ) && item->IsRoutable() )
1452 aItems.insert( item );
1463 item->SetRank( -1 );
1464 item->Mark( item->Marker() & ~aMarkerMask );
1471 std::vector<ITEM*> garbage;
1475 if( item->Marker() & aMarker )
1476 garbage.emplace_back( item );
1479 for(
ITEM* item : garbage )
1502 && ( (
A == a2 &&
B == b2 ) || (
A == b2 &&
B == a2 ) ) )
1531 ARC* seg2 = static_cast<ARC*>( item );
1537 && ( (
A == a2 &&
B == b2 ) || (
A == b2 &&
B == a2 ) ) )
1561 for( JOINT_MAP::value_type& j :
m_joints )
1563 if( !j.second.Layers().Overlaps( aLayerMask ) )
1566 if( aBox.
Contains( j.second.Pos() ) && j.second.LinkCount( aKindMask ) )
1568 aJoints.push_back( &j.second );
1578 if( !
Overrides( &j.second ) && j.second.Layers().Overlaps( aLayerMask ) )
1580 if( aBox.
Contains( j.second.Pos() ) && j.second.LinkCount( aKindMask ) )
1582 aJoints.push_back( &j.second );
1602 for(
ITEM* item : *l_cur )
1604 if( item->Parent() == aParent )
void ClearRanks(int aMarkerMask=MK_HEAD|MK_VIOLATION|MK_HOLE)
Represent an intersection between two line segments.
const SHAPE_LINE_CHAIN & CLine() const
Base class for PNS router board items.
int Query(const ITEM *aItem, int aMinDistance, Visitor &aVisitor) const
Searches items in the index that are in proximity of aItem.
void HullIntersection(const SHAPE_LINE_CHAIN &hull, const SHAPE_LINE_CHAIN &line, SHAPE_LINE_CHAIN::INTERSECTIONS &ips)
std::list< ITEM * > NET_ITEMS_LIST
std::set< NODE * > m_children
list of nodes branched from this one
ITEM * m_item
Item found to be colliding with m_head.
const SHAPE_ARC & Arc(size_t aArc) const
DEFAULT_OBSTACLE_VISITOR(NODE::OBSTACLES &aTab, const ITEM *aItem, int aKindMask, bool aDifferentNetsOnly)
const NODE * m_node
node we are searching in (either root or a branch)
void SetOwner(NODE *aOwner)
Set the node that owns this item.
virtual int Layer() const
Keep the router "world" - i.e.
int GetHoleToHoleClearance(const ITEM *aA, const ITEM *aB, bool aUseClearanceEpsilon=true) const
Return the pre-set worst case clearance between any pair of items.
int GetClearance(const ITEM *aA, const ITEM *aB, bool aUseClearanceEpsilon=true) const
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
void SetCountLimit(int aLimit)
bool IsMultilayer() const
SHAPE_LINE_CHAIN & Simplify(bool aRemoveColinear=true)
Simplify the line chain by removing colinear adjacent segments and duplicate vertices.
bool Unlink(ITEM *aItem)
For trivial joints, return the segment adjacent to (aCurrent).
VECTOR2I p
< Point of intersection between our and their.
int m_distFirst
... and the distance thereof
void FindLineEnds(const LINE &aLine, JOINT &aA, JOINT &aB)
Destroy all child nodes. Applicable only to the root node.
void doRemove(ITEM *aItem)
void removeSegmentIndex(SEGMENT *aSeg)
bool Overlaps(const LAYER_RANGE &aOther) const
int FindLinesBetweenJoints(const JOINT &aA, const JOINT &aB, std::vector< LINE > &aLines)
Find the joints corresponding to the ends of line aLine.
void Link(LINKED_ITEM *aLink)
Return the list of links from the owning node that constitute this line (or NULL if the line is not l...
bool IsLineCorner(bool aAllowLockedSegs=false) const
Checks if a joint connects two segments of the same net, layer, and width.
void Lock(bool aLock=true)
virtual int Clearance(const ITEM *aA, const ITEM *aB, bool aUseClearanceEpsilon=true)=0
Represents a track on a PCB, connecting two non-trivial joints (that is, vias, pads,...
virtual void Unmark(int aMarker=-1) const
bool Overrides(ITEM *aItem) const
void linkJoint(const VECTOR2I &aPos, const LAYER_RANGE &aLayers, int aNet, ITEM *aWhere)
Unlink an item from a joint.
int PointCount() const
Return the number of points (vertices) in this line chain.
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
void Add(const LINE &aLine)
void Commit(NODE *aNode)
Apply the changes from a given branch (aNode) to the root branch.
NODE * Branch()
Create a lightweight copy (called branch) of self that tracks the changes (added/removed items) wrs t...
const VECTOR2I & Pos() const
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,...
int GetHoleClearance(const ITEM *aA, const ITEM *aB, bool aUseClearanceEpsilon=true) const
void unlinkJoint(const VECTOR2I &aPos, const LAYER_RANGE &aLayers, int aNet, ITEM *aWhere)
Helpers for adding/removing items.
bool operator()(ITEM *aItem) override
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
INDEX * m_index
Geometric/Net index of the items.
void Remove(ARC *aArc)
Remove an item from this branch.
void SetWidth(int aWidth)
Return line width.
bool LayersOverlap(const ITEM *aOther) const
Return true if the set of layers spanned by aOther overlaps our layers.
const VECTOR2I & CPoint(int aIdx) const
virtual int Width() const
ssize_t ArcIndex(size_t aSegment) const
Return the arc index for the given segment index.
void addSegment(SEGMENT *aSeg)
NODE * m_root
root node of the whole hierarchy
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
int m_depth
depth of the node (number of parent nodes in the inheritance chain)
A 2D point on a given set of layers and belonging to a certain net, that links together a number of b...
RULE_RESOLVER * m_ruleResolver
Design rules resolver.
void addSolid(SOLID *aSeg)
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...
bool BelongsTo(NODE *aNode) const
void rebuildJoint(JOINT *aJoint, ITEM *aItem)
void followLine(LINKED_ITEM *aCurrent, bool aScanDirection, int &aPos, int aLimit, VECTOR2I *aCorners, LINKED_ITEM **aSegments, bool *aArcReversed, bool &aGuardHit, bool aStopAtLockedJoints, bool aFollowLockedSegments)
ITEM * FindItemByParent(const BOARD_ITEM *aParent)
int Find(const VECTOR2I &aP, int aThreshold=0) const
Search for point aP.
virtual const SHAPE * Shape() const
Return the geometrical shape of the item.
HIT_VISITOR(ITEM_SET &aTab, const VECTOR2I &aPoint)
SEGMENT * findRedundantSegment(const VECTOR2I &A, const VECTOR2I &B, const LAYER_RANGE &lr, int aNet)
bool IsLinked() const
Check if the segment aLink is a part of the line.
const VECTOR2I & GetP0() const
bool Contains(const Vec &aPoint) const
const std::string Format() const
Return the vector formatted as a string.
OBSTACLE_VISITOR(const ITEM *aItem)
void ClipVertexRange(int aStart, int aEnd)
Return the number of corners of angles specified by mask aAngles.
bool operator()(ITEM *aCandidate) override
bool visit(ITEM *aCandidate)
bool Collide(const ITEM *aOther, const NODE *aNode, bool aDifferentNetsOnly=true) const
Check for a collision (clearance violation) with between us and item aOther.
std::unordered_set< ITEM * > m_override
hash of root's items that have been changed in this node
int QueryJoints(const BOX2I &aBox, std::vector< JOINT * > &aJoints, LAYER_RANGE aLayerMask=LAYER_RANGE::All(), int aKindMask=ITEM::ANY_T)
int m_kindMask
(solids, vias, segments, etc...)
const ITEM * m_item
the item we are looking for collisions with
ITEM_SET::ENTRIES LINKED_ITEMS
Joints are hashed by their position, layers and net.
void SetWorld(const NODE *aNode, const NODE *aOverride=nullptr)
virtual void SetRank(int aRank)
const LINKED_ITEMS & LinkList() const
~NODE()
Return the expected clearance between items a and b.
int SegmentCount() const
Return the number of segments in this line chain.
ARC * findRedundantArc(const VECTOR2I &A, const VECTOR2I &B, const LAYER_RANGE &lr, int aNet)
const ITEM_SET HitTest(const VECTOR2I &aPoint) const
Find all items that contain the point aPoint.
void SetLayers(const LAYER_RANGE &aLayers)
int QueryColliding(const ITEM *aItem, OBSTACLES &aObstacles, int aKindMask=ITEM::ANY_T, int aLimitCount=-1, bool aDifferentNetsOnly=true)
Find items colliding (closer than clearance) with the item aItem.
SHAPE_LINE_CHAIN m_hull
Hull of the colliding m_item.
JOINT * FindJoint(const VECTOR2I &aPos, int aLayer, int aNet)
Search for a joint at a given position, layer and belonging to given net.
SHAPE_LINE_CHAIN & Line()
NET_ITEMS_LIST * GetItemsForNet(int aNet)
Returns list of all items in a given net.
const VECTOR2I & Pos() const
void Replace(ITEM *aOldItem, std::unique_ptr< ITEM > aNewItem)
Replace an item with another one.
virtual VECTOR2I Anchor(int n) const
void RemoveByMarker(int aMarker)
virtual DEBUG_DECORATOR * GetDebugDecorator()=0
const SHAPE * Shape() const override
Return the geometrical shape of the item.
void removeSolidIndex(SOLID *aSeg)
JOINT_MAP::value_type TagJointPair
ITEM_SET::iterator begin()
int index_their
When true, the corner [index_our] of the 'our' line lies exactly on 'their' line.
void Dump(bool aLong=false)
const SEG CSegment(int aIndex) const
Return a constant copy of the aIndex segment in the line chain.
int Size() const
Returns number of items stored in the index.
virtual void ClearLinks()
Return the number of segments that were assembled together to form this line.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void AllItemsInNet(int aNet, std::set< ITEM * > &aItems, int aKindMask=-1)
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.
HASH_TAG m_tag
< hash tag for unordered_multimap
JOINT & touchJoint(const VECTOR2I &aPos, const LAYER_RANGE &aLayers, int aNet)
Touch a joint and links it to an m_item.
bool OfKind(int aKindMask) const
Return true if the item's type matches the mask aKindMask.
std::unordered_set< ITEM * > m_garbageItems
void Add(ITEM *aItem)
Adds item to the spatial index.
const ENTRIES & CItems() const
void removeViaIndex(VIA *aVia)
int Width() const
Return true if the line is geometrically identical as line aOther.
const ITEM * m_head
Item we search collisions with.
void Merge(const JOINT &aJoint)
virtual ~DEFAULT_OBSTACLE_VISITOR()
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 removeArcIndex(ARC *aVia)
PnsKind Kind() const
Return the type (kind) of the item.
OPT< OBSTACLE > OPT_OBSTACLE
virtual bool IsConnected() const
Returns information if the object is derived from BOARD_CONNECTED_ITEM.
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.
SHAPE_ARC Reversed() const
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...
int LinkCount(int aMask=-1) const
const VECTOR2I & Pos() const
int m_maxClearance
worst case item-item clearance
LINKED_ITEM * NextSegment(ITEM *aCurrent, bool aAllowLockedSegs=false) const
void Link(ITEM *aItem)
Unlink a given board item from the joint (upon its removal from a NODE)
JOINT_MAP m_joints
hash table with the joints, linking the items.
VECTOR2I m_ipFirst
First intersection between m_head and m_hull.
std::vector< OBSTACLE > OBSTACLES
const NODE * m_override
node that overrides root entries
Push and Shove diff pair dimensions (gap) settings dialog.
virtual VECTOR2I Anchor(int n) const override
NODE * m_parent
node this node was branched from
void Remove(ITEM *aItem)
Removes an item from the spatial index.
virtual int HoleToHoleClearance(const ITEM *aA, const ITEM *aB, bool aUseClearanceEpsilon=true)=0
virtual int HoleClearance(const ITEM *aA, const ITEM *aB, bool aUseClearanceEpsilon=true)=0
bool Add(std::unique_ptr< SEGMENT > aSegment, bool aAllowRedundant=false)
Add an item to the current node.
const VECTOR2I & GetP1() const
ROUTER_IFACE * GetInterface() const
static ROUTER * GetInstance()
Represent a contiguous set of PCB layers.
const LAYER_RANGE & Layers() const
void LockJoint(const VECTOR2I &aPos, const ITEM *aItem, bool aLock)
std::vector< ITEM * > ITEM_VECTOR
Hold an object colliding with another object, along with some useful data about the collision.
static std::vector< std::string > split(const std::string &aStr, const std::string &aDelim)
Split the input string into a vector of output strings.