54static std::unordered_set<const NODE*> allocNodes;
67 allocNodes.insert(
this );
76 wxLogTrace( wxT(
"PNS" ), wxT(
"attempting to free a node that has kids." ) );
81 if( allocNodes.find(
this ) == allocNodes.end() )
83 wxLogTrace( wxT(
"PNS" ), wxT(
"attempting to free an already-free'd node." ) );
87 allocNodes.erase(
this );
92 std::vector<const ITEM*> toDelete;
94 toDelete.reserve(
m_index->Size() );
98 if( item->BelongsTo(
this ) )
102 HOLE* hole =
static_cast<HOLE*
>( item );
115 toDelete.push_back(item);
120 toDelete.push_back(item);
130 for(
const ITEM* item : toDelete )
132 wxLogTrace( wxT(
"PNS" ), wxT(
"del item %p type %s" ), item, item->KindStr().c_str() );
151 int cl =
m_ruleResolver->Clearance( aA, aB, aUseClearanceEpsilon );
181 wxLogTrace( wxT(
"PNS" ), wxT(
"%d items, %d joints, %d overrides" ),
243 if( !aCandidate->
OfKind(
m_ctx->options.m_kindMask ) )
247 if(
m_item == aCandidate )
250 if(
m_ctx->options.m_filter && !
m_ctx->options.m_filter( aCandidate ) )
253 if(
visit( aCandidate ) )
259 if(
m_ctx->options.m_limitCount > 0 && (
int)
m_ctx->obstacles.size() >=
m_ctx->options.m_limitCount )
279 assert( allocNodes.find(
this ) != allocNodes.end() );
294 return aObstacles.size();
304 for(
int i = 0; i < aLine->
CLine().SegmentCount(); i++ )
317 if( obstacleSet.empty() )
321 std::vector<OBSTACLE> obstacles( obstacleSet.begin(), obstacleSet.end() );
322 const int numObstacles = (int) obstacles.size();
324 const int layer = aLine->
Layer();
334 BOX2I bbox = cachedHull.BBox();
349 struct ObstacleHullData
355 std::vector<ObstacleHullData> hullData( numObstacles );
357 for(
int i = 0; i < numObstacles; i++ )
359 const OBSTACLE& obstacle = obstacles[i];
362 + aLine->
Width() / 2;
371 +
via.Diameter( aLine->
Layer() ) / 2;
373 hullData[i].viaHull = makeHull( ruleResolver->
HullCache( obstacle.
m_item,
374 viaClearance, 0, layer ) );
379 struct ObstacleResult
385 std::vector<ObstacleResult> results( numObstacles );
388 auto processObstacle = [&](
int i )
390 std::vector<SHAPE_LINE_CHAIN::INTERSECTION> ips;
391 ObstacleResult&
result = results[i];
400 int dist = linePath.
PathLength( ip.p, ip.index_their );
419 int dist = linePath.
PathLength( ip.p, ip.index_their );
434 constexpr int MIN_OBSTACLES_PER_BLOCK = 8;
435 constexpr int PARALLEL_THRESHOLD = MIN_OBSTACLES_PER_BLOCK;
437 if( numObstacles > PARALLEL_THRESHOLD )
440 std::size_t numBlocks = std::max<std::size_t>( 1, numObstacles / MIN_OBSTACLES_PER_BLOCK );
442 auto futures =
tp.submit_loop( 0, numObstacles, [&](
int i ) { processObstacle( i ); },
448 for(
int i = 0; i < numObstacles; i++ )
449 processObstacle( i );
458 for(
int i = 0; i < numObstacles; i++ )
462 nearest = obstacles[i];
466 if( results[i].dist == 0 )
472 nearest = obstacles[0];
509 const LINE* line =
static_cast<const LINE*
>( aItemA );
619 aSolid->SetOwner(
this );
660 switch( aItem->
Kind() )
689 for(
size_t i = 0; i < l.
ArcCount(); i++ )
701 auto newarc = std::make_unique< ARC >( aLine, s );
702 aLine.
Link( newarc.get() );
703 Add( std::move( newarc ),
true );
727 std::unique_ptr<SEGMENT> newseg = std::make_unique<SEGMENT>( aLine, s );
728 aLine.
Link( newseg.get() );
729 Add( std::move( newseg ),
true );
747bool NODE::Add( std::unique_ptr< SEGMENT > aSegment,
bool aAllowRedundant )
749 if( aSegment->Seg().A == aSegment->Seg().B )
751 wxLogTrace( wxT(
"PNS" ),
752 wxT(
"attempting to add a segment with same end coordinates, ignoring." ) );
776bool NODE::Add( std::unique_ptr< ARC > aArc,
bool aAllowRedundant )
801 if( edgeExclusion->Collide( aPos ) )
811 bool holeRemoved =
false;
840 m_root->m_garbageItems.insert( aItem );
879 std::vector<ITEM*> links( aJoint->
LinkList() );
891 auto range =
m_joints.equal_range( tag );
898 for(
auto f = range.first; f != range.second; ++f )
909 bool completelyErased =
false;
916 completelyErased =
true;
921 for(
ITEM* link : links )
925 else if( !completelyErased )
954 add( aNewItem.release() );
961 Add( aNewLine, aAllowRedundantSegments );
1000 switch( aItem->
Kind() )
1026 LINE* l =
static_cast<LINE*
>( aItem );
1038 if(
via->HasHole() )
1041 via->Hole()->SetOwner(
via );
1057 std::vector<LINKED_ITEM*>& segRefs = aLine.
Links();
1076 bool& aGuardHit,
bool aStopAtLockedJoints,
bool aFollowLockedSegments )
1078 bool prevReversed =
false;
1082 for(
int count = 0 ; ; ++count )
1084 const VECTOR2I p = aCurrent->
Anchor( aScanDirection ^ prevReversed );
1090 aCorners[aPos] = jt->
Pos();
1091 aSegments[aPos] = aCurrent;
1092 aArcReversed[aPos] =
false;
1096 if( ( aScanDirection && jt->
Pos() == aCurrent->
Anchor( 0 ) )
1097 || ( !aScanDirection && jt->
Pos() == aCurrent->
Anchor( 1 ) ) )
1099 aArcReversed[aPos] =
true;
1103 aPos += ( aScanDirection ? 1 : -1 );
1105 if( count && guard == p )
1107 if( aPos >= 0 && aPos < aLimit )
1108 aSegments[aPos] =
nullptr;
1116 if(
locked || aPos < 0 || aPos == aLimit )
1119 aCurrent = jt->
NextSegment( aCurrent, aFollowLockedSegments );
1124 prevReversed = ( aCurrent && jt->
Pos() == aCurrent->
Anchor( aScanDirection ) );
1130 bool aFollowLockedSegments,
bool aAllowSegmentSizeMismatch )
1132 const int MaxVerts = 1024 * 16;
1134 std::array<VECTOR2I, MaxVerts + 1> corners;
1135 std::array<LINKED_ITEM*, MaxVerts + 1> segs;
1136 std::array<bool, MaxVerts + 1> arcReversed;
1139 bool guardHit =
false;
1141 int i_start = MaxVerts / 2;
1142 int i_end = i_start + 1;
1151 followLine( aSeg,
false, i_start, MaxVerts, corners.data(), segs.data(), arcReversed.data(),
1152 guardHit, aStopAtLockedJoints, aFollowLockedSegments );
1156 followLine( aSeg,
true, i_end, MaxVerts, corners.data(), segs.data(), arcReversed.data(),
1157 guardHit, aStopAtLockedJoints, aFollowLockedSegments );
1163 bool originSet =
false;
1167 for(
int i = i_start + 1; i < i_end; i++ )
1172 if( !aAllowSegmentSizeMismatch && ( li && li->
Width() != aSeg->
Width() ) )
1178 if( li && prev_seg != li )
1182 const ARC* arc =
static_cast<const ARC*
>( li );
1191 if( li == aSeg && aOriginSegmentIndex && !originSet )
1195 *aOriginSegmentIndex = line.
PointCount() - 1;
1207 if( aOriginSegmentIndex && *aOriginSegmentIndex >= pl.
SegmentCount() )
1210 wxASSERT_MSG( pl.
SegmentCount() != 0,
"assembled line should never be empty" );
1235 JOINT j_start, j_end;
1242 if( id_end < id_start )
1243 std::swap( id_end, id_start );
1245 if( id_start >= 0 && id_end >= 0 )
1248 aLines.push_back( line );
1265 m_index->SetDeferred(
false );
1272 const SEGMENT* locked_seg =
nullptr;
1273 std::vector<VVIA*> vvias;
1277 JOINT joint = jointPair.second;
1286 bool prev_mask =
false;
1287 std::optional<int> prev_mask_margin;
1289 bool is_width_change =
false;
1290 bool is_locked =
false;
1306 std::optional<int> mask_margin;
1310 mask = track->HasSolderMask();
1311 mask_margin = track->GetLocalSolderMaskMargin();
1318 prev_mask_margin = mask_margin;
1320 else if( w != prev_w || mask != prev_mask || mask_margin != prev_mask_margin )
1322 is_width_change =
true;
1325 max_w = std::max( w, max_w );
1328 is_locked = t->IsLocked();
1333 if( ( is_width_change || n_seg >= 3 || is_locked ) && n_solid == 0 && n_vias == 0 )
1344 locked_seg->
Seg().
B :
1345 locked_seg->
Seg().
A;
1352 for(
auto vvia : vvias )
1371 f =
m_root->m_joints.find( tag );
1376 if( f->second.Pos() == aPos && f->second.Net() == aNet && f->second.Layers().Overlaps( aLayer ) )
1401 JOINT_MAP::iterator f =
m_joints.find( tag );
1403 std::pair<JOINT_MAP::iterator, JOINT_MAP::iterator> range;
1408 range =
m_root->m_joints.equal_range( tag );
1410 for( f = range.first; f != range.second; ++f )
1415 JOINT jt( aPos, aLayers, aNet );
1422 range =
m_joints.equal_range( tag );
1424 if( range.first ==
m_joints.end() )
1427 for( f = range.first; f != range.second; ++f )
1429 if( aLayers.
Overlaps( f->second.Layers() ) )
1431 jt.
Merge( f->second );
1445 wxLogTrace( wxT(
"PNS" ), wxT(
"joint layers %d-%d, net %d, pos %s, links: %d" ),
1449 m_tag.pos.Format().c_str(),
1476 std::unordered_set<SEGMENT*> all_segs;
1479 for( i = m_items.begin(); i != m_items.end(); i++ )
1482 all_segs.insert(
static_cast<SEGMENT*
>( *i ) );
1487 for( i =
m_root->m_items.begin(); i !=
m_root->m_items.end(); i++ )
1490 all_segs.insert(
static_cast<SEGMENT*
>(*i) );
1494 JOINT_MAP::iterator j;
1500 wxLogTrace( wxT(
"PNS" ), wxT(
"joint : %s, links : %d\n" ),
1501 j->second.GetPos().Format().c_str(), j->second.LinkCount() );
1502 JOINT::LINKED_ITEMS::const_iterator k;
1504 for( k = j->second.GetLinkList().begin(); k != j->second.GetLinkList().end(); ++k )
1506 const ITEM* m_item = *k;
1508 switch( m_item->GetKind() )
1513 wxLogTrace( wxT(
"PNS" ), wxT(
" -> seg %s %s\n" ),
1514 seg->GetSeg().A.
Format().c_str(),
1515 seg->GetSeg().B.
Format().c_str() );
1526 int lines_count = 0;
1528 while( !all_segs.empty() )
1530 SEGMENT* s = *all_segs.begin();
1533 LINE::LinkedSegments* seg_refs = l->GetLinkedSegments();
1537 wxLogTrace( wxT(
"PNS" ), wxT(
"Line: %s, net %d " ),
1538 l->GetLine().
Format().c_str(), l->GetNet() );
1541 for( std::vector<SEGMENT*>::iterator j = seg_refs->begin(); j != seg_refs->end(); ++j )
1543 wxLogTrace( wxT(
"PNS" ), wxT(
"%s " ), (*j)->GetSeg().A.Format().c_str() );
1545 if( j + 1 == seg_refs->end() )
1546 wxLogTrace( wxT(
"PNS" ), wxT(
"%s\n" ), (*j)->GetSeg().B.Format().c_str() );
1548 all_segs.erase( *j );
1554 wxLogTrace( wxT(
"PNS" ), wxT(
"Local joints: %d, lines : %d \n" ),
1569 aAdded.reserve(
m_index->Size() );
1572 aRemoved.push_back( item );
1575 aAdded.push_back( item );
1584 for(
NODE* node : kids )
1586 node->releaseChildren();
1597 std::vector<const ITEM*> toDelete;
1602 if( !item->BelongsTo(
this ) )
1604 toDelete.push_back( item );
1613 for(
const ITEM* item : toDelete)
1659 for(
ITEM* item : *l_cur )
1661 if( item->OfKind( aKindMask ) && item->IsRoutable() )
1662 aItems.insert( item );
1672 for(
ITEM* item : *l_root )
1674 if( !
Overrides( item ) && item->OfKind( aKindMask ) && item->IsRoutable() )
1675 aItems.insert( item );
1686 item->SetRank( -1 );
1687 item->Mark( item->Marker() & ~aMarkerMask );
1694 std::vector<ITEM*> garbage;
1698 if( item->Marker() & aMarker )
1699 garbage.emplace_back( item );
1702 for(
ITEM* item : garbage )
1725 && ( (
A == a2 &&
B == b2 ) || (
A == b2 &&
B == a2 ) ) )
1754 ARC* seg2 =
static_cast<ARC*
>( item );
1760 && ( (
A == a2 &&
B == b2 ) || (
A == b2 &&
B == a2 ) ) )
1784 for( JOINT_MAP::value_type& j :
m_joints )
1786 if( !j.second.Layers().Overlaps( aLayerMask ) )
1789 if( aBox.
Contains( j.second.Pos() ) && j.second.LinkCount( aKindMask ) )
1791 aJoints.push_back( &j.second );
1799 for( JOINT_MAP::value_type& j :
m_root->m_joints )
1801 if( !
Overrides( &j.second ) && j.second.Layers().Overlaps( aLayerMask ) )
1803 if( aBox.
Contains( j.second.Pos() ) && j.second.LinkCount( aKindMask ) )
1805 aJoints.push_back( &j.second );
1824 for(
ITEM* item : *l_cur )
1826 if( item->Parent() == aParent )
1838 std::vector<ITEM*> ret;
1842 if( item->Parent() == aParent )
1843 ret.push_back( item );
1861 if( item->Net() == handle.
net && item->Layers().Overlaps(handle.
layers) )
1862 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(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.
void BeginBulkAdd()
Defer spatial index insertion during bulk population.
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.
void FinalizeBulkAdd()
Build the spatial index from all items added since BeginBulkAdd().
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.
ROUTING_SETTINGS & Settings()
static ROUTER * GetInstance()
DIRECTION_45::CORNER_MODE GetCornerMode() const
virtual const SHAPE_LINE_CHAIN & HullCache(const ITEM *aItem, int aClearance, int aWalkaroundThickness, int aLayer)
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.
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...
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.
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.
wxString result
Test unit parsing edge cases and error handling.
thread_pool & GetKiCadThreadPool()
Get a reference to the current thread pool.
BS::priority_thread_pool thread_pool
Casted dyn_cast(From aObject)
A lightweight dynamic downcast.
VECTOR2< int32_t > VECTOR2I