55 LINE l =
m_world->AssembleLine( root,
nullptr,
false,
false,
false );
75 std::deque<const JOINT*> searchQueue;
78 searchQueue.push_back( aStart );
79 processed.insert( aStart );
81 while( !searchQueue.empty() )
83 const JOINT* current = searchQueue.front();
84 searchQueue.pop_front();
90 const JOINT* a =
m_world->FindJoint( item->Anchor( 0 ), item );;
91 const JOINT* b =
m_world->FindJoint( item->Anchor( 1 ), item );;
92 const JOINT*
next = ( *a == *current ) ? b : a;
94 if( processed.find(
next ) == processed.end() )
96 processed.insert(
next );
97 searchQueue.push_back(
next );
110 LINE track( *aTrack );
116 std::unique_ptr<NODE> tmpNode(
m_world->Branch() );
119 tmpNode->Add( track );
123 if( !jt ||
m_world->GetRuleResolver()->NetCode( jt->
Net() ) <= 0 )
126 ITEM* connected =
nullptr;
134 if( !link->BelongsTo( tmpNode.get() ) )
187 std::set<ITEM*> disconnected;
189 m_world->AllItemsInNet( aStart->
Net(), disconnected );
193 for(
ITEM* link : jt->LinkList() )
195 if( disconnected.find( link ) != disconnected.end() )
196 disconnected.erase( link );
200 int best_dist = INT_MAX;
201 ITEM* best =
nullptr;
203 for(
ITEM* item : disconnected )
205 if( item->OfKind( aKindMask ) )
207 for(
int i = 0; i < item->AnchorCount(); i++ )
210 int d = ( p - aStart->
Pos() ).EuclideanNorm();
229 std::set<ITEM*>& aVisited,
230 bool aFollowLockedSegments )
232 using clock = std::chrono::steady_clock;
235 best.
m_end = aStartJoint;
238 auto startTime = clock::now();
248 std::set<const JOINT*> visitedJoints;
252 std::stack<STATE> stateStack;
256 initial.joint = aStartJoint;
257 initial.prev = aPrev;
258 initial.pathLength = 0;
259 initial.visitedJoints.insert( aStartJoint );
260 initial.via =
nullptr;
262 stateStack.push( std::move( initial ) );
264 while( !stateStack.empty() )
267 auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
268 clock::now() - startTime ).count();
270 if( elapsed > timeoutMs )
272 wxLogTrace( wxT(
"PNS_TUNE" ),
273 wxT(
"followBranch: timeout after %lld ms, returning best path found" ),
278 STATE current = std::move( stateStack.top() );
281 const JOINT* joint = current.joint;
287 for(
ITEM* link : links )
289 if( link->OfKind(
ITEM::VIA_T ) && !aVisited.contains( link ) )
297 bool foundBranch =
false;
299 for(
ITEM* link : links )
304 if( link == current.prev )
307 if( aVisited.contains( link ) )
311 false, aFollowLockedSegments );
319 if( current.visitedJoints.count( nextJoint ) )
326 nextState.joint = nextJoint;
327 nextState.prev = l.
Links().back();
328 nextState.pathItems = current.pathItems;
329 nextState.pathLength = current.pathLength + l.
CLine().
Length();
330 nextState.visitedJoints = current.visitedJoints;
331 nextState.visitedJoints.insert( nextJoint );
336 nextState.pathItems.Add(
via );
338 nextState.pathItems.Add( l );
340 stateStack.push( std::move( nextState ) );
346 if( current.pathLength > best.
m_length )
350 best.
m_items = current.pathItems;
355 wxLogTrace( wxT(
"PNS_TUNE" ),
356 wxT(
"followBranch: completed with best path length=%d, %d items" ),
364 const JOINT** aTerminalJointB,
365 bool aFollowLockedSegments )
369 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"=== followTrivialPath START ===" ) );
370 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"followTrivialPath: initial line has %d segments, %zu links" ),
372 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"followTrivialPath: line endpoints: (%d,%d) to (%d,%d)" ),
379 std::set<ITEM*> visited;
382 visited.insert( link );
387 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"followTrivialPath: LEFT branch starting from joint at (%d,%d)" ),
390 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"followTrivialPath: LEFT branch result: length=%d, %d items" ),
391 left.m_length,
left.m_items.Size() );
393 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"followTrivialPath: RIGHT branch starting from joint at (%d,%d)" ),
396 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"followTrivialPath: RIGHT branch result: length=%d, %d items" ),
399 if( aTerminalJointA )
400 *aTerminalJointA =
left.m_end;
402 if( aTerminalJointB )
403 *aTerminalJointB =
right.m_end;
406 int leftSegCount = 0;
407 int rightSegCount = 0;
408 int initialSegCount = 0;
417 path.Prepend( item );
420 LINE* l =
dynamic_cast<LINE*
>( item );
434 LINE* l =
dynamic_cast<LINE*
>( item );
445 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"" ) );
446 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"=== followTrivialPath SUMMARY ===" ) );
447 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"Starting segment count: %d" ), initialSegCount );
448 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"Left branch: %d segments, length=%d" ), leftSegCount,
left.m_length );
449 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"Initial line: %d segments, length=%lld" ), initialSegCount, aLine2->
CLine().
Length() );
450 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"Right branch: %d segments, length=%d" ), rightSegCount,
right.m_length );
451 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"Total segments in path: %d" ), leftSegCount + initialSegCount + rightSegCount );
452 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"Total path length: %d" ), totalLength );
453 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"Total items in result: %d" ),
path.Size() );
454 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"=== followTrivialPath END ===" ) );
455 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"" ) );
462 std::pair<const JOINT*, const JOINT*>* aTerminalJoints,
463 bool aFollowLockedSegments )
465 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"*** AssembleTrivialPath: START ***" ) );
466 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTrivialPath: aStart=%p, kind=%s" ),
467 aStart, aStart->
KindStr().c_str() );
474 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTrivialPath: starting from VIA" ) );
480 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTrivialPath: VIA is fanout, returning empty" ) );
486 for(
ITEM* item : links )
491 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTrivialPath: found segment/arc from VIA" ) );
499 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTrivialPath: starting from SEGMENT/ARC" ) );
504 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTrivialPath: no segment found, returning empty" ) );
510 LINE l =
m_world->AssembleLine( seg,
nullptr,
false, aFollowLockedSegments );
512 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTrivialPath: assembled line with %d segments, length=%lld" ),
515 const JOINT* jointA =
nullptr;
516 const JOINT* jointB =
nullptr;
520 if( aTerminalJoints )
522 wxASSERT( jointA && jointB );
523 *aTerminalJoints = std::make_pair( jointA, jointB );
524 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTrivialPath: terminal joints at (%d,%d) and (%d,%d)" ),
528 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTrivialPath: returning path with %d items" ),
path.Size() );
529 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"*** AssembleTrivialPath: END ***" ) );
530 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"" ) );
546 m_world->QueryColliding( aVia, obstacles, opts );
549 std::set<LINKED_ITEM*> assembled;
556 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"findLinesFromVia: VIA at (%d,%d), net=%p, %zu obstacles" ), aVia->
Pos().
x,
557 aVia->
Pos().
y, net, obstacles.size() );
559 for(
const OBSTACLE& obs : obstacles )
561 if( obs.m_item->Net() != net )
566 if( aVisited.contains( linked ) )
569 if( assembled.contains( linked ) )
576 bool anchor0Inside, anchor1Inside;
588 anchor0Inside = shape && shape->
Collide( anchor0, 0 );
589 anchor1Inside = shape && shape->
Collide( anchor1, 0 );
592 if( !anchor0Inside && !anchor1Inside )
594 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
" skip collision: layer=%d anchor0=(%d,%d) anchor1=(%d,%d)" ),
595 linked->
Layer(), anchor0.
x, anchor0.
y, anchor1.
x, anchor1.
y );
599 LINE l =
m_world->AssembleLine( linked,
nullptr,
false,
true );
602 assembled.insert( link );
612 const std::set<ITEM*>& aVisited )
614 using clock = std::chrono::steady_clock;
620 auto startTime = clock::now();
627 std::set<ITEM*> visited;
630 std::stack<STATE> stateStack;
633 initial.endpoint = aStartFromBack ? aStartLine.
CLastPoint() : aStartLine.
CPoint( 0 );
634 initial.pathLength = 0;
635 initial.visited = aVisited;
636 stateStack.push( std::move( initial ) );
638 while( !stateStack.empty() )
640 auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>( clock::now() - startTime ).count();
642 if( elapsed > timeoutMs )
644 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"walkTuningPath: timeout after %lld ms" ), elapsed );
648 STATE current = std::move( stateStack.top() );
655 for(
ITEM* item : hits )
657 if( item->OfKind(
ITEM::SOLID_T ) && item->Net() == net && !current.visited.contains( item ) )
666 if( current.pathLength > best.
m_length )
669 best.
m_items = current.pathItems;
674 current.visited.insert(
pad );
676 for(
ITEM* item : hits )
681 if( item->Net() != net || current.visited.contains( item ) )
687 bool startNear = ( contLine.
CPoint( 0 ) - ep ).SquaredEuclideanNorm()
688 <= ( contLine.
CLastPoint() - ep ).SquaredEuclideanNorm();
691 nextState.endpoint = startNear ? contLine.
CLastPoint() : contLine.
CPoint( 0 );
692 nextState.pathItems = current.pathItems;
693 nextState.pathItems.Add( contLine );
694 nextState.pathLength = current.pathLength + contLine.
CLine().
Length();
695 nextState.visited = current.visited;
698 nextState.visited.insert( link );
700 stateStack.push( std::move( nextState ) );
708 for(
ITEM* item : hits )
710 if( item->OfKind(
ITEM::VIA_T ) && item->Net() == net && !item->IsVirtual()
711 && !current.visited.contains( item ) )
713 via =
static_cast<VIA*
>( item );
720 current.visited.insert(
via );
724 for(
LINE& contLine : continuations )
727 bool startNearVia = ( contLine.CPoint( 0 ) - ep ).SquaredEuclideanNorm()
728 <= ( contLine.CLastPoint() - ep ).SquaredEuclideanNorm();
730 VECTOR2I forwardEndpoint = startNearVia ? contLine.CLastPoint() : contLine.CPoint( 0 );
732 int64_t contLength = contLine.CLine().Length();
741 contLength = clipped.
Length();
745 nextState.endpoint = forwardEndpoint;
746 nextState.pathItems = current.pathItems;
747 nextState.pathItems.Add(
via );
748 nextState.pathItems.Add( contLine );
749 nextState.pathLength = current.pathLength + contLength;
750 nextState.visited = current.visited;
753 nextState.visited.insert( link );
755 stateStack.push( std::move( nextState ) );
758 if( continuations.empty() )
760 if( current.pathLength > best.
m_length )
763 best.
m_items = current.pathItems;
771 if( current.pathLength > best.
m_length )
774 best.
m_items = current.pathItems;
780 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"walkTuningPath: completed, best length=%lld, %d items, pad=%p" ),
790 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"" ) );
791 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"########## AssembleTuningPath: START ##########" ) );
792 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTuningPath: aStart=%p, kind=%s" ),
793 aStart, aStart->
KindStr().c_str() );
807 for(
ITEM* item : links )
821 if( continuations.empty() )
823 wxLogTrace( wxT(
"PNS_TUNE" ),
824 wxT(
"AssembleTuningPath: no via continuation found, returning empty" ) );
828 for(
LINKED_ITEM* link : continuations.front().Links() )
845 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTuningPath: no segment found, returning empty" ) );
849 LINE l =
m_world->AssembleLine( seg,
nullptr,
false,
true );
851 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTuningPath: initial line %d segments, length=%lld" ), l.
SegmentCount(),
854 std::set<ITEM*> visited;
857 visited.insert( link );
859 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTuningPath: walking LEFT from (%d,%d)" ), l.
CPoint( 0 ).
x,
863 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTuningPath: walking RIGHT from (%d,%d)" ), l.
CLastPoint().
x,
870 path.Prepend( item );
886 padA =
static_cast<PAD*
>( bi );
889 *aStartPad =
left.m_endPad;
891 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTuningPath: found start pad" ) );
901 padB =
static_cast<PAD*
>( bi );
904 *aEndPad =
right.m_endPad;
906 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTuningPath: found end pad" ) );
912 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTuningPath: no pads found, returning path" ) );
913 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"########## AssembleTuningPath: END ##########" ) );
917 auto processPad = [&](
PAD* aPad )
919 for(
int idx = 0; idx <
path.Size(); idx++ )
938 std::set<PAD*> processedPads;
941 processedPads.insert( padA );
944 processedPads.insert( padB );
946 for(
int idx = 0; idx <
path.Size(); idx++ )
957 for(
ITEM* item : hits )
966 PAD* intermediatePad =
static_cast<PAD*
>( bi );
968 if( processedPads.find( intermediatePad ) == processedPads.end() )
970 wxLogTrace( wxT(
"PNS_TUNE" ),
971 wxT(
"AssembleTuningPath: processing intermediate"
974 processPad( intermediatePad );
975 processedPads.insert( intermediatePad );
986 for(
int idx = 0; idx <
path.Size(); idx++ )
999 for(
int delta : { -1, 1 } )
1001 int j = idx +
delta;
1014 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTuningPath: final path has %d items" ),
path.Size() );
1015 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"########## AssembleTuningPath: END ##########" ) );
1042 if( !coupledNet || !startItem )
1045 LINE lp =
m_world->AssembleLine( startItem,
nullptr,
false,
false,
false );
1047 std::vector<ITEM*> pItems;
1048 std::vector<ITEM*> nItems;
1053 pItems.push_back( item );
1056 std::set<ITEM*> coupledItems;
1057 m_world->AllItemsInNet( coupledNet, coupledItems );
1059 for(
ITEM* item : coupledItems )
1062 nItems.push_back( item );
1067 SEG::ecoord minDist_sq = std::numeric_limits<SEG::ecoord>::max();
1068 SEG::ecoord minDistTarget_sq = std::numeric_limits<SEG::ecoord>::max();
1071 auto findNItem = [&](
ITEM* p_item )
1073 for(
ITEM* n_item : nItems )
1075 SEG::ecoord dist_sq = std::numeric_limits<SEG::ecoord>::max();
1077 if( n_item->Kind() != p_item->Kind() )
1100 const ARC* p_arc =
static_cast<const ARC*
>( p_item );
1101 const ARC* n_arc =
static_cast<const ARC*
>( n_item );
1115 if( dist_sq <= minDist_sq )
1117 SEG::ecoord distTarget_sq = n_item->Shape( -1 )->SquaredDistance( targetPoint );
1118 if( distTarget_sq < minDistTarget_sq )
1120 minDistTarget_sq = distTarget_sq;
1121 minDist_sq = dist_sq;
1124 coupledItem =
static_cast<LINKED_ITEM*
>( n_item );
1130 findNItem( startItem );
1135 std::set<ITEM*> linksToTest;
1146 if( link != linked )
1147 linksToTest.emplace( link );
1151 for(
ITEM* link : linksToTest )
1158 LINE ln =
m_world->AssembleLine( coupledItem,
nullptr,
false,
false,
false );
1160 if(
m_world->GetRuleResolver()->DpNetPolarity( refNet ) < 0 )
1161 std::swap( lp, ln );
1174 const ARC* refArc =
static_cast<ARC*
>( refItem );
1175 const ARC* coupledArc =
static_cast<ARC*
>( coupledItem );
1190 std::deque<ITEM*> pending;
1197 pending.push_back( aStart );
1200 int64_t initialArea = clusterBBox.
GetArea();
1201 std::unordered_set<ITEM*> processed;
1203 while( !pending.empty() )
1208 pending.pop_front();
1210 if( processed.find(
top ) == processed.end() )
1215 processed.insert(
top );
1217 m_world->QueryColliding(
top, obstacles, opts );
1219 for(
const OBSTACLE& obs : obstacles )
1226 if( aExcludedNet && obs.m_item->Net() == aExcludedNet )
1232 clusterBBox.
Merge( line.CLine().BBox() );
1236 clusterBBox.
Merge( obs.m_item->Shape( aLayer )->BBox() );
1239 const int64_t currentArea = clusterBBox.
GetArea();
1240 const double areaRatio = (double) currentArea / (
double) ( initialArea + 1 );
1242 if( aAreaExpansionLimit > 0.0 && areaRatio > aAreaExpansionLimit )
1245 if( processed.find( obs.m_item ) == processed.end() &&
1246 obs.m_item->Layers().Overlaps( aLayer ) && !( obs.m_item->Marker() &
MK_HEAD ) )
1248 processed.insert( obs.m_item );
1249 cluster.
m_items.push_back( obs.m_item );
1250 pending.push_back( obs.m_item );
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
constexpr ecoord_type GetArea() const
Return the area of the rectangle.
KICAD_T Type() const
Returns the type of object.
static void OptimiseTraceInVia(SHAPE_LINE_CHAIN &aLine, const PCB_VIA *aVia, PCB_LAYER_ID aLayer)
Clips trace portions inside a VIA pad and replaces them with a straight-line segment from the VIA edg...
static bool IsPointInsideViaPad(const PCB_VIA *aVia, const VECTOR2I &aPoint, PCB_LAYER_ID aLayer)
Returns true if the given point falls inside VIA pad shape on the given layer.
static void OptimiseTraceInPad(SHAPE_LINE_CHAIN &aLine, const PAD *aPad, PCB_LAYER_ID aPcbLayer)
Optimises the given trace / line to minimise the electrical path length within the given pad.
int Width() const override
const SHAPE_ARC & CArc() const
Basic class for a differential pair.
void SetWidth(int aWidth)
void Add(const LINE &aLine)
Base class for PNS router board items.
BOARD_ITEM * Parent() const
void SetLayers(const PNS_LAYER_RANGE &aLayers)
virtual const SHAPE * Shape(int aLayer) const
Return the geometrical shape of the item.
const PNS_LAYER_RANGE & Layers() const
virtual NET_HANDLE Net() const
PnsKind Kind() const
Return the type (kind) of the item.
virtual int Layer() const
bool OfKind(int aKindMask) const
virtual VECTOR2I Anchor(int n) const
std::string KindStr() const
virtual int AnchorCount() 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
bool IsNonFanoutVia() const
const ITEM_SET & CLinks() const
const VECTOR2I & Pos() const
Represents a track on a PCB, connecting two non-trivial joints (that is, vias, pads,...
const VECTOR2I & CPoint(int aIdx) const
void SetShape(const SHAPE_LINE_CHAIN &aLine)
Return the shape of the line.
const SHAPE_LINE_CHAIN & CLine() const
const VECTOR2I & CLastPoint() const
SHAPE_LINE_CHAIN & Line()
void Reverse()
Clip the line to the nearest obstacle, traversing from the line's start vertex (0).
int Width() const
Return true if the line is geometrically identical as line aOther.
bool IsLinked() const
Check if the segment aLink is a part of the line.
std::vector< LINKED_ITEM * > & Links()
LINKED_ITEM * GetLink(int aIndex) const
Erase the linking information. Used to detach the line from the owning node.
virtual void ClearLinks()
Return the number of segments that were assembled together to form this line.
std::set< OBSTACLE > OBSTACLES
virtual PCB_LAYER_ID GetBoardLayerFromPNSLayer(int aLayer) const =0
int Width() const override
ITEM * NearestUnconnectedItem(const JOINT *aStart, int *aAnchor=nullptr, int aKindMask=ITEM::ANY_T)
std::set< const JOINT * > JOINT_SET
bool LeadingRatLine(const LINE *aTrack, SHAPE_LINE_CHAIN &aRatLine)
std::vector< LINE > findLinesFromVia(ROUTER_IFACE *aRouterIface, VIA *aVia, const std::set< ITEM * > &aVisited)
const DIFF_PAIR AssembleDiffPair(SEGMENT *aStart)
WALK_RESULT walkTuningPath(ROUTER_IFACE *aRouterIface, LINE &aStartLine, bool aStartFromBack, const std::set< ITEM * > &aVisited)
ITEM_SET followTrivialPath(LINE *aLine, const JOINT **aTerminalJointA, const JOINT **aTerminalJointB, bool aFollowLockedSegments=false)
const ITEM_SET ConnectedItems(const JOINT *aStart, int aKindMask=ITEM::ANY_T)
bool NearestUnconnectedAnchorPoint(const LINE *aTrack, VECTOR2I &aPoint, PNS_LAYER_RANGE &aLayers, ITEM *&aItem)
const CLUSTER AssembleCluster(ITEM *aStart, int aLayer, double aAreaExpansionLimit=0.0, NET_HANDLE aExcludedNet=nullptr)
const JOINT_SET ConnectedJoints(const JOINT *aStart)
const ITEM_SET AssembleTuningPath(ROUTER_IFACE *aRouterIface, ITEM *aStart, SOLID **aStartPad=nullptr, SOLID **aEndPad=nullptr)
Like AssembleTrivialPath, but follows the track length algorithm, which discards segments that are fu...
const int DP_PARALLELITY_THRESHOLD
PATH_RESULT followBranch(const JOINT *aStartJoint, LINKED_ITEM *aPrev, std::set< ITEM * > &aVisited, bool aFollowLockedSegments)
const ITEM_SET AssembleTrivialPath(ITEM *aStart, std::pair< const JOINT *, const JOINT * > *aTerminalJoints=nullptr, bool aFollowLockedSegments=false)
Assemble a trivial path between two joints given a starting item.
bool SimplifyLine(LINE *aLine)
const VECTOR2I & Pos() const
const SHAPE * Shape(int aLayer) const override
Return the geometrical shape of the item.
Represent a contiguous set of PCB layers.
ecoord SquaredDistance(const SEG &aSeg) const
VECTOR2I::extended_type ecoord
static SEG::ecoord Square(int a)
bool ApproxParallel(const SEG &aSeg, int aDistanceThreshold=1) const
const VECTOR2I & GetCenter() const
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
int PointCount() const
Return the number of points (vertices) in this line chain.
void Clear()
Remove all points from the line chain.
void Simplify(int aTolerance=0)
Simplify the line chain by removing colinear adjacent segments and duplicate vertices.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
long long int Length() const
Return length of the line chain in Euclidean metric.
An abstract shape on 2D plane.
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,...
virtual VECTOR2I Centre() const
Compute a center-of-mass of the shape.
virtual const BOX2I BBox(int aClearance=0) const =0
Compute a bounding box of the shape, with a margin of aClearance a collision.
constexpr extended_type Cross(const VECTOR2< T > &aVector) const
Compute cross product of self with aVector.
constexpr extended_type SquaredEuclideanNorm() const
Compute the squared euclidean norm of the vector, which is defined as (x ** 2 + y ** 2).
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
int m_FollowBranchTimeout
Timeout for the PNS router's followBranch path search, in milliseconds.
PCB_LAYER_ID
A quick note on layer IDs:
Push and Shove diff pair dimensions (gap) settings dialog.
bool commonParallelProjection(SEG p, SEG n, SEG &pClip, SEG &nClip)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Hold an object colliding with another object, along with some useful data about the collision.
std::vector< ITEM * > m_items
KIBIS top(path, &reporter)
wxString result
Test unit parsing edge cases and error handling.
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
@ PCB_PAD_T
class PAD, a pad in a footprint
VECTOR2< int32_t > VECTOR2I