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;
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() );
159 JOINT_MAP::iterator j;
169 wxLogTrace( wxT(
"PNS" ), wxT(
"%d items, %d joints, %d overrides" ),
191 m_override( nullptr )
235 if(
m_item == aCandidate )
241 if(
visit( aCandidate ) )
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;
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;
1211 else if(
const auto t = dyn_cast<const PNS::SEGMENT*>( item ) )
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 )
1263 Add( ItemCast<VIA>( std::move( std::unique_ptr<VVIA>( vvia ) ) ) );
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;
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" ),
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" ),
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 );
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
void Remove(ITEM *aItem)
Removes an item from the spatial index.
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.
int Query(const ITEM *aItem, int aMinDistance, Visitor &aVisitor) const
Searches items in the index that are in proximity of aItem.
NET_ITEMS_LIST * GetItemsForNet(NET_HANDLE aNet)
Returns list of all items in a given net.
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 void ClearCacheForItems(std::vector< const ITEM * > &aItems)
virtual int ClearanceEpsilon() const
virtual int Clearance(const ITEM *aA, const ITEM *aB, bool aUseClearanceEpsilon=true)=0
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,...
const std::string Format() const
Return the vector formatted as a string.
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)
static std::vector< std::string > split(const std::string &aStr, const std::string &aDelim)
Split the input string into a vector of output strings.
const COLLISION_SEARCH_OPTIONS options
std::set< OBSTACLE > & obstacles
std::function< bool(const ITEM *)> m_filter
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.
VECTOR2< int32_t > VECTOR2I