101 if(
m_tail.SegmentCount() == 0 )
108 std::vector<SHAPE_LINE_CHAIN::INTERSECTION> ips;
140 if( i.index_our < n )
215 bool pullback_1 =
false;
222 if( pullback_1 || pullback_2 )
237 PNS_DBG(
Dbg(), Message, wxString::Format(
"Placer: pullback triggered [%d] [%s %s]",
277 int reduce_index = -1;
304 if( reduce_index >= 0 )
306 PNS_DBG(
Dbg(), Message, wxString::Format(
"Placer: reducing tail: %d" , reduce_index ) );
310 tail.
Remove( reduce_index + 1, -1 );
339 PNS_DBG(
Dbg(), Message, wxT(
"Merge failed: not enough head segs." ) );
345 PNS_DBG(
Dbg(), Message, wxT(
"Merge failed: head and tail discontinuous." ) );
349 if(
m_head.CountCorners( ForbiddenAngles ) != 0 )
369 if( dir_head.
Angle( dir_tail ) & ForbiddenAngles )
386 PNS_DBG(
Dbg(), Message, wxString::Format(
"Placer: merge %d, new direction: %s" , n_head,
400 int idx = l.
Split( aP );
410 PNS_DBG(
Dbg(), AddPoint, aP,
BLUE, 500000, wxString::Format(
"hug-target-check-%d", idx ) );
411 PNS_DBG(
Dbg(), AddShape, &l2,
BLUE, 500000, wxT(
"hug-target-line" ) );
413 if( dist < thresholdDist )
423 aOut = std::move( l2 );
424 thresholdDist = dist;
434 std::vector<int> dists;
435 std::vector<VECTOR2I> pts;
441 int accumulatedDist = 0;
449 dists.push_back( ( aCursor - s.
A ).EuclideanNorm() );
450 pts.push_back( s.
A );
453 if( pn != s.
A && pn != s.
B )
455 dists.push_back( ( pn - aCursor ).EuclideanNorm() );
459 accumulatedDist += s.
Length();
461 if ( accumulatedDist > lengthThreshold )
468 dists.push_back( ( aCursor - lastP ).EuclideanNorm() );
469 pts.push_back( lastP );
471 int minDistLoc = std::numeric_limits<int>::max();
473 int minDistGlob = std::numeric_limits<int>::max();
476 for(
int i = 0; i < (int) dists.size(); i++ )
480 if( d < minDistGlob )
487 if( dists.size() >= 3 )
489 for(
int i = 0; i < (int) dists.size() - 3; i++ )
491 if( dists[i + 2] > dists[i + 1] && dists[i] > dists[i + 1] )
493 int d = dists[i + 1];
502 if( dists.back() < minDistLoc && minPLoc >= 0 )
504 minDistLoc = dists.back();
505 minPLoc = dists.size() - 1;
511 minDistLoc = minDistGlob;
522 preferred = minPGlob;
529 int thresholdDist = 0;
540 for(
int i = 0; i < (int) pts.size() ; i++)
577 PNS_DBG(
Dbg(), BeginGroup, wxString::Format(
"walk-round-%d", round ), 0 );
581 PNS_DBG(
Dbg(), AddItem, &l1,
BLUE, 20000, wxT(
"walk-base-l1" ) );
593 double hugThresholdLengthComplete =
597 std::optional<LINE> bestLine;
608 : std::numeric_limits<int>::max();
610 : std::numeric_limits<int>::max();
616 LINE tmpHead, tmpTail;
628 PNS_DBG(
Dbg(), AddItem, &wr.
lines[WP_CW],
RED, 20000, wxT(
"wf-result-cw-postopt" ) );
630 bestLine = wr.
lines[WP_CW];
637 LINE tmpHead, tmpTail;
648 PNS_DBG(
Dbg(), AddItem, &wr.
lines[WP_CCW],
RED, 20000, wxT(
"wf-result-ccw-postopt" ) );
651 if( len_ccw < len_cw )
652 bestLine = wr.
lines[WP_CCW];
655 int bestLength = len_cw < len_ccw ? len_cw : len_ccw;
657 if( bestLength < hugThresholdLengthComplete && bestLine.has_value() )
659 walkFull.
SetShape( bestLine->CLine() );
665 bool validCw =
false;
666 bool validCcw =
false;
667 int distCcw = std::numeric_limits<int>::max();
668 int distCw = std::numeric_limits<int>::max();
678 distCw = ( aP - l_cw.
CLastPoint() ).EuclideanNorm();
680 PNS_DBG(
Dbg(), AddShape, &l_cw,
MAGENTA, 200000, wxString::Format(
"wh-result-cw %s",
681 validCw ?
"non-colliding"
690 distCcw = ( aP - l_ccw.
CLastPoint() ).EuclideanNorm();
692 PNS_DBG(
Dbg(), AddShape, &l_ccw,
MAGENTA, 200000, wxString::Format(
"wh-result-ccw %s",
693 validCcw ?
"non-colliding"
698 if( distCw < distCcw && validCw )
725 PNS_DBG(
Dbg(), AddItem, &walkFull,
GREEN, 200000, wxT(
"walk-full" ) );
730 wxString::Format(
"walk-via ok %d", aViaOk ? 1 : 0 ) );
733 aWalkLine = walkFull;
749 switch(
Settings().OptimizerEffort() )
773 PNS_DBG(
Dbg(), AddItem, &walkFull,
GREEN, 100000, wxString::Format(
"collision check fail" ) );
803 PNS_DBG(
Dbg(), AddItem, &aNewHead,
GREEN, 100000, wxString::Format(
"walk-new-head" ) );
804 PNS_DBG(
Dbg(), AddItem, &aNewTail,
BLUE, 100000, wxT(
"walk-new-tail" ) );
813 m_head.SetBlockingObstacle(
nullptr );
834 if( ( nearest - aP ).EuclideanNorm() <
m_head.Width() / 2 )
843 if( !
Settings().AllowDRCViolations() )
847 if( obs && obs->m_distFirst != INT_MAX )
850 m_head.SetBlockingObstacle( obs->m_item );
865 LINE newTail( aOldTail );
866 LINE newHead( aOldTail );
911 newHead = std::move( l2 );
914 PNS_DBG(
Dbg(), AddItem, &newHead,
BLUE, 500000, wxT(
"head-post-split" ) );
916 aNewHead = std::move( newHead );
917 aNewTail = std::move( newTail );
946 m_shove->SetSpringbackDoNotTouchNode(
nullptr );
949 LINE newHead( walkSolids );
952 PNS_DBG(
Dbg(), AddPoint, newHead.
Via().
Pos(),
RED, 1000000, wxString::Format(
"SVIA [%d]", viaOk?1:0 ) );
969 switch(
Settings().OptimizerEffort() )
994 newHead =
m_shove->GetModifiedHead( 0 );
1009 PNS_DBG(
Dbg(), AddItem, &aNewHead,
GREEN, 1000000,
"head-sh-postopt" );
1063 int tailLookbackSegments = 3;
1068 int threshold = std::min( tail.
PointCount(), tailLookbackSegments + 1 );
1115 bool go_back =
false;
1120 PNS_DBG(
Dbg(), Message, wxString::Format(
"routeStep: direction: %s head: %d, tail: %d shapes" ,
1125 PNS_DBG(
Dbg(), BeginGroup, wxT(
"route-step" ), 0 );
1130 for( i = 0; i < n_iter; i++ )
1134 LINE newHead, newTail;
1136 if( !go_back &&
Settings().FollowMouse() )
1146 if( !
routeHead( aP, newHead, newTail ) )
1148 m_tail = std::move( prevTail );
1149 m_head = std::move( prevHead );
1154 if(
m_tail.PointCount() == 0 )
1165 PNS_DBG(
Dbg(), AddItem, &newHead,
LIGHTGREEN, 100000, wxString::Format(
"new_head [fail: %d]", fail?1:0 ) );
1170 PNS_DBG(
Dbg(), Message, wxString::Format(
"N VIA H %d T %d\n",
m_head.EndsWithVia() ? 1 : 0,
m_tail.EndsWithVia() ? 1 : 0 ) );
1172 m_head = std::move( newHead );
1173 m_tail = std::move( newTail );
1181 PNS_DBG(
Dbg(), Message, wxString::Format(
"SI VIA H %d T %d\n",
m_head.EndsWithVia() ? 1 : 0,
m_tail.EndsWithVia() ? 1 : 0 ) );
1193 PNS_DBG(
Dbg(), Message, wxString::Format(
"PB VIA H %d T %d\n",
m_head.EndsWithVia() ? 1 : 0,
m_tail.EndsWithVia() ? 1 : 0 ) );
1200 if( !fail &&
Settings().FollowMouse() )
1207 PNS_DBG(
Dbg(), Message, wxString::Format(
"PreM VIA H %d T %d\n",
m_head.EndsWithVia() ? 1 : 0,
m_tail.EndsWithVia() ? 1 : 0 ) );
1211 PNS_DBG(
Dbg(), Message, wxString::Format(
"PostM VIA H %d T %d\n",
m_head.EndsWithVia() ? 1 : 0,
m_tail.EndsWithVia() ? 1 : 0 ) );
1352 SEG seg =
static_cast<SEGMENT*
>( aStartItem )->Seg();
1356 else if( aP == seg.
B )
1362 double angle =
static_cast<SOLID*
>( aStartItem )->GetOrientation().AsDegrees();
1367 PNS_DBG(
Dbg(), Message, wxString::Format(
"Posture: init %s, last seg %s",
1417 wxLogTrace( wxT(
"PNS" ), wxT(
"world %p, intitial-direction %s layer %d" ),
1434 if( aEndItem && aEndItem->
Owner() )
1435 eiDepth =
static_cast<const NODE*
>( aEndItem->
Owner() )->
Depth();
1445 bool reachesEnd =
route( aP );
1456 m_head.AppendVia( fallbackVia );
1466 const SEG targetSeg =
static_cast<SEGMENT*
>( aEndItem )->Seg();
1487 && aEndItem && latestNode->
Depth() >= eiDepth
1506 bool realEnd =
false;
1524 else if(
m_router->GetInterface()->GetNetCode( aEndItem->
Net() ) <= 0 )
1535 if( !
Settings().AllowDRCViolations() )
1557 m_lastNode->GetUpdatedItems( removed, added );
1617 for(
int i = 0; i < lastV; i++ )
1619 ssize_t arcIndex = l.
ArcIndex( i );
1621 if( arcIndex < 0 || ( lastArc >= 0 && i == lastV - 1 && !l.
IsPtOnArc( lastV ) ) )
1627 std::unique_ptr<SEGMENT> sp = std::make_unique<SEGMENT>( seg );
1628 lastItem = sp.get();
1635 if( arcIndex == lastArc )
1642 std::unique_ptr<ARC> ap = std::make_unique<ARC>( arc );
1643 lastItem = ap.get();
1663 if( realEnd &&
Settings().RemoveLoops() )
1716 std::optional<VECTOR2I> ret;
1721 if(
m_head.Line().PointCount() )
1722 ret =
m_head.Line().CPoint( 0 );
1772 m_shove->RewindToLastLockedNode();
1796 std::set<ITEM*> cleanup;
1804 SEG refSeg =
static_cast<SEGMENT*
>( aItem )->Seg();
1810 if( neighbor == aItem
1812 || !neighbor->LayersOverlap( aItem ) )
1817 if(
static_cast<const SEGMENT*
>( neighbor )->Width()
1818 !=
static_cast<const SEGMENT*
>( aItem )->Width() )
1823 const SEG& testSeg =
static_cast<const SEGMENT*
>( neighbor )->Seg();
1827 const JOINT* nA = aNode->
FindJoint( neighbor->Anchor( 0 ), neighbor );
1828 const JOINT* nB = aNode->
FindJoint( neighbor->Anchor( 1 ), neighbor );
1830 if( ( nA == aJoint && nB->
LinkCount() == 1 ) ||
1831 ( nB == aJoint && nA->
LinkCount() == 1 ) )
1833 cleanup.insert( neighbor );
1836 else if( testSeg.
Contains( refSeg ) )
1841 if( ( aA == aJoint && aB->
LinkCount() == 1 ) ||
1842 ( aB == aJoint && aA->
LinkCount() == 1 ) )
1844 cleanup.insert( aItem );
1851 for(
ITEM* item : added )
1859 processJoint( jA, item );
1860 processJoint( jB, item );
1863 for(
ITEM* seg : cleanup )
1868 LINE l_orig = aNode->
AssembleLine( aLatest,
nullptr,
false,
false,
false );
1882 PNS_DBG(
Dbg(), AddItem, &l,
RED, 100000, wxT(
"simplified"));
1898 if(
m_sizes.TrackWidthIsExplicit()
1906 if(
m_head.EndsWithVia() )
1937 PNS_DBG(
Dbg(), Message, wxString::Format( wxT(
"buildInitialLine: m_direction %s, guessedDir %s, tail points %d" ),
1952 if(
m_tail.SegmentCount() == 1 &&
m_head.SegmentCount() > 0 )
1955 if( dirMatch ||
m_head.SegmentCount() == 1 )
1975 if( !
m_tail.PointCount() )
1993 PNS_DBG(
Dbg(), AddItem, &aHead,
CYAN, 10000, wxT(
"initial-trace" ) );
2011 for(
int attempt = 0; attempt < 2; attempt++)
2022 aHead =
LINE( aHead, line );
2082 st.
pts.push_back(pt);
2085 m_stages.push_back( std::move( st ) );
2112 || aJoin == aEndItem->
Anchor( 0 ) || aJoin == aEndItem->
Anchor( 1 ) )
2122 std::vector<const ITEM*> newLinks;
2127 newLinks.push_back( item );
2130 if( newLinks.empty() )
2133 auto reachesAnchor = [&](
const JOINT* aStart,
bool aIncludeNew,
bool aSkipTarget )
2135 std::vector<const JOINT*> pending = { aStart };
2136 std::set<const JOINT*> visited;
2138 while( !pending.empty() )
2140 const JOINT* joint = pending.back();
2143 if( !joint || joint->
Pos() == aJoin || !visited.insert( joint ).second )
2148 if( item->IsVirtual() || ( !aIncludeNew && !item->Parent() )
2149 || ( aSkipTarget && item->Parent() == aEndItem->
Parent() ) )
2159 if( item->Anchor(
end ) != joint->
Pos() )
2160 pending.push_back( aNode->
FindJoint( item->Anchor(
end ), item ) );
2169 bool newRouteAnchored =
false;
2171 for(
const ITEM* item : newLinks )
2175 if( item->Anchor(
end ) != aJoin
2176 && reachesAnchor( aNode->
FindJoint( item->Anchor(
end ), item ),
true,
true ) )
2178 newRouteAnchored =
true;
2183 if( newRouteAnchored )
2187 if( !newRouteAnchored )
2190 std::vector<std::vector<LINKED_ITEM*>>
candidates;
2191 bool hasAnchoredSide =
false;
2192 int targetSides = 0;
2202 if( link->
Anchor( 0 ) != aJoin && link->
Anchor( 1 ) != aJoin )
2207 if( reachesAnchor( aNode->
FindJoint( farEnd, link ),
false,
false ) )
2209 hasAnchoredSide =
true;
2214 std::vector<LINKED_ITEM*> branch;
2215 std::set<LINKED_ITEM*> seen;
2219 if( link->
Anchor( 0 ) != from && link->
Anchor( 1 ) != from )
2222 if(
Router()->GetInterface()->TouchesCopperZone( link ) )
2224 hasAnchoredSide =
true;
2228 branch.push_back( link );
2236 if(
end->LinkCount() == 1 )
2242 if(
end->LinkCount() != 2 )
2247 for(
ITEM* adjacent :
end->LinkList() )
2259 if( ( targetSides == 2 && hasAnchoredSide ) || targetSides == 1 )
2261 for(
const std::vector<LINKED_ITEM*>& branch :
candidates )
2264 aNode->
Remove( segment );
2278 std::set<LINKED_ITEM *> toErase;
2280 aNode->
Add( aLatest,
true );
2282 for(
int s = 0; s < aLatest.
LinkCount(); s++ )
2287 std::vector<LINE> lines;
2296 int removedCount = 0;
2299 for(
LINE& line : lines )
2303 if( !( line.ContainsLink( seg ) ) && line.SegmentCount() )
2306 bool hasLockedSegment =
false;
2309 if( ss->IsLocked() )
2311 hasLockedSegment =
true;
2316 if( !hasLockedSegment )
2319 toErase.insert( ss );
2326 PNS_DBG(
Dbg(), Message, wxString::Format(
"total segs removed: %d/%d", removedCount, total ) );
2332 aNode->
Remove( aLatest );
constexpr Vec NearestPoint(const Vec &aPoint) const
Return the point in this rect that is closest to the provided point.
Represent route directions & corner angles in a 45-degree metric.
const SHAPE_LINE_CHAIN BuildInitialTrace(const VECTOR2I &aP0, const VECTOR2I &aP1, bool aStartDiagonal=false, CORNER_MODE aMode=CORNER_MODE::MITERED_45) const
Build a 2-segment line chain between points aP0 and aP1 and following 45-degree routing regime.
AngleType Angle(const DIRECTION_45 &aOther) const
Return the type of angle between directions (this) and aOther.
AngleType
Represent kind of angle formed by vectors heading in two DIRECTION_45s.
Directions
Available directions, there are 8 of them, as on a rectilinear map (north = up) + an extra undefined ...
@ ROUNDED_90
H/V with filleted corners.
@ MITERED_90
H/V only (90-degree corners)
@ ROUNDED_45
H/V/45 with filleted corners.
@ MITERED_45
H/V/45 with mitered corners (default)
const std::string Format() const
Format the direction in a human readable word.
KICAD_T Type() const
Returns the type of object.
void SetDebugDecorator(DEBUG_DECORATOR *aDecorator)
Assign a debug decorator allowing this algo to draw extra graphics for visual debugging.
void SetLogger(LOGGER *aLogger)
virtual LOGGER * Logger()
Return the logger object, allowing to dump geometry to a file.
ROUTER * Router() const
Return the instance of our router.
ROUTING_SETTINGS & Settings() const
Return current router settings.
DEBUG_DECORATOR * Dbg() const
void SetWidth(int aWidth) override
FIXED_TAIL(int aLineCount=1)
bool PopStage(STAGE &aStage)
void AddStage(const VECTOR2I &aStart, int aLayer, bool placingVias, DIRECTION_45 direction, NODE *aNode)
std::vector< STAGE > m_stages
const std::vector< ITEM * > & CItems() const
Base class for PNS router board items.
BOARD_ITEM * Parent() const
virtual NET_HANDLE Net() const
PnsKind Kind() const
Return the type (kind) of the item.
void SetNet(NET_HANDLE aNet)
void SetLayer(int aLayer)
bool OfKind(int aKindMask) const
virtual VECTOR2I Anchor(int n) 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
int LinkCount(int aMask=-1) const
bool IsLineCorner(bool aAllowLockedSegs=false) const
Check if a joint connects two segments of the same net, layer, and width.
const ITEM_SET & CLinks() const
const VECTOR2I & Pos() const
bool mergeHead()
Moves "established" segments from the head to the tail if certain conditions are met.
bool handleSelfIntersections()
Check if the head of the track intersects its tail.
LINE_PLACER(ROUTER *aRouter)
bool SetLayer(int aLayer) override
Set the current routing layer.
NODE * m_lastNode
Postprocessed world state (including marked collisions & removed loops)
bool route(const VECTOR2I &aP)
Re-route the current track to point aP.
void updatePStart(const LINE &tail)
bool AbortPlacement() override
std::unique_ptr< SHOVE > m_shove
The shove engine.
const LINE Trace() const
Return the complete routed line.
bool splitHeadTail(const LINE &aNewLine, const LINE &aOldTail, LINE &aNewHead, LINE &aNewTail)
bool handlePullback()
Deal with pull-back: reduces the tail if head trace is moved backwards wrs to the current tail direct...
void setWorld(NODE *aWorld)
Set the board to route.
void UpdateSizes(const SIZES_SETTINGS &aSizes) override
Perform on-the-fly update of the width, via diameter & drill size from a settings class.
bool reduceTail(const VECTOR2I &aEnd)
Attempt to reduce the number of segments in the tail by trying to replace a certain number of latest ...
void SetOrthoMode(bool aOrthoMode) override
Force the router to place a straight 90/45 degree trace (with the end as near to the cursor as possib...
LINE m_tail
routing "tail": part of the track that has been already fixed due to collisions with obstacles
MOUSE_TRAIL_TRACER m_mouseTrailTracer
bool Start(const VECTOR2I &aP, ITEM *aStartItem) override
Start routing a single track at point aP, taking item aStartItem as anchor (unless NULL).
std::optional< VECTOR2I > m_last_p_end
bool optimizeTailHeadTransition()
Try to reduce the corner count of the most recent part of tail/head by merging obtuse/collinear segme...
bool HasPlacedAnything() const override
void routeStep(const VECTOR2I &aP)
Perform a single routing algorithm step, for the end point aP.
NODE * m_currentNode
Current world state.
bool buildInitialLine(const VECTOR2I &aP, LINE &aHead, PNS::PNS_MODE aMode, bool aForceNoVia=false)
bool cursorDistMinimum(const SHAPE_LINE_CHAIN &aL, const VECTOR2I &aCursor, double lengthThreshold, SHAPE_LINE_CHAIN &aOut)
LINE m_head
the volatile part of the track from the previously analyzed point to the current routing destination
VECTOR2I m_fixStart
start point of the last 'fix'
bool rhMarkObstacles(const VECTOR2I &aP, LINE &aNewHead, LINE &aNewTail)
Route step mark obstacles mode.
NODE * m_world
pointer to world to search colliding items
DIRECTION_45 m_initial_direction
routing direction for new traces
NODE * CurrentNode(bool aLoopsRemoved=false) const override
Return the most recent world state.
bool rhWalkBase(const VECTOR2I &aP, LINE &aWalkLine, int aCollisionMask, PNS::PNS_MODE aMode, bool &aViaOk)
void setInitialDirection(const DIRECTION_45 &aDirection)
Set preferred direction of the very first track segment to be laid.
void updateLeadingRatLine()
Draw the "leading" rats nest line, which connects the end of currently routed track and the nearest y...
bool routeHead(const VECTOR2I &aP, LINE &aNewHead, LINE &aNewTail)
Compute the head trace between the current start point (m_p_start) and point aP, starting with direct...
bool rhWalkOnly(const VECTOR2I &aP, LINE &aNewHead, LINE &aNewTail)
Route step walk around mode.
void FlipPosture() override
Toggle the current posture (straight/diagonal) of the trace head.
const VIA makeVia(const VECTOR2I &aP)
bool rhShoveOnly(const VECTOR2I &aP, LINE &aNewHead, LINE &aNewTail)
Route step shove mode.
bool CommitPlacement() override
VECTOR2I m_p_start
current routing start (end of tail, beginning of head)
void GetModifiedNets(std::vector< NET_HANDLE > &aNets) const override
Return the nets of all currently routed trace(s)
bool Move(const VECTOR2I &aP, ITEM *aEndItem) override
Move the end of the currently routed trace to the point aP, taking aEndItem as anchor (if not NULL).
void removeAntennas(NODE *aNode, const ITEM *aEndItem, const VECTOR2I &aJoin)
DIRECTION_45 m_direction
current routing direction
void initPlacement()
Initialize placement of a new line with given parameters.
const ITEM_SET Traces() override
Return the complete routed line, as a single-member ITEM_SET.
bool FixRoute(const VECTOR2I &aP, ITEM *aEndItem, bool aForceFinish) override
Commit the currently routed track to the parent node taking aP as the final end point and aEndItem as...
std::optional< VECTOR2I > UnfixRoute() override
bool ToggleVia(bool aEnabled) override
Enable/disable a via at the end of currently routed trace.
bool clipAndCheckCollisions(const VECTOR2I &aP, const SHAPE_LINE_CHAIN &aL, SHAPE_LINE_CHAIN &aOut, int &thresholdDist)
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 AppendVia(const VIA &aVia)
const SEG CSegment(int aIdx) const
int Width() const
Return line width.
LINKED_ITEM * GetLink(int aIndex) const
int LinkCount() const
Return the number of segments that were assembled together to form this line.
virtual void ClearLinks()
Erase the linking information. Used to detach the line from the owning node.
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...
int FindLinesBetweenJoints(const JOINT &aA, const JOINT &aB, std::vector< LINE > &aLines)
Find all lines between a pair of joints. Used by the loop removal procedure.
std::vector< ITEM * > ITEM_VECTOR
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.
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.
std::optional< OBSTACLE > OPT_OBSTACLE
int Depth() const
Return the number of nodes in the inheritance chain (wrs to the root node).
void FindLineEnds(const LINE &aLine, JOINT &aA, JOINT &aB)
Find the joints corresponding to the ends of line aLine.
bool Add(std::unique_ptr< SEGMENT > aSegment, bool aAllowRedundant=false)
Add an item to the current node.
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.
void KillChildren()
Destroy all child nodes. Applicable only to the root node.
void Remove(ARC *aArc)
Remove an item from this branch.
Perform various optimizations of the lines being routed, attempting to make the lines shorter and les...
void SetCollisionMask(int aMask)
void SetEffortLevel(int aEffort)
static bool Optimize(LINE *aLine, int aEffortLevel, NODE *aWorld, const VECTOR2I &aV=VECTOR2I(0, 0))
A quick shortcut to optimize a line without creating and setting up an optimizer.
@ SMART_PADS
Reroute pad exits.
@ FANOUT_CLEANUP
Simplify pad-pad and pad-via connections if possible.
@ MERGE_SEGMENTS
Reduce corner cost iteratively.
@ MERGE_COLINEAR
Merge co-linear segments.
const ITEM_OWNER * Owner() const
Return the owner of this item, or NULL if there's none.
virtual bool removeLoops(NODE *aNode, LINE &aLatest)
PLACEMENT_ALGO(ROUTER *aRouter)
virtual bool simplifyNewLine(NODE *aNode, LINKED_ITEM *aLatest)
Assemble a line starting from segment or arc aLatest, removes collinear segments and redundant vertic...
PNS_LAYER_RANGE GetViaLayerRange(const SIZES_SETTINGS &aSizes) const
Return the layer span a via placed with aSizes occupies.
virtual NET_HANDLE GetOrphanedNetHandle()=0
ROUTER_IFACE * GetInterface() const
int ViaForcePropIterationLimit() const
double WalkaroundHugLengthThreshold() const
bool GetFixAllSegments() const
PNS_MODE Mode() const
Return the routing mode.
DIRECTION_45::CORNER_MODE GetCornerMode() const
void SetWidth(int aWidth) override
bool LeadingRatLine(const LINE *aTrack, SHAPE_LINE_CHAIN &aRatLine)
const VECTOR2I & Pos() const
bool PushoutForce(NODE *aNode, const VECTOR2I &aDirection, VECTOR2I &aForce, int aCollisionMask=ITEM::ANY_T, int aMaxIterations=10)
void SetPos(const VECTOR2I &aPos)
void SetIterationLimit(const int aIterLimit)
void SetSolidsOnly(bool aSolidsOnly)
STATUS Route(const LINE &aInitialPath, LINE &aWalkPath, bool aOptimize=true)
void SetItemMask(int aMask)
void SetAllowedPolicies(std::vector< WALK_POLICY > aPolicies)
Represent a contiguous set of PCB layers.
const VECTOR2I NearestPoint(const VECTOR2I &aP) const
Compute a point on the segment (this) that is closest to point aP.
int Length() const
Return the length (this).
bool Collinear(const SEG &aSeg) const
Check if segment aSeg lies on the same line as (this).
bool Overlaps(const SEG &aSeg) const
bool Contains(const SEG &aSeg) const
VECTOR2I LineProject(const VECTOR2I &aP) const
Compute the perpendicular projection point of aP on a line passing through ends of the segment.
bool PointOnEdge(const VECTOR2I &aP, int aAccuracy=0) const
Check if point aP lies on an edge or vertex of the line chain.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
int Intersect(const SEG &aSeg, std::vector< INTERSECTION > &aIp) const
Find all intersection points between our line chain and the segment aSeg.
bool IsPtOnArc(size_t aPtIndex) const
const SHAPE_ARC & Arc(size_t aArc) const
void SetPoint(int aIndex, const VECTOR2I &aPos)
Move a point to a specific location.
int Split(const VECTOR2I &aP, bool aExact=false)
Insert the point aP belonging to one of the our segments, splitting the adjacent segment in two.
int ShapeCount() const
Return the number of shapes (line segments or arcs) in this line chain.
int PointCount() const
Return the number of points (vertices) in this line chain.
void Replace(int aStartIndex, int aEndIndex, const VECTOR2I &aP)
Replace points with indices in range [start_index, end_index] with a single point aP.
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 Simplify(int aTolerance=0)
Simplify the line chain by removing colinear adjacent segments and duplicate vertices.
const std::vector< SHAPE_ARC > & CArcs() const
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
const VECTOR2I NearestPoint(const VECTOR2I &aP, bool aAllowInternalShapePoints=true) const
Find a point on the line chain that is closest to point aP.
const SHAPE_LINE_CHAIN Slice(int aStartIndex, int aEndIndex) const
Return a subset of this line chain containing the [start_index, end_index] range of points.
int SegmentCount() const
Return the number of segments in this line chain.
const VECTOR2I & CLastPoint() const
Return the last point in the line chain.
void Remove(int aStartIndex, int aEndIndex)
Remove the range of points [start_index, end_index] 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
void RemoveShape(int aPointIndex)
Remove the shape at the given index from the line chain.
long long int Length() const
Return length of the line chain in Euclidean metric.
int Find(const VECTOR2I &aP, int aThreshold=0) const
Search for point aP.
const std::vector< VECTOR2I > & CPoints() const
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
Push and Shove diff pair dimensions (gap) settings dialog.
bool SplitAdjacentSegments(NODE *aNode, ITEM *aSeg, const VECTOR2I &aP)
Snaps the point aP to segment aSeg.
@ RM_MarkObstacles
Ignore collisions, mark obstacles.
@ RM_Walkaround
Only walk around.
std::unique_ptr< typename std::remove_const< T >::type > Clone(const T &aItem)
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
#define PNS_DBG(dbg, method,...)
#define PNS_DBGN(dbg, method)
std::vector< FIX_POINT > pts
LINE lines[MaxWalkPolicies]
STATUS status[MaxWalkPolicies]
Represent an intersection between two line segments.
static std::vector< int > candidates(const SEGMENT_INDEX &aIndex, const SEG &aQuery, int aPadding)
@ PCB_PAD_T
class PAD, a pad in a footprint
VECTOR2< int32_t > VECTOR2I