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 )
172 std::set<ITEM*> disconnected;
174 m_world->AllItemsInNet( aStart->
Net(), disconnected );
178 for(
ITEM* link : jt->LinkList() )
180 if( disconnected.find( link ) != disconnected.end() )
181 disconnected.erase( link );
185 int best_dist = INT_MAX;
186 ITEM* best =
nullptr;
188 for(
ITEM* item : disconnected )
190 if( item->OfKind( aKindMask ) )
192 for(
int i = 0; i < item->AnchorCount(); i++ )
195 int d = ( p - aStart->
Pos() ).EuclideanNorm();
214 std::set<ITEM*>& aVisited,
215 bool aFollowLockedSegments )
217 using clock = std::chrono::steady_clock;
220 best.
m_end = aStartJoint;
223 auto startTime = clock::now();
233 std::set<const JOINT*> visitedJoints;
237 std::stack<STATE> stateStack;
241 initial.joint = aStartJoint;
242 initial.prev = aPrev;
243 initial.pathLength = 0;
244 initial.visitedJoints.insert( aStartJoint );
245 initial.via =
nullptr;
247 stateStack.push( std::move( initial ) );
249 while( !stateStack.empty() )
252 auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
253 clock::now() - startTime ).count();
255 if( elapsed > timeoutMs )
257 wxLogTrace( wxT(
"PNS_TUNE" ),
258 wxT(
"followBranch: timeout after %lld ms, returning best path found" ),
263 STATE current = std::move( stateStack.top() );
266 const JOINT* joint = current.joint;
272 for(
ITEM* link : links )
274 if( link->OfKind(
ITEM::VIA_T ) && !aVisited.contains( link ) )
282 bool foundBranch =
false;
284 for(
ITEM* link : links )
289 if( link == current.prev )
292 if( aVisited.contains( link ) )
296 false, aFollowLockedSegments );
304 if( current.visitedJoints.count( nextJoint ) )
311 nextState.joint = nextJoint;
312 nextState.prev = l.
Links().back();
313 nextState.pathItems = current.pathItems;
314 nextState.pathLength = current.pathLength + l.
CLine().
Length();
315 nextState.visitedJoints = current.visitedJoints;
316 nextState.visitedJoints.insert( nextJoint );
321 nextState.pathItems.Add(
via );
323 nextState.pathItems.Add( l );
325 stateStack.push( std::move( nextState ) );
331 if( current.pathLength > best.
m_length )
335 best.
m_items = current.pathItems;
340 wxLogTrace( wxT(
"PNS_TUNE" ),
341 wxT(
"followBranch: completed with best path length=%d, %d items" ),
349 const JOINT** aTerminalJointB,
350 bool aFollowLockedSegments )
354 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"=== followTrivialPath START ===" ) );
355 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"followTrivialPath: initial line has %d segments, %zu links" ),
357 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"followTrivialPath: line endpoints: (%d,%d) to (%d,%d)" ),
364 std::set<ITEM*> visited;
367 visited.insert( link );
372 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"followTrivialPath: LEFT branch starting from joint at (%d,%d)" ),
375 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"followTrivialPath: LEFT branch result: length=%d, %d items" ),
376 left.m_length,
left.m_items.Size() );
378 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"followTrivialPath: RIGHT branch starting from joint at (%d,%d)" ),
381 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"followTrivialPath: RIGHT branch result: length=%d, %d items" ),
384 if( aTerminalJointA )
385 *aTerminalJointA =
left.m_end;
387 if( aTerminalJointB )
388 *aTerminalJointB =
right.m_end;
391 int leftSegCount = 0;
392 int rightSegCount = 0;
393 int initialSegCount = 0;
402 path.Prepend( item );
405 LINE* l =
dynamic_cast<LINE*
>( item );
419 LINE* l =
dynamic_cast<LINE*
>( item );
430 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"" ) );
431 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"=== followTrivialPath SUMMARY ===" ) );
432 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"Starting segment count: %d" ), initialSegCount );
433 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"Left branch: %d segments, length=%d" ), leftSegCount,
left.m_length );
434 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"Initial line: %d segments, length=%lld" ), initialSegCount, aLine2->
CLine().
Length() );
435 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"Right branch: %d segments, length=%d" ), rightSegCount,
right.m_length );
436 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"Total segments in path: %d" ), leftSegCount + initialSegCount + rightSegCount );
437 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"Total path length: %d" ), totalLength );
438 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"Total items in result: %d" ),
path.Size() );
439 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"=== followTrivialPath END ===" ) );
440 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"" ) );
447 std::pair<const JOINT*, const JOINT*>* aTerminalJoints,
448 bool aFollowLockedSegments )
450 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"*** AssembleTrivialPath: START ***" ) );
451 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTrivialPath: aStart=%p, kind=%s" ),
452 aStart, aStart->
KindStr().c_str() );
459 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTrivialPath: starting from VIA" ) );
465 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTrivialPath: VIA is fanout, returning empty" ) );
471 for(
ITEM* item : links )
476 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTrivialPath: found segment/arc from VIA" ) );
484 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTrivialPath: starting from SEGMENT/ARC" ) );
489 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTrivialPath: no segment found, returning empty" ) );
495 LINE l =
m_world->AssembleLine( seg,
nullptr,
false, aFollowLockedSegments );
497 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTrivialPath: assembled line with %d segments, length=%lld" ),
500 const JOINT* jointA =
nullptr;
501 const JOINT* jointB =
nullptr;
505 if( aTerminalJoints )
507 wxASSERT( jointA && jointB );
508 *aTerminalJoints = std::make_pair( jointA, jointB );
509 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTrivialPath: terminal joints at (%d,%d) and (%d,%d)" ),
513 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTrivialPath: returning path with %d items" ),
path.Size() );
514 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"*** AssembleTrivialPath: END ***" ) );
515 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"" ) );
531 m_world->QueryColliding( aVia, obstacles, opts );
534 std::set<LINKED_ITEM*> assembled;
541 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"findLinesFromVia: VIA at (%d,%d), net=%p, %zu obstacles" ), aVia->
Pos().
x,
542 aVia->
Pos().
y, net, obstacles.size() );
544 for(
const OBSTACLE& obs : obstacles )
546 if( obs.m_item->Net() != net )
551 if( aVisited.contains( linked ) )
554 if( assembled.contains( linked ) )
561 bool anchor0Inside, anchor1Inside;
573 anchor0Inside = shape && shape->
Collide( anchor0, 0 );
574 anchor1Inside = shape && shape->
Collide( anchor1, 0 );
577 if( !anchor0Inside && !anchor1Inside )
579 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
" skip collision: layer=%d anchor0=(%d,%d) anchor1=(%d,%d)" ),
580 linked->
Layer(), anchor0.
x, anchor0.
y, anchor1.
x, anchor1.
y );
584 LINE l =
m_world->AssembleLine( linked,
nullptr,
false,
true );
587 assembled.insert( link );
597 const std::set<ITEM*>& aVisited )
599 using clock = std::chrono::steady_clock;
605 auto startTime = clock::now();
612 std::set<ITEM*> visited;
615 std::stack<STATE> stateStack;
618 initial.endpoint = aStartFromBack ? aStartLine.
CLastPoint() : aStartLine.
CPoint( 0 );
619 initial.pathLength = 0;
620 initial.visited = aVisited;
621 stateStack.push( std::move( initial ) );
623 while( !stateStack.empty() )
625 auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>( clock::now() - startTime ).count();
627 if( elapsed > timeoutMs )
629 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"walkTuningPath: timeout after %lld ms" ), elapsed );
633 STATE current = std::move( stateStack.top() );
640 for(
ITEM* item : hits )
642 if( item->OfKind(
ITEM::SOLID_T ) && item->Net() == net && !current.visited.contains( item ) )
651 if( current.pathLength > best.
m_length )
654 best.
m_items = current.pathItems;
659 current.visited.insert(
pad );
661 for(
ITEM* item : hits )
666 if( item->Net() != net || current.visited.contains( item ) )
672 bool startNear = ( contLine.
CPoint( 0 ) - ep ).SquaredEuclideanNorm()
673 <= ( contLine.
CLastPoint() - ep ).SquaredEuclideanNorm();
676 nextState.endpoint = startNear ? contLine.
CLastPoint() : contLine.
CPoint( 0 );
677 nextState.pathItems = current.pathItems;
678 nextState.pathItems.Add( contLine );
679 nextState.pathLength = current.pathLength + contLine.
CLine().
Length();
680 nextState.visited = current.visited;
683 nextState.visited.insert( link );
685 stateStack.push( std::move( nextState ) );
693 for(
ITEM* item : hits )
695 if( item->OfKind(
ITEM::VIA_T ) && item->Net() == net && !item->IsVirtual()
696 && !current.visited.contains( item ) )
698 via =
static_cast<VIA*
>( item );
705 current.visited.insert(
via );
709 for(
LINE& contLine : continuations )
712 bool startNearVia = ( contLine.CPoint( 0 ) - ep ).SquaredEuclideanNorm()
713 <= ( contLine.CLastPoint() - ep ).SquaredEuclideanNorm();
715 VECTOR2I forwardEndpoint = startNearVia ? contLine.CLastPoint() : contLine.CPoint( 0 );
717 int64_t contLength = contLine.CLine().Length();
726 contLength = clipped.
Length();
730 nextState.endpoint = forwardEndpoint;
731 nextState.pathItems = current.pathItems;
732 nextState.pathItems.Add(
via );
733 nextState.pathItems.Add( contLine );
734 nextState.pathLength = current.pathLength + contLength;
735 nextState.visited = current.visited;
738 nextState.visited.insert( link );
740 stateStack.push( std::move( nextState ) );
743 if( continuations.empty() )
745 if( current.pathLength > best.
m_length )
748 best.
m_items = current.pathItems;
756 if( current.pathLength > best.
m_length )
759 best.
m_items = current.pathItems;
765 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"walkTuningPath: completed, best length=%lld, %d items, pad=%p" ),
775 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"" ) );
776 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"########## AssembleTuningPath: START ##########" ) );
777 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTuningPath: aStart=%p, kind=%s" ),
778 aStart, aStart->
KindStr().c_str() );
792 for(
ITEM* item : links )
806 if( continuations.empty() )
808 wxLogTrace( wxT(
"PNS_TUNE" ),
809 wxT(
"AssembleTuningPath: no via continuation found, returning empty" ) );
813 for(
LINKED_ITEM* link : continuations.front().Links() )
830 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTuningPath: no segment found, returning empty" ) );
834 LINE l =
m_world->AssembleLine( seg,
nullptr,
false,
true );
836 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTuningPath: initial line %d segments, length=%lld" ), l.
SegmentCount(),
839 std::set<ITEM*> visited;
842 visited.insert( link );
844 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTuningPath: walking LEFT from (%d,%d)" ), l.
CPoint( 0 ).
x,
848 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTuningPath: walking RIGHT from (%d,%d)" ), l.
CLastPoint().
x,
855 path.Prepend( item );
871 padA =
static_cast<PAD*
>( bi );
874 *aStartPad =
left.m_endPad;
876 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTuningPath: found start pad" ) );
886 padB =
static_cast<PAD*
>( bi );
889 *aEndPad =
right.m_endPad;
891 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTuningPath: found end pad" ) );
897 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTuningPath: no pads found, returning path" ) );
898 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"########## AssembleTuningPath: END ##########" ) );
902 auto processPad = [&](
PAD* aPad )
904 for(
int idx = 0; idx <
path.Size(); idx++ )
923 std::set<PAD*> processedPads;
926 processedPads.insert( padA );
929 processedPads.insert( padB );
931 for(
int idx = 0; idx <
path.Size(); idx++ )
942 for(
ITEM* item : hits )
951 PAD* intermediatePad =
static_cast<PAD*
>( bi );
953 if( processedPads.find( intermediatePad ) == processedPads.end() )
955 wxLogTrace( wxT(
"PNS_TUNE" ),
956 wxT(
"AssembleTuningPath: processing intermediate"
959 processPad( intermediatePad );
960 processedPads.insert( intermediatePad );
971 for(
int idx = 0; idx <
path.Size(); idx++ )
984 for(
int delta : { -1, 1 } )
999 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"AssembleTuningPath: final path has %d items" ),
path.Size() );
1000 wxLogTrace( wxT(
"PNS_TUNE" ), wxT(
"########## AssembleTuningPath: END ##########" ) );
1027 if( !coupledNet || !startItem )
1032 std::vector<ITEM*> pItems;
1033 std::vector<ITEM*> nItems;
1038 pItems.push_back( item );
1041 std::set<ITEM*> coupledItems;
1042 m_world->AllItemsInNet( coupledNet, coupledItems );
1044 for(
ITEM* item : coupledItems )
1047 nItems.push_back( item );
1052 SEG::ecoord minDist_sq = std::numeric_limits<SEG::ecoord>::max();
1053 SEG::ecoord minDistTarget_sq = std::numeric_limits<SEG::ecoord>::max();
1056 auto findNItem = [&](
ITEM* p_item )
1058 for(
ITEM* n_item : nItems )
1060 SEG::ecoord dist_sq = std::numeric_limits<SEG::ecoord>::max();
1062 if( n_item->Kind() != p_item->Kind() )
1085 const ARC* p_arc =
static_cast<const ARC*
>( p_item );
1086 const ARC* n_arc =
static_cast<const ARC*
>( n_item );
1100 if( dist_sq <= minDist_sq )
1102 SEG::ecoord distTarget_sq = n_item->Shape( -1 )->SquaredDistance( targetPoint );
1103 if( distTarget_sq < minDistTarget_sq )
1105 minDistTarget_sq = distTarget_sq;
1106 minDist_sq = dist_sq;
1109 coupledItem =
static_cast<LINKED_ITEM*
>( n_item );
1115 findNItem( startItem );
1120 std::set<ITEM*> linksToTest;
1131 if( link != linked )
1132 linksToTest.emplace( link );
1136 for(
ITEM* link : linksToTest )
1145 if(
m_world->GetRuleResolver()->DpNetPolarity( refNet ) < 0 )
1146 std::swap( lp, ln );
1159 const ARC* refArc =
static_cast<ARC*
>( refItem );
1160 const ARC* coupledArc =
static_cast<ARC*
>( coupledItem );
1175 std::deque<ITEM*> pending;
1182 pending.push_back( aStart );
1185 int64_t initialArea = clusterBBox.
GetArea();
1186 std::unordered_set<ITEM*> processed;
1188 while( !pending.empty() )
1193 pending.pop_front();
1195 if( processed.find(
top ) == processed.end() )
1200 processed.insert(
top );
1202 m_world->QueryColliding(
top, obstacles, opts );
1204 for(
const OBSTACLE& obs : obstacles )
1211 if( aExcludedNet && obs.m_item->Net() == aExcludedNet )
1217 clusterBBox.
Merge( line.CLine().BBox() );
1221 clusterBBox.
Merge( obs.m_item->Shape( aLayer )->BBox() );
1224 const int64_t currentArea = clusterBBox.
GetArea();
1225 const double areaRatio = (double) currentArea / (
double) ( initialArea + 1 );
1227 if( aAreaExpansionLimit > 0.0 && areaRatio > aAreaExpansionLimit )
1230 if( processed.find( obs.m_item ) == processed.end() &&
1231 obs.m_item->Layers().Overlaps( aLayer ) && !( obs.m_item->Marker() &
MK_HEAD ) )
1233 processed.insert( obs.m_item );
1234 cluster.
m_items.push_back( obs.m_item );
1235 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