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;
188 std::vector<const ITEM*> joined;
190 m_world->AllItemsInNet( aStart->
Net(), disconnected );
194 for(
ITEM* link : jt->LinkList() )
196 if( disconnected.find( link ) != disconnected.end() )
197 disconnected.erase( link );
199 joined.push_back( link );
205 m_iface->RemoveBoardConnected( joined, disconnected );
207 int best_dist = INT_MAX;
208 ITEM* best =
nullptr;
210 for(
ITEM* item : disconnected )
212 if( item->OfKind( aKindMask ) )
214 for(
int i = 0; i < item->AnchorCount(); i++ )
217 int d = ( p - aStart->
Pos() ).EuclideanNorm();
236 std::set<ITEM*>& aVisited,
237 bool aFollowLockedSegments )
239 using clock = std::chrono::steady_clock;
242 best.
m_end = aStartJoint;
245 auto startTime = clock::now();
255 std::set<const JOINT*> visitedJoints;
259 std::stack<STATE> stateStack;
263 initial.joint = aStartJoint;
264 initial.prev = aPrev;
265 initial.pathLength = 0;
266 initial.visitedJoints.insert( aStartJoint );
267 initial.via =
nullptr;
269 stateStack.push( std::move( initial ) );
271 while( !stateStack.empty() )
274 auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
275 clock::now() - startTime ).count();
277 if( elapsed > timeoutMs )
279 wxLogTrace( wxT(
"PNS_TUNE" ),
280 wxT(
"followBranch: timeout after %lld ms, returning best path found" ),
285 STATE current = std::move( stateStack.top() );
288 const JOINT* joint = current.joint;
294 for(
ITEM* link : links )
296 if( link->OfKind(
ITEM::VIA_T ) && !aVisited.contains( link ) )
304 bool foundBranch =
false;
306 for(
ITEM* link : links )
311 if( link == current.prev )
314 if( aVisited.contains( link ) )
318 false, aFollowLockedSegments );
326 if( current.visitedJoints.count( nextJoint ) )
333 nextState.joint = nextJoint;
334 nextState.prev = l.
Links().back();
335 nextState.pathItems = current.pathItems;
336 nextState.pathLength = current.pathLength + l.
CLine().
Length();
337 nextState.visitedJoints = current.visitedJoints;
338 nextState.visitedJoints.insert( nextJoint );
343 nextState.pathItems.Add(
via );
345 nextState.pathItems.Add( l );
347 stateStack.push( std::move( nextState ) );
353 if( current.pathLength > best.
m_length )
357 best.
m_items = current.pathItems;
362 wxLogTrace( wxT(
"PNS_TUNE" ),
363 wxT(
"followBranch: completed with best path length=%d, %d items" ),
371 const JOINT** aTerminalJointB,
372 bool aFollowLockedSegments )
376 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"=== followTrivialPath START ===" ) );
377 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"followTrivialPath: initial line has %d segments, %zu links" ),
379 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"followTrivialPath: line endpoints: (%d,%d) to (%d,%d)" ),
386 std::set<ITEM*> visited;
389 visited.insert( link );
394 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"followTrivialPath: LEFT branch starting from joint at (%d,%d)" ),
397 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"followTrivialPath: LEFT branch result: length=%d, %d items" ),
398 left.m_length,
left.m_items.Size() );
400 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"followTrivialPath: RIGHT branch starting from joint at (%d,%d)" ),
403 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"followTrivialPath: RIGHT branch result: length=%d, %d items" ),
406 if( aTerminalJointA )
407 *aTerminalJointA =
left.m_end;
409 if( aTerminalJointB )
410 *aTerminalJointB =
right.m_end;
413 int leftSegCount = 0;
414 int rightSegCount = 0;
415 int initialSegCount = 0;
424 path.Prepend( item );
427 LINE* l =
dynamic_cast<LINE*
>( item );
441 LINE* l =
dynamic_cast<LINE*
>( item );
452 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"" ) );
453 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"=== followTrivialPath SUMMARY ===" ) );
454 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"Starting segment count: %d" ), initialSegCount );
455 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"Left branch: %d segments, length=%d" ), leftSegCount,
left.m_length );
456 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"Initial line: %d segments, length=%lld" ), initialSegCount, aLine2->
CLine().
Length() );
457 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"Right branch: %d segments, length=%d" ), rightSegCount,
right.m_length );
458 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"Total segments in path: %d" ), leftSegCount + initialSegCount + rightSegCount );
459 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"Total path length: %d" ), totalLength );
460 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"Total items in result: %d" ),
path.Size() );
461 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"=== followTrivialPath END ===" ) );
462 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"" ) );
469 std::pair<const JOINT*, const JOINT*>* aTerminalJoints,
470 bool aFollowLockedSegments )
472 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"*** AssembleTrivialPath: START ***" ) );
473 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTrivialPath: aStart=%p, kind=%s" ),
474 aStart, aStart->
KindStr().c_str() );
481 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTrivialPath: starting from VIA" ) );
487 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTrivialPath: VIA is fanout, returning empty" ) );
493 for(
ITEM* item : links )
498 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTrivialPath: found segment/arc from VIA" ) );
506 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTrivialPath: starting from SEGMENT/ARC" ) );
511 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTrivialPath: no segment found, returning empty" ) );
517 LINE l =
m_world->AssembleLine( seg,
nullptr,
false, aFollowLockedSegments );
519 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTrivialPath: assembled line with %d segments, length=%lld" ),
522 const JOINT* jointA =
nullptr;
523 const JOINT* jointB =
nullptr;
527 if( aTerminalJoints )
529 wxASSERT( jointA && jointB );
530 *aTerminalJoints = std::make_pair( jointA, jointB );
531 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTrivialPath: terminal joints at (%d,%d) and (%d,%d)" ),
535 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTrivialPath: returning path with %d items" ),
path.Size() );
536 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"*** AssembleTrivialPath: END ***" ) );
537 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"" ) );
553 m_world->QueryColliding( aVia, obstacles, opts );
556 std::set<LINKED_ITEM*> assembled;
563 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"findLinesFromVia: VIA at (%d,%d), net=%p, %zu obstacles" ), aVia->
Pos().
x,
564 aVia->
Pos().
y, net, obstacles.size() );
566 for(
const OBSTACLE& obs : obstacles )
568 if( obs.m_item->Net() != net )
573 if( aVisited.contains( linked ) )
576 if( assembled.contains( linked ) )
583 bool anchor0Inside, anchor1Inside;
595 anchor0Inside = shape && shape->
Collide( anchor0, 0 );
596 anchor1Inside = shape && shape->
Collide( anchor1, 0 );
599 if( !anchor0Inside && !anchor1Inside )
601 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
" skip collision: layer=%d anchor0=(%d,%d) anchor1=(%d,%d)" ),
602 linked->
Layer(), anchor0.
x, anchor0.
y, anchor1.
x, anchor1.
y );
606 LINE l =
m_world->AssembleLine( linked,
nullptr,
false,
true );
609 assembled.insert( link );
619 const std::set<ITEM*>& aVisited )
621 using clock = std::chrono::steady_clock;
627 auto startTime = clock::now();
634 std::set<ITEM*> visited;
637 std::stack<STATE> stateStack;
640 initial.endpoint = aStartFromBack ? aStartLine.
CLastPoint() : aStartLine.
CPoint( 0 );
641 initial.pathLength = 0;
642 initial.visited = aVisited;
643 stateStack.push( std::move( initial ) );
645 while( !stateStack.empty() )
647 auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>( clock::now() - startTime ).count();
649 if( elapsed > timeoutMs )
651 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"walkTuningPath: timeout after %lld ms" ), elapsed );
655 STATE current = std::move( stateStack.top() );
662 for(
ITEM* item : hits )
664 if( item->OfKind(
ITEM::SOLID_T ) && item->Net() == net && !current.visited.contains( item ) )
673 if( current.pathLength > best.
m_length )
676 best.
m_items = current.pathItems;
681 current.visited.insert(
pad );
683 for(
ITEM* item : hits )
688 if( item->Net() != net || current.visited.contains( item ) )
694 bool startNear = ( contLine.
CPoint( 0 ) - ep ).SquaredEuclideanNorm()
695 <= ( contLine.
CLastPoint() - ep ).SquaredEuclideanNorm();
698 nextState.endpoint = startNear ? contLine.
CLastPoint() : contLine.
CPoint( 0 );
699 nextState.pathItems = current.pathItems;
700 nextState.pathItems.Add( contLine );
701 nextState.pathLength = current.pathLength + contLine.
CLine().
Length();
702 nextState.visited = current.visited;
705 nextState.visited.insert( link );
707 stateStack.push( std::move( nextState ) );
715 for(
ITEM* item : hits )
717 if( item->OfKind(
ITEM::VIA_T ) && item->Net() == net && !item->IsVirtual()
718 && !current.visited.contains( item ) )
720 via =
static_cast<VIA*
>( item );
727 current.visited.insert(
via );
731 for(
LINE& contLine : continuations )
734 bool startNearVia = ( contLine.CPoint( 0 ) - ep ).SquaredEuclideanNorm()
735 <= ( contLine.CLastPoint() - ep ).SquaredEuclideanNorm();
737 VECTOR2I forwardEndpoint = startNearVia ? contLine.CLastPoint() : contLine.CPoint( 0 );
739 int64_t contLength = contLine.CLine().Length();
748 contLength = clipped.
Length();
752 nextState.endpoint = forwardEndpoint;
753 nextState.pathItems = current.pathItems;
754 nextState.pathItems.Add(
via );
755 nextState.pathItems.Add( contLine );
756 nextState.pathLength = current.pathLength + contLength;
757 nextState.visited = current.visited;
760 nextState.visited.insert( link );
762 stateStack.push( std::move( nextState ) );
765 if( continuations.empty() )
767 if( current.pathLength > best.
m_length )
770 best.
m_items = current.pathItems;
778 if( current.pathLength > best.
m_length )
781 best.
m_items = current.pathItems;
787 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"walkTuningPath: completed, best length=%lld, %d items, pad=%p" ),
797 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"" ) );
798 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"########## AssembleTuningPath: START ##########" ) );
799 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTuningPath: aStart=%p, kind=%s" ),
800 aStart, aStart->
KindStr().c_str() );
814 for(
ITEM* item : links )
828 if( continuations.empty() )
830 wxLogTrace( wxT(
"PNS_TUNE" ),
831 wxT(
"AssembleTuningPath: no via continuation found, returning empty" ) );
835 for(
LINKED_ITEM* link : continuations.front().Links() )
852 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTuningPath: no segment found, returning empty" ) );
856 LINE l =
m_world->AssembleLine( seg,
nullptr,
false,
true );
858 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTuningPath: initial line %d segments, length=%lld" ), l.
SegmentCount(),
861 std::set<ITEM*> visited;
864 visited.insert( link );
866 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTuningPath: walking LEFT from (%d,%d)" ), l.
CPoint( 0 ).
x,
870 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTuningPath: walking RIGHT from (%d,%d)" ), l.
CLastPoint().
x,
877 path.Prepend( item );
893 padA =
static_cast<PAD*
>( bi );
896 *aStartPad =
left.m_endPad;
898 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTuningPath: found start pad" ) );
908 padB =
static_cast<PAD*
>( bi );
911 *aEndPad =
right.m_endPad;
913 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTuningPath: found end pad" ) );
919 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTuningPath: no pads found, returning path" ) );
920 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"########## AssembleTuningPath: END ##########" ) );
924 auto processPad = [&](
PAD* aPad )
926 for(
int idx = 0; idx <
path.Size(); idx++ )
945 std::set<PAD*> processedPads;
948 processedPads.insert( padA );
951 processedPads.insert( padB );
953 for(
int idx = 0; idx <
path.Size(); idx++ )
964 for(
ITEM* item : hits )
973 PAD* intermediatePad =
static_cast<PAD*
>( bi );
975 if( processedPads.find( intermediatePad ) == processedPads.end() )
977 wxLogTrace( wxT(
"PNS_TUNE" ),
978 wxT(
"AssembleTuningPath: processing intermediate"
981 processPad( intermediatePad );
982 processedPads.insert( intermediatePad );
993 for(
int idx = 0; idx <
path.Size(); idx++ )
1006 for(
int delta : { -1, 1 } )
1008 int j = idx +
delta;
1021 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTuningPath: final path has %d items" ),
path.Size() );
1022 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"########## AssembleTuningPath: END ##########" ) );
1049 if( !coupledNet || !startItem )
1052 LINE lp =
m_world->AssembleLine( startItem,
nullptr,
false,
false,
false );
1054 std::vector<ITEM*> pItems;
1055 std::vector<ITEM*> nItems;
1060 pItems.push_back( item );
1063 std::set<ITEM*> coupledItems;
1064 m_world->AllItemsInNet( coupledNet, coupledItems );
1066 for(
ITEM* item : coupledItems )
1069 nItems.push_back( item );
1074 SEG::ecoord minDist_sq = std::numeric_limits<SEG::ecoord>::max();
1075 SEG::ecoord minDistTarget_sq = std::numeric_limits<SEG::ecoord>::max();
1078 auto findNItem = [&](
ITEM* p_item )
1080 for(
ITEM* n_item : nItems )
1082 SEG::ecoord dist_sq = std::numeric_limits<SEG::ecoord>::max();
1084 if( n_item->Kind() != p_item->Kind() )
1107 const ARC* p_arc =
static_cast<const ARC*
>( p_item );
1108 const ARC* n_arc =
static_cast<const ARC*
>( n_item );
1122 if( dist_sq <= minDist_sq )
1124 SEG::ecoord distTarget_sq = n_item->Shape( -1 )->SquaredDistance( targetPoint );
1125 if( distTarget_sq < minDistTarget_sq )
1127 minDistTarget_sq = distTarget_sq;
1128 minDist_sq = dist_sq;
1131 coupledItem =
static_cast<LINKED_ITEM*
>( n_item );
1137 findNItem( startItem );
1142 std::set<ITEM*> linksToTest;
1153 if( link != linked )
1154 linksToTest.emplace( link );
1158 for(
ITEM* link : linksToTest )
1165 LINE ln =
m_world->AssembleLine( coupledItem,
nullptr,
false,
false,
false );
1167 if(
m_world->GetRuleResolver()->DpNetPolarity( refNet ) < 0 )
1168 std::swap( lp, ln );
1181 const ARC* refArc =
static_cast<ARC*
>( refItem );
1182 const ARC* coupledArc =
static_cast<ARC*
>( coupledItem );
1195 std::deque<ITEM*> pending;
1202 pending.push_back( aStart );
1205 int64_t initialArea = clusterBBox.
GetArea();
1206 std::unordered_set<ITEM*> processed;
1208 while( !pending.empty() )
1213 pending.pop_front();
1215 if( processed.find(
top ) == processed.end() )
1220 processed.insert(
top );
1222 m_world->QueryColliding(
top, obstacles, opts );
1224 for(
const OBSTACLE& obs : obstacles )
1231 if( aExcludedNet && obs.m_item->Net() == aExcludedNet )
1237 clusterBBox.
Merge( line.CLine().BBox() );
1241 clusterBBox.
Merge( obs.m_item->Shape( aLayer )->BBox() );
1244 const int64_t currentArea = clusterBBox.
GetArea();
1245 const double areaRatio = (double) currentArea / (
double) ( initialArea + 1 );
1247 if( aAreaExpansionLimit > 0.0 && areaRatio > aAreaExpansionLimit )
1250 if( processed.find( obs.m_item ) == processed.end() &&
1251 obs.m_item->Layers().Overlaps( aLayer ) && !( obs.m_item->Marker() &
MK_HEAD ) )
1253 processed.insert( obs.m_item );
1254 cluster.
m_items.push_back( obs.m_item );
1255 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.
static constexpr int DP_PARALLELITY_THRESHOLD
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
Return the aIdx-th point of the line.
void SetShape(const SHAPE_LINE_CHAIN &aLine)
Assign a shape to the line (a polyline/line chain).
const SHAPE_LINE_CHAIN & CLine() const
const VECTOR2I & CLastPoint() const
SHAPE_LINE_CHAIN & Line()
Modifiable accessor to the underlying shape.
void Reverse()
Reverse the point/vertex order.
int Width() const
Return line width.
std::vector< LINKED_ITEM * > & Links()
Return the list of links from the owning node that constitute this line (or NULL if the line is not l...
LINKED_ITEM * GetLink(int aIndex) const
virtual void ClearLinks()
Erase the linking information. Used to detach the line from the owning node.
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)
const CLUSTER AssembleCluster(ITEM *aStart, int aLayer, double aAreaExpansionLimit=0.0, NET_HANDLE aExcludedNet=nullptr, int aOverrideClearance=0)
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)
TOPOLOGY(NODE *aNode, ROUTER_IFACE *aIface=nullptr)
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 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...
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