KiCad PCB EDA Suite
PNS::LINE_PLACER Class Reference

Single track placement algorithm. More...

#include <pns_line_placer.h>

Inheritance diagram for PNS::LINE_PLACER:
PNS::PLACEMENT_ALGO PNS::ALGO_BASE

Public Member Functions

 LINE_PLACER (ROUTER *aRouter)
 
 ~LINE_PLACER ()
 
bool Start (const VECTOR2I &aP, ITEM *aStartItem) override
 Start routing a single track at point aP, taking item aStartItem as anchor (unless NULL). More...
 
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). More...
 
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 the final anchor (if provided). More...
 
bool UnfixRoute () override
 
bool CommitPlacement () override
 
bool AbortPlacement () override
 
bool HasPlacedAnything () const override
 
bool ToggleVia (bool aEnabled) override
 Enable/disable a via at the end of currently routed trace. More...
 
bool SetLayer (int aLayer) override
 Set the current routing layer. More...
 
const LINEHead () const
 Return the "head" of the line being placed, that is the volatile part that has not been "fixed" yet. More...
 
const LINETail () const
 Return the "tail" of the line being placed, the part which has already wrapped around and shoved some obstacles. More...
 
const LINE Trace () const
 Return the complete routed line. More...
 
const ITEM_SET Traces () override
 Return the complete routed line, as a single-member ITEM_SET. More...
 
const VECTOR2ICurrentEnd () const override
 Return the current end of the line being placed. More...
 
const std::vector< int > CurrentNets () const override
 Return the net code of currently routed track. More...
 
int CurrentLayer () const override
 Return the layer of currently routed track. More...
 
NODECurrentNode (bool aLoopsRemoved=false) const override
 Return the most recent world state. More...
 
void FlipPosture () override
 Toggle the current posture (straight/diagonal) of the trace head. More...
 
void UpdateSizes (const SIZES_SETTINGS &aSizes) override
 Perform on-the-fly update of the width, via diameter & drill size from a settings class. More...
 
void SetOrthoMode (bool aOrthoMode) override
 Function SetOrthoMode() More...
 
bool IsPlacingVia () const override
 Function IsPlacingVia() More...
 
void GetModifiedNets (std::vector< int > &aNets) const override
 Function GetModifiedNets. More...
 
bool SplitAdjacentSegments (NODE *aNode, ITEM *aSeg, const VECTOR2I &aP)
 Check if point aP lies on segment aSeg. More...
 
ROUTERRouter () const
 Return current router settings. More...
 
ROUTING_SETTINGSSettings () const
 Return the logger object, allowing to dump geometry to a file. More...
 
virtual LOGGERLogger ()
 
void SetLogger (LOGGER *aLogger)
 
void SetDebugDecorator (DEBUG_DECORATOR *aDecorator)
 Assign a debug decorator allowing this algo to draw extra graphics for visual debugging. More...
 
DEBUG_DECORATORDbg () const
 
const BOX2IVisibleViewArea () const
 

Protected Attributes

DEBUG_DECORATORm_debugDecorator
 
ROUTERm_router
 
LOGGERm_logger
 

Private Member Functions

bool route (const VECTOR2I &aP)
 Re-route the current track to point aP. More...
 
void updateLeadingRatLine ()
 Draw the "leading" rats nest line, which connects the end of currently routed track and the nearest yet unrouted item. More...
 
void setWorld (NODE *aWorld)
 Set the board to route. More...
 
void initPlacement ()
 Initialize placement of a new line with given parameters. More...
 
void setInitialDirection (const DIRECTION_45 &aDirection)
 Set preferred direction of the very first track segment to be laid. More...
 
void removeLoops (NODE *aNode, LINE &aLatest)
 Searches aNode for traces concurrent to aLatest and removes them. More...
 
void simplifyNewLine (NODE *aNode, LINKED_ITEM *aLatest)
 Assemble a line starting from segment or arc aLatest, removes collinear segments and redundant vertices. More...
 
bool handleSelfIntersections ()
 Check if the head of the track intersects its tail. More...
 
bool handlePullback ()
 Deal with pull-back: reduces the tail if head trace is moved backwards wrs to the current tail direction. More...
 
bool mergeHead ()
 Moves "established" segments from the head to the tail if certain conditions are met. More...
 
bool reduceTail (const VECTOR2I &aEnd)
 Attempt to reduce the number of segments in the tail by trying to replace a certain number of latest tail segments with a direct trace leading to aEnd that does not collide with anything. More...
 
bool optimizeTailHeadTransition ()
 Try to reduce the corner count of the most recent part of tail/head by merging obtuse/collinear segments. More...
 
bool routeHead (const VECTOR2I &aP, LINE &aNewHead)
 Compute the head trace between the current start point (m_p_start) and point aP, starting with direction defined in m_direction. More...
 
void routeStep (const VECTOR2I &aP)
 Perform a single routing algorithm step, for the end point aP. More...
 
bool rhWalkOnly (const VECTOR2I &aP, LINE &aNewHead)
 Route step shove mode. More...
 
bool rhShoveOnly (const VECTOR2I &aP, LINE &aNewHead)
 Route step mark obstacles mode. More...
 
bool rhMarkObstacles (const VECTOR2I &aP, LINE &aNewHead)
 
const VIA makeVia (const VECTOR2I &aP)
 
bool buildInitialLine (const VECTOR2I &aP, LINE &aHead, bool aForceNoVia=false)
 

Private Attributes

DIRECTION_45 m_direction
 current routing direction More...
 
DIRECTION_45 m_initial_direction
 routing direction for new traces More...
 
LINE m_head
 the volatile part of the track from the previously analyzed point to the current routing destination More...
 
LINE m_last_head
 Most recent successful (non-colliding) head. More...
 
LINE m_tail
 routing "tail": part of the track that has been already fixed due to collisions with obstacles More...
 
NODEm_world
 pointer to world to search colliding items More...
 
VECTOR2I m_p_start
 current routing start (end of tail, beginning of head) More...
 
std::unique_ptr< SHOVEm_shove
 The shove engine. More...
 
NODEm_currentNode
 Current world state. More...
 
NODEm_lastNode
 Postprocessed world state (including marked collisions & removed loops) More...
 
SIZES_SETTINGS m_sizes
 
bool m_placingVia
 
int m_currentNet
 
int m_currentLayer
 
VECTOR2I m_currentEnd
 
VECTOR2I m_currentStart
 
LINE m_currentTrace
 
ITEMm_startItem
 
bool m_idle
 
bool m_chainedPlacement
 
bool m_orthoMode
 
bool m_placementCorrect
 
FIXED_TAIL m_fixedTail
 
MOUSE_TRAIL_TRACER m_mouseTrailTracer
 

Detailed Description

Single track placement algorithm.

Interactively routes a track. Applies shove and walkaround algorithms when needed.

Definition at line 84 of file pns_line_placer.h.

Constructor & Destructor Documentation

◆ LINE_PLACER()

PNS::LINE_PLACER::LINE_PLACER ( ROUTER aRouter)

Definition at line 40 of file pns_line_placer.cpp.

40  :
41  PLACEMENT_ALGO( aRouter )
42 {
44  m_world = nullptr;
45  m_shove = nullptr;
46  m_currentNode = nullptr;
47  m_idle = true;
48 
49  // Init temporary variables (do not leave uninitialized members)
50  m_lastNode = nullptr;
51  m_placingVia = false;
52  m_currentNet = 0;
53  m_currentLayer = 0;
54  m_startItem = nullptr;
55  m_chainedPlacement = false;
56  m_orthoMode = false;
57  m_placementCorrect = false;
58 }
NODE * m_lastNode
Postprocessed world state (including marked collisions & removed loops)
NODE * m_world
pointer to world to search colliding items
DIRECTION_45 m_initial_direction
routing direction for new traces
std::unique_ptr< SHOVE > m_shove
The shove engine.
NODE * m_currentNode
Current world state.
PLACEMENT_ALGO(ROUTER *aRouter)

References m_chainedPlacement, m_currentLayer, m_currentNet, m_currentNode, m_idle, m_initial_direction, m_lastNode, m_orthoMode, m_placementCorrect, m_placingVia, m_shove, m_startItem, m_world, and DIRECTION_45::N.

◆ ~LINE_PLACER()

PNS::LINE_PLACER::~LINE_PLACER ( )

Definition at line 61 of file pns_line_placer.cpp.

62 {
63 }

Member Function Documentation

◆ AbortPlacement()

bool PNS::LINE_PLACER::AbortPlacement ( )
overridevirtual

Reimplemented from PNS::PLACEMENT_ALGO.

Definition at line 1729 of file pns_line_placer.cpp.

1730 {
1731  m_world->KillChildren();
1732  return true;
1733 }
NODE * m_world
pointer to world to search colliding items
void KillChildren()
Definition: pns_node.cpp:1405

References PNS::NODE::KillChildren(), and m_world.

◆ buildInitialLine()

bool PNS::LINE_PLACER::buildInitialLine ( const VECTOR2I aP,
LINE aHead,
bool  aForceNoVia = false 
)
private

Definition at line 1651 of file pns_line_placer.cpp.

1652 {
1653  SHAPE_LINE_CHAIN l;
1654  DIRECTION_45 guessedDir = m_mouseTrailTracer.GetPosture( aP );
1655 
1656  wxLogTrace( "PNS", "buildInitialLine: m_direction %s, guessedDir %s, tail points %d",
1657  m_direction.Format(), guessedDir.Format(), m_tail.PointCount() );
1658 
1659  // Rounded corners don't make sense when routing orthogonally (single track at a time)
1660  bool fillet = !m_orthoMode && Settings().GetCornerMode() == CORNER_MODE::ROUNDED_45;
1661 
1662  if( m_p_start == aP )
1663  {
1664  l.Clear();
1665  }
1666  else
1667  {
1668  if( Settings().GetFreeAngleMode() && Settings().Mode() == RM_MarkObstacles )
1669  {
1670  l = SHAPE_LINE_CHAIN( { m_p_start, aP } );
1671  }
1672  else
1673  {
1674  if( !m_tail.PointCount() )
1675  l = guessedDir.BuildInitialTrace( m_p_start, aP, false, fillet );
1676  else
1677  l = m_direction.BuildInitialTrace( m_p_start, aP, false, fillet );
1678  }
1679 
1680  if( l.SegmentCount() > 1 && m_orthoMode )
1681  {
1682  VECTOR2I newLast = l.CSegment( 0 ).LineProject( l.CPoint( -1 ) );
1683 
1684  l.Remove( -1, -1 );
1685  l.SetPoint( 1, newLast );
1686  }
1687  }
1688 
1689  aHead.SetLayer( m_currentLayer );
1690  aHead.SetShape( l );
1691 
1692  if( !m_placingVia || aForceNoVia )
1693  return true;
1694 
1695  VIA v( makeVia( aP ) );
1696  v.SetNet( aHead.Net() );
1697 
1698  if( Settings().Mode() == RM_MarkObstacles )
1699  {
1700  aHead.AppendVia( v );
1701  return true;
1702  }
1703 
1704  VECTOR2I force;
1705  VECTOR2I lead = aP - m_p_start;
1706 
1707  bool solidsOnly = ( Settings().Mode() != RM_Walkaround );
1708 
1709  if( v.PushoutForce( m_currentNode, lead, force, solidsOnly, 40 ) )
1710  {
1711  SHAPE_LINE_CHAIN line = guessedDir.BuildInitialTrace( m_p_start, aP + force, false,
1712  fillet );
1713  aHead = LINE( aHead, line );
1714 
1715  v.SetPos( v.Pos() + force );
1716  return true;
1717  }
1718 
1719  return false; // via placement unsuccessful
1720 }
void SetPoint(int aIndex, const VECTOR2I &aPos)
Move a point to a specific location.
const std::string Format() const
Format the direction in a human readable word.
Definition: direction45.h:117
H/V/45 with filleted corners.
int PointCount() const
Definition: pns_line.h:140
ROUTING_SETTINGS & Settings() const
Return the logger object, allowing to dump geometry to a file.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
VECTOR2I LineProject(const VECTOR2I &aP) const
Compute the perpendicular projection point of aP on a line passing through ends of the segment.
Definition: seg.cpp:268
Normal via.
Definition: router_tool.cpp:72
LINE m_tail
routing "tail": part of the track that has been already fixed due to collisions with obstacles
Represent route directions & corner angles in a 45-degree metric.
Definition: direction45.h:36
DIRECTION_45 m_direction
current routing direction
PNS_MODE Mode() const
Set the routing mode.
const SHAPE_LINE_CHAIN BuildInitialTrace(const VECTOR2I &aP0, const VECTOR2I &aP1, bool aStartDiagonal=false, bool aFillet=false) const
Build a 2-segment line chain between points aP0 and aP1 and following 45-degree routing regime.
MOUSE_TRAIL_TRACER m_mouseTrailTracer
void Remove(int aStartIndex, int aEndIndex)
Remove the range of points [start_index, end_index] from the line chain.
int SegmentCount() const
Return the number of segments in this line chain.
NODE * m_currentNode
Current world state.
Ignore collisions, mark obstacles.
CORNER_MODE GetCornerMode() const
const SEG CSegment(int aIndex) const
Return a constant copy of the aIndex segment in the line chain.
Represent a polyline (an zero-thickness chain of connected line segments).
Only walk around.
DIRECTION_45 GetPosture(const VECTOR2I &aP)
void Clear()
Remove all points from the line chain.
VECTOR2I m_p_start
current routing start (end of tail, beginning of head)
const VIA makeVia(const VECTOR2I &aP)

References PNS::LINE::AppendVia(), DIRECTION_45::BuildInitialTrace(), SHAPE_LINE_CHAIN::Clear(), SHAPE_LINE_CHAIN::CPoint(), SHAPE_LINE_CHAIN::CSegment(), DIRECTION_45::Format(), PNS::ROUTING_SETTINGS::GetCornerMode(), PNS::MOUSE_TRAIL_TRACER::GetPosture(), SEG::LineProject(), m_currentLayer, m_currentNode, m_direction, m_mouseTrailTracer, m_orthoMode, m_p_start, m_placingVia, m_tail, makeVia(), PNS::ROUTING_SETTINGS::Mode(), PNS::ITEM::Net(), PNS::LINE::PointCount(), PNS::VIA::Pos(), PNS::VIA::PushoutForce(), SHAPE_LINE_CHAIN::Remove(), PNS::RM_MarkObstacles, PNS::RM_Walkaround, PNS::ROUNDED_45, SHAPE_LINE_CHAIN::SegmentCount(), PNS::ITEM::SetLayer(), PNS::ITEM::SetNet(), SHAPE_LINE_CHAIN::SetPoint(), PNS::VIA::SetPos(), PNS::LINE::SetShape(), and PNS::ALGO_BASE::Settings().

Referenced by rhMarkObstacles(), rhShoveOnly(), and rhWalkOnly().

◆ CommitPlacement()

bool PNS::LINE_PLACER::CommitPlacement ( )
overridevirtual

Reimplemented from PNS::PLACEMENT_ALGO.

Definition at line 1469 of file pns_line_placer.cpp.

1470 {
1471  if( m_lastNode )
1473 
1474  m_lastNode = nullptr;
1475  m_currentNode = nullptr;
1476  return true;
1477 }
ROUTER * Router() const
Return current router settings.
Definition: pns_algo_base.h:54
NODE * m_lastNode
Postprocessed world state (including marked collisions & removed loops)
void CommitRouting()
Definition: pns_router.cpp:699
NODE * m_currentNode
Current world state.

References PNS::ROUTER::CommitRouting(), m_currentNode, m_lastNode, and PNS::ALGO_BASE::Router().

◆ CurrentEnd()

const VECTOR2I& PNS::LINE_PLACER::CurrentEnd ( ) const
inlineoverridevirtual

Return the current end of the line being placed.

It may not be equal to the cursor position due to collisions.

Implements PNS::PLACEMENT_ALGO.

Definition at line 155 of file pns_line_placer.h.

156  {
157  return m_currentEnd;
158  }

References m_currentEnd.

◆ CurrentLayer()

int PNS::LINE_PLACER::CurrentLayer ( ) const
inlineoverridevirtual

Return the layer of currently routed track.

Implements PNS::PLACEMENT_ALGO.

Definition at line 171 of file pns_line_placer.h.

172  {
173  return m_currentLayer;
174  }

References m_currentLayer.

◆ CurrentNets()

const std::vector<int> PNS::LINE_PLACER::CurrentNets ( ) const
inlineoverridevirtual

Return the net code of currently routed track.

Implements PNS::PLACEMENT_ALGO.

Definition at line 163 of file pns_line_placer.h.

164  {
165  return std::vector<int>( 1, m_currentNet );
166  }

References m_currentNet.

◆ CurrentNode()

NODE * PNS::LINE_PLACER::CurrentNode ( bool  aLoopsRemoved = false) const
overridevirtual

Return the most recent world state.

Implements PNS::PLACEMENT_ALGO.

Definition at line 1029 of file pns_line_placer.cpp.

1030 {
1031  if( aLoopsRemoved && m_lastNode )
1032  return m_lastNode;
1033 
1034  return m_currentNode;
1035 }
NODE * m_lastNode
Postprocessed world state (including marked collisions & removed loops)
NODE * m_currentNode
Current world state.

References m_currentNode, and m_lastNode.

◆ Dbg()

◆ FixRoute()

bool PNS::LINE_PLACER::FixRoute ( const VECTOR2I aP,
ITEM aEndItem,
bool  aForceFinish 
)
overridevirtual

Commit the currently routed track to the parent node taking aP as the final end point and aEndItem as the final anchor (if provided).

Returns
true if route has been committed. May return false if the routing result is violating design rules. In such cases, the track is only committed if CanViolateDRC() is on.

<

Todo:
Determine what to do if m_lastNode is a null pointer. I'm guessing return false but someone with more knowledge of the code will need to determine that..

Implements PNS::PLACEMENT_ALGO.

Definition at line 1240 of file pns_line_placer.cpp.

1241 {
1242  bool fixAll = Settings().GetFixAllSegments();
1243  bool realEnd = false;
1244 
1245  LINE pl = Trace();
1246 
1247  if( Settings().Mode() == RM_MarkObstacles )
1248  {
1249  // Mark Obstacles is sort of a half-manual, half-automated mode in which the
1250  // user has more responsibility and authority.
1251 
1252  if( aEndItem )
1253  {
1254  // The user has indicated a connection should be made. If either the trace or
1255  // endItem is net-less, then allow the connection by adopting the net of the other.
1256  if( m_currentNet <= 0 )
1257  {
1258  m_currentNet = aEndItem->Net();
1259  pl.SetNet( m_currentNet );
1260  }
1261  else if (aEndItem->Net() <= 0 )
1262  {
1263  aEndItem->SetNet( m_currentNet );
1264  }
1265  }
1266 
1267  // Collisions still prevent fixing unless "Allow DRC violations" is checked
1268  if( !Settings().AllowDRCViolations() && m_world->CheckColliding( &pl ) )
1269  return false;
1270  }
1271 
1272  const SHAPE_LINE_CHAIN& l = pl.CLine();
1273 
1274  if( !l.SegmentCount() )
1275  {
1276  if( m_lastNode )
1277  {
1278  // Do a final optimization to the stored state
1279  NODE::ITEM_VECTOR removed, added;
1280  m_lastNode->GetUpdatedItems( removed, added );
1281 
1282  if( !added.empty() && added.back()->Kind() == ITEM::SEGMENT_T )
1283  simplifyNewLine( m_lastNode, static_cast<SEGMENT*>( added.back() ) );
1284  }
1285 
1286  // Nothing to commit if we have an empty line
1287  if( !pl.EndsWithVia() )
1288  return false;
1289 
1292  if( m_lastNode )
1293  m_lastNode->Add( Clone( pl.Via() ) );
1294 
1295  m_currentNode = nullptr;
1296 
1297  m_idle = true;
1298  m_placementCorrect = true;
1299  return true;
1300  }
1301 
1302  VECTOR2I p_pre_last = l.CPoint( -1 );
1303  const VECTOR2I p_last = l.CPoint( -1 );
1304 
1305  if( l.PointCount() > 2 )
1306  p_pre_last = l.CPoint( -2 );
1307 
1308  if( aEndItem && m_currentNet >= 0 && m_currentNet == aEndItem->Net() )
1309  realEnd = true;
1310 
1311  if( aForceFinish )
1312  realEnd = true;
1313 
1314  // TODO: Rollback doesn't work properly if fix-all isn't enabled and we are placing arcs,
1315  // so if we are, act as though we are in fix-all mode.
1316  if( !fixAll && l.ArcCount() )
1317  fixAll = true;
1318 
1319  // TODO: lastDirSeg will be calculated incorrectly if we end on an arc
1320  SEG lastDirSeg = ( !fixAll && l.SegmentCount() > 1 ) ? l.CSegment( -2 ) : l.CSegment( -1 );
1321  DIRECTION_45 d_last( lastDirSeg );
1322 
1323  int lastV;
1324 
1325  if( realEnd || m_placingVia || fixAll )
1326  lastV = l.SegmentCount();
1327  else
1328  lastV = std::max( 1, l.SegmentCount() - 1 );
1329 
1330  ARC arc;
1331  SEGMENT seg;
1332  LINKED_ITEM* lastItem = nullptr;
1333  int lastArc = -1;
1334 
1335  for( int i = 0; i < lastV; i++ )
1336  {
1337  ssize_t arcIndex = l.ArcIndex( i );
1338 
1339  if( arcIndex < 0 || ( lastArc >= 0 && i == lastV - 1 && !l.IsPtOnArc( lastV ) ) )
1340  {
1341  seg = SEGMENT( pl.CSegment( i ), m_currentNet );
1342  seg.SetWidth( pl.Width() );
1343  seg.SetLayer( m_currentLayer );
1344 
1345  std::unique_ptr<SEGMENT> sp = std::make_unique<SEGMENT>( seg );
1346  lastItem = sp.get();
1347 
1348  if( !m_lastNode->Add( std::move( sp ) ) )
1349  lastItem = nullptr;
1350  }
1351  else
1352  {
1353  if( arcIndex == lastArc )
1354  continue;
1355 
1356  arc = ARC( l.Arc( arcIndex ), m_currentNet );
1357  arc.SetWidth( pl.Width() );
1358  arc.SetLayer( m_currentLayer );
1359 
1360  std::unique_ptr<ARC> ap = std::make_unique<ARC>( arc );
1361  lastItem = ap.get();
1362 
1363  if( !m_lastNode->Add( std::move( ap ) ) )
1364  lastItem = nullptr;
1365 
1366  lastArc = arcIndex;
1367  }
1368  }
1369 
1370  if( pl.EndsWithVia() )
1371  m_lastNode->Add( Clone( pl.Via() ) );
1372 
1373  if( realEnd && lastItem )
1374  simplifyNewLine( m_lastNode, lastItem );
1375 
1376  if( !realEnd )
1377  {
1378  setInitialDirection( d_last );
1379  m_currentStart = ( m_placingVia || fixAll ) ? p_last : p_pre_last;
1380 
1381  VECTOR2I ps;
1382  if( m_tail.SegmentCount() )
1383  ps = m_tail.CPoint( 0 );
1384  else
1385  ps = m_p_start;
1386 
1388 
1389  m_startItem = nullptr;
1390  m_placingVia = false;
1391  m_chainedPlacement = !pl.EndsWithVia();
1392 
1395 
1396  m_head.Line().Clear();
1397  m_tail.Line().Clear();
1398  m_head.RemoveVia();
1399  m_tail.RemoveVia();
1402 
1403  m_shove->AddLockedSpringbackNode( m_currentNode );
1404 
1405  DIRECTION_45 lastSegDir = pl.EndsWithVia() ? DIRECTION_45::UNDEFINED : d_last;
1406 
1411 
1412  m_placementCorrect = true;
1413  }
1414  else
1415  {
1416  m_placementCorrect = true;
1417  m_idle = true;
1418  }
1419 
1420  return realEnd;
1421 }
const SHAPE_ARC & Arc(size_t aArc) const
NODE * m_lastNode
Postprocessed world state (including marked collisions & removed loops)
int SegmentCount() const
Definition: pns_line.h:139
NODE * m_world
pointer to world to search colliding items
void simplifyNewLine(NODE *aNode, LINKED_ITEM *aLatest)
Assemble a line starting from segment or arc aLatest, removes collinear segments and redundant vertic...
LINE m_head
the volatile part of the track from the previously analyzed point to the current routing destination
void RemoveVia()
Definition: pns_line.h:194
const LINE Trace() const
Return the complete routed line.
size_t ArcCount() const
int PointCount() const
Return the number of points (vertices) in this line chain.
NODE * Branch()
Create a lightweight copy (called branch) of self that tracks the changes (added/removed items) wrs t...
Definition: pns_node.cpp:137
const VECTOR2I & CPoint(int aIdx) const
Definition: pns_line.h:145
ssize_t ArcIndex(size_t aSegment) const
Return the arc index for the given segment index.
ROUTING_SETTINGS & Settings() const
Return the logger object, allowing to dump geometry to a file.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
DIRECTION_45 m_initial_direction
routing direction for new traces
LINE m_tail
routing "tail": part of the track that has been already fixed due to collisions with obstacles
void setInitialDirection(const DIRECTION_45 &aDirection)
Set preferred direction of the very first track segment to be laid.
Represent route directions & corner angles in a 45-degree metric.
Definition: direction45.h:36
std::unique_ptr< SHOVE > m_shove
The shove engine.
DIRECTION_45 m_direction
current routing direction
void AddTrailPoint(const VECTOR2I &aP)
MOUSE_TRAIL_TRACER m_mouseTrailTracer
FIXED_TAIL m_fixedTail
int SegmentCount() const
Return the number of segments in this line chain.
bool IsPtOnArc(size_t aPtIndex) const
void AddStage(const VECTOR2I &aStart, int aLayer, bool placingVias, DIRECTION_45 direction, NODE *aNode)
SHAPE_LINE_CHAIN & Line()
Definition: pns_line.h:136
Definition: seg.h:40
NODE * m_currentNode
Current world state.
Ignore collisions, mark obstacles.
const SEG CSegment(int aIndex) const
Return a constant copy of the aIndex segment in the line chain.
std::unique_ptr< typename std::remove_const< T >::type > Clone(const T &aItem)
Definition: pns_item.h:265
Represent a polyline (an zero-thickness chain of connected line segments).
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.
Definition: pns_node.cpp:450
void SetDefaultDirections(DIRECTION_45 aInitDirection, DIRECTION_45 aLastSegDir)
int Width() const
Return true if the line is geometrically identical as line aOther.
Definition: pns_line.h:156
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.
Definition: pns_node.cpp:1338
void Clear()
Remove all points from the line chain.
VECTOR2I m_p_start
current routing start (end of tail, beginning of head)
bool Add(std::unique_ptr< SEGMENT > aSegment, bool aAllowRedundant=false)
Add an item to the current node.
Definition: pns_node.cpp:638
std::vector< ITEM * > ITEM_VECTOR
Definition: pns_node.h:148

References PNS::NODE::Add(), PNS::FIXED_TAIL::AddStage(), PNS::MOUSE_TRAIL_TRACER::AddTrailPoint(), SHAPE_LINE_CHAIN::Arc(), SHAPE_LINE_CHAIN::ArcCount(), SHAPE_LINE_CHAIN::ArcIndex(), PNS::NODE::Branch(), PNS::NODE::CheckColliding(), PNS::MOUSE_TRAIL_TRACER::Clear(), SHAPE_LINE_CHAIN::Clear(), PNS::LINE::CLine(), PNS::Clone(), PNS::LINE::CPoint(), SHAPE_LINE_CHAIN::CPoint(), PNS::LINE::CSegment(), SHAPE_LINE_CHAIN::CSegment(), PNS::LINE::EndsWithVia(), PNS::ROUTING_SETTINGS::GetFixAllSegments(), PNS::NODE::GetUpdatedItems(), SHAPE_LINE_CHAIN::IsPtOnArc(), PNS::LINE::Line(), m_chainedPlacement, m_currentLayer, m_currentNet, m_currentNode, m_currentStart, m_direction, m_fixedTail, m_head, m_idle, m_initial_direction, m_lastNode, m_mouseTrailTracer, m_p_start, m_placementCorrect, m_placingVia, m_shove, m_startItem, m_tail, m_world, PNS::ITEM::Net(), SHAPE_LINE_CHAIN::PointCount(), PNS::LINE::RemoveVia(), PNS::RM_MarkObstacles, PNS::ITEM::SEGMENT_T, PNS::LINE::SegmentCount(), SHAPE_LINE_CHAIN::SegmentCount(), PNS::MOUSE_TRAIL_TRACER::SetDefaultDirections(), setInitialDirection(), PNS::ITEM::SetLayer(), PNS::ITEM::SetNet(), PNS::ALGO_BASE::Settings(), PNS::MOUSE_TRAIL_TRACER::SetTolerance(), PNS::SEGMENT::SetWidth(), PNS::ARC::SetWidth(), simplifyNewLine(), Trace(), DIRECTION_45::UNDEFINED, PNS::LINE::Via(), and PNS::LINE::Width().

◆ FlipPosture()

void PNS::LINE_PLACER::FlipPosture ( )
overridevirtual

Toggle the current posture (straight/diagonal) of the trace head.

Reimplemented from PNS::PLACEMENT_ALGO.

Definition at line 1023 of file pns_line_placer.cpp.

1024 {
1026 }
MOUSE_TRAIL_TRACER m_mouseTrailTracer

References PNS::MOUSE_TRAIL_TRACER::FlipPosture(), and m_mouseTrailTracer.

◆ GetModifiedNets()

void PNS::LINE_PLACER::GetModifiedNets ( std::vector< int > &  aNets) const
overridevirtual

Function GetModifiedNets.

Returns the net codes of all currently routed trace(s)

Reimplemented from PNS::PLACEMENT_ALGO.

Definition at line 1723 of file pns_line_placer.cpp.

1724 {
1725  aNets.push_back( m_currentNet );
1726 }

References m_currentNet.

◆ handlePullback()

bool PNS::LINE_PLACER::handlePullback ( )
private

Deal with pull-back: reduces the tail if head trace is moved backwards wrs to the current tail direction.

Returns
true if the line has been changed.

Definition at line 173 of file pns_line_placer.cpp.

174 {
175  SHAPE_LINE_CHAIN& head = m_head.Line();
176  SHAPE_LINE_CHAIN& tail = m_tail.Line();
177 
178  if( head.PointCount() < 2 )
179  return false;
180 
181  int n = tail.PointCount();
182 
183  if( n == 0 )
184  {
185  return false;
186  }
187  else if( n == 1 )
188  {
189  m_p_start = tail.CPoint( 0 );
190  tail.Clear();
191  return true;
192  }
193 
194  DIRECTION_45 first_head, last_tail;
195 
196  wxASSERT( tail.PointCount() >= 2 );
197 
198  if( !head.IsPtOnArc( 0 ) )
199  first_head = DIRECTION_45( head.CSegment( 0 ) );
200  else
201  first_head = DIRECTION_45( head.CArcs()[head.ArcIndex(0)] );
202 
203  int lastSegIdx = tail.PointCount() - 2;
204 
205  if( !tail.IsPtOnArc( lastSegIdx ) )
206  last_tail = DIRECTION_45( tail.CSegment( lastSegIdx ) );
207  else
208  last_tail = DIRECTION_45( tail.CArcs()[tail.ArcIndex(lastSegIdx)] );
209 
210  DIRECTION_45::AngleType angle = first_head.Angle( last_tail );
211 
212  // case 1: we have a defined routing direction, and the currently computed
213  // head goes in different one.
214  bool pullback_1 = false; // (m_direction != DIRECTION_45::UNDEFINED && m_direction != first_head);
215 
216  // case 2: regardless of the current routing direction, if the tail/head
217  // extremities form an acute or right angle, reduce the tail by one segment
218  // (and hope that further iterations) will result with a cleaner trace
219  bool pullback_2 = ( angle == DIRECTION_45::ANG_RIGHT || angle == DIRECTION_45::ANG_ACUTE );
220 
221  if( pullback_1 || pullback_2 )
222  {
223  lastSegIdx = tail.PrevShape( -1 );
224 
225  if( !tail.IsPtOnArc( lastSegIdx ) )
226  {
227  const SEG& seg = tail.CSegment( lastSegIdx );
228  m_direction = DIRECTION_45( seg );
229  m_p_start = seg.A;
230  }
231  else
232  {
233  const SHAPE_ARC& arc = tail.CArcs()[tail.ArcIndex( lastSegIdx )];
234  m_direction = DIRECTION_45( arc );
235  m_p_start = arc.GetP0();
236  }
237 
238  wxLogTrace( "PNS", "Placer: pullback triggered [%d] [%s %s]",
239  n, last_tail.Format().c_str(), first_head.Format().c_str() );
240 
241  // erase the last point in the tail, hoping that the next iteration will
242  // result with a head trace that starts with a segment following our
243  // current direction.
244  if( n < 2 )
245  tail.Clear(); // don't leave a single-point tail
246  else
247  tail.RemoveShape( -1 );
248 
249  if( !tail.SegmentCount() )
251 
252  return true;
253  }
254 
255  return false;
256 }
int PrevShape(int aPointIndex) const
void RemoveShape(int aPointIndex)
Remove the shape at the given index from the line chain.
const std::string Format() const
Format the direction in a human readable word.
Definition: direction45.h:117
LINE m_head
the volatile part of the track from the previously analyzed point to the current routing destination
const std::vector< SHAPE_ARC > & CArcs() const
int PointCount() const
Return the number of points (vertices) in this line chain.
ssize_t ArcIndex(size_t aSegment) const
Return the arc index for the given segment index.
AngleType Angle(const DIRECTION_45 &aOther) const
Return the type of angle between directions (this) and aOther.
Definition: direction45.h:169
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
DIRECTION_45 m_initial_direction
routing direction for new traces
LINE m_tail
routing "tail": part of the track that has been already fixed due to collisions with obstacles
Represent route directions & corner angles in a 45-degree metric.
Definition: direction45.h:36
DIRECTION_45 m_direction
current routing direction
const VECTOR2I & GetP0() const
Definition: shape_arc.h:111
int SegmentCount() const
Return the number of segments in this line chain.
bool IsPtOnArc(size_t aPtIndex) const
SHAPE_LINE_CHAIN & Line()
Definition: pns_line.h:136
Definition: seg.h:40
AngleType
Represent kind of angle formed by vectors heading in two DIRECTION_45s.
Definition: direction45.h:65
const SEG CSegment(int aIndex) const
Return a constant copy of the aIndex segment in the line chain.
Represent a polyline (an zero-thickness chain of connected line segments).
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
VECTOR2I A
Definition: seg.h:48
void Clear()
Remove all points from the line chain.
VECTOR2I m_p_start
current routing start (end of tail, beginning of head)

References SEG::A, DIRECTION_45::ANG_ACUTE, DIRECTION_45::ANG_RIGHT, DIRECTION_45::Angle(), PNS::angle(), SHAPE_LINE_CHAIN::ArcIndex(), SHAPE_LINE_CHAIN::CArcs(), SHAPE_LINE_CHAIN::Clear(), SHAPE_LINE_CHAIN::CPoint(), SHAPE_LINE_CHAIN::CSegment(), DIRECTION_45::Format(), SHAPE_ARC::GetP0(), SHAPE_LINE_CHAIN::IsPtOnArc(), PNS::LINE::Line(), m_direction, m_head, m_initial_direction, m_p_start, m_tail, SHAPE_LINE_CHAIN::PointCount(), SHAPE_LINE_CHAIN::PrevShape(), SHAPE_LINE_CHAIN::RemoveShape(), and SHAPE_LINE_CHAIN::SegmentCount().

Referenced by routeStep().

◆ handleSelfIntersections()

bool PNS::LINE_PLACER::handleSelfIntersections ( )
private

Check if the head of the track intersects its tail.

If so, cuts the tail up to the intersecting segment and fixes the head direction to match the last segment before the cut.

Returns
true if the line has been changed.

Definition at line 101 of file pns_line_placer.cpp.

102 {
104  SHAPE_LINE_CHAIN& head = m_head.Line();
105  SHAPE_LINE_CHAIN& tail = m_tail.Line();
106 
107  // if there is no tail, there is nothing to intersect with
108  if( tail.PointCount() < 2 )
109  return false;
110 
111  if( head.PointCount() < 2 )
112  return false;
113 
114  // completely new head trace? chop off the tail
115  if( tail.CPoint(0) == head.CPoint(0) )
116  {
117  m_p_start = tail.CPoint( 0 );
119  tail.Clear();
120  return true;
121  }
122 
123  tail.Intersect( head, ips );
124 
125  // no intesection points - nothing to reduce
126  if( ips.empty() )
127  return false;
128 
129  int n = INT_MAX;
130  VECTOR2I ipoint;
131 
132  // if there is more than one intersection, find the one that is
133  // closest to the beginning of the tail.
134  for( const SHAPE_LINE_CHAIN::INTERSECTION& i : ips )
135  {
136  if( i.index_our < n )
137  {
138  n = i.index_our;
139  ipoint = i.p;
140  }
141  }
142 
143  // ignore the point where head and tail meet
144  if( ipoint == head.CPoint( 0 ) || ipoint == tail.CPoint( -1 ) )
145  return false;
146 
147  // Intersection point is on the first or the second segment: just start routing
148  // from the beginning
149  if( n < 2 )
150  {
151  m_p_start = tail.CPoint( 0 );
153  tail.Clear();
154  head.Clear();
155 
156  return true;
157  }
158  else
159  {
160  // Clip till the last tail segment before intersection.
161  // Set the direction to the one of this segment.
162  const SEG last = tail.CSegment( n - 1 );
163  m_p_start = last.A;
164  m_direction = DIRECTION_45( last );
165  tail.Remove( n, -1 );
166  return true;
167  }
168 
169  return false;
170 }
Represent an intersection between two line segments.
int Intersect(const SEG &aSeg, INTERSECTIONS &aIp) const
Find all intersection points between our line chain and the segment aSeg.
std::vector< INTERSECTION > INTERSECTIONS
LINE m_head
the volatile part of the track from the previously analyzed point to the current routing destination
int PointCount() const
Return the number of points (vertices) in this line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
DIRECTION_45 m_initial_direction
routing direction for new traces
LINE m_tail
routing "tail": part of the track that has been already fixed due to collisions with obstacles
Represent route directions & corner angles in a 45-degree metric.
Definition: direction45.h:36
DIRECTION_45 m_direction
current routing direction
void Remove(int aStartIndex, int aEndIndex)
Remove the range of points [start_index, end_index] from the line chain.
SHAPE_LINE_CHAIN & Line()
Definition: pns_line.h:136
Definition: seg.h:40
const SEG CSegment(int aIndex) const
Return a constant copy of the aIndex segment in the line chain.
Represent a polyline (an zero-thickness chain of connected line segments).
VECTOR2I A
Definition: seg.h:48
void Clear()
Remove all points from the line chain.
VECTOR2I m_p_start
current routing start (end of tail, beginning of head)

References SEG::A, SHAPE_LINE_CHAIN::Clear(), SHAPE_LINE_CHAIN::CPoint(), SHAPE_LINE_CHAIN::CSegment(), SHAPE_LINE_CHAIN::Intersect(), PNS::LINE::Line(), m_direction, m_head, m_initial_direction, m_p_start, m_tail, SHAPE_LINE_CHAIN::PointCount(), and SHAPE_LINE_CHAIN::Remove().

Referenced by routeStep().

◆ HasPlacedAnything()

bool PNS::LINE_PLACER::HasPlacedAnything ( ) const
overridevirtual

Reimplemented from PNS::PLACEMENT_ALGO.

Definition at line 1463 of file pns_line_placer.cpp.

1464 {
1465  return m_placementCorrect || m_fixedTail.StageCount() > 1;
1466 }
FIXED_TAIL m_fixedTail
int StageCount() const

References m_fixedTail, m_placementCorrect, and PNS::FIXED_TAIL::StageCount().

Referenced by UpdateSizes().

◆ Head()

const LINE& PNS::LINE_PLACER::Head ( ) const
inline

Return the "head" of the line being placed, that is the volatile part that has not been "fixed" yet.

Definition at line 133 of file pns_line_placer.h.

133 { return m_head; }
LINE m_head
the volatile part of the track from the previously analyzed point to the current routing destination

References m_head.

◆ initPlacement()

void PNS::LINE_PLACER::initPlacement ( )
private

Initialize placement of a new line with given parameters.

Definition at line 1157 of file pns_line_placer.cpp.

1158 {
1159  m_idle = false;
1160 
1161  m_head.Line().Clear();
1162  m_tail.Line().Clear();
1169  m_head.RemoveVia();
1170  m_tail.RemoveVia();
1171 
1174 
1175  NODE* world = Router()->GetWorld();
1176 
1177  world->KillChildren();
1178  NODE* rootNode = world->Branch();
1179 
1181 
1182  setWorld( rootNode );
1183 
1184  wxLogTrace( "PNS", "world %p, intitial-direction %s layer %d",
1185  m_world,
1186  m_direction.Format().c_str(),
1187  m_currentLayer );
1188 
1189  m_lastNode = nullptr;
1191 
1192  m_shove = std::make_unique<SHOVE>( m_world->Branch(), Router() );
1193 }
ROUTER * Router() const
Return current router settings.
Definition: pns_algo_base.h:54
NODE * m_lastNode
Postprocessed world state (including marked collisions & removed loops)
NODE * m_world
pointer to world to search colliding items
void SetLayer(int aLayer)
Definition: pns_item.h:155
const std::string Format() const
Format the direction in a human readable word.
Definition: direction45.h:117
LINE m_head
the volatile part of the track from the previously analyzed point to the current routing destination
void RemoveVia()
Definition: pns_line.h:194
SIZES_SETTINGS m_sizes
NODE * Branch()
Create a lightweight copy (called branch) of self that tracks the changes (added/removed items) wrs t...
Definition: pns_node.cpp:137
void SetWidth(int aWidth)
Return line width.
Definition: pns_line.h:149
void SetNet(int aNet)
Definition: pns_item.h:149
DIRECTION_45 m_initial_direction
routing direction for new traces
void KillChildren()
Definition: pns_node.cpp:1405
LINE m_tail
routing "tail": part of the track that has been already fixed due to collisions with obstacles
bool SplitAdjacentSegments(NODE *aNode, ITEM *aSeg, const VECTOR2I &aP)
Check if point aP lies on segment aSeg.
std::unique_ptr< SHOVE > m_shove
The shove engine.
DIRECTION_45 m_direction
current routing direction
SHAPE_LINE_CHAIN & Line()
Definition: pns_line.h:136
NODE * m_currentNode
Current world state.
void setWorld(NODE *aWorld)
Set the board to route.
void Clear()
Remove all points from the line chain.
VECTOR2I m_p_start
current routing start (end of tail, beginning of head)
NODE * GetWorld() const
Definition: pns_router.h:153

References PNS::NODE::Branch(), SHAPE_LINE_CHAIN::Clear(), DIRECTION_45::Format(), PNS::ROUTER::GetWorld(), PNS::NODE::KillChildren(), PNS::LINE::Line(), m_currentLayer, m_currentNet, m_currentNode, m_currentStart, m_direction, m_head, m_idle, m_initial_direction, m_lastNode, m_p_start, m_shove, m_sizes, m_startItem, m_tail, m_world, PNS::LINE::RemoveVia(), PNS::ALGO_BASE::Router(), PNS::ITEM::SetLayer(), PNS::ITEM::SetNet(), PNS::LINE::SetWidth(), setWorld(), SplitAdjacentSegments(), and PNS::SIZES_SETTINGS::TrackWidth().

Referenced by Start().

◆ IsPlacingVia()

bool PNS::LINE_PLACER::IsPlacingVia ( ) const
inlineoverridevirtual

Function IsPlacingVia()

Returns true if the placer is placing a via (or more vias).

Reimplemented from PNS::PLACEMENT_ALGO.

Definition at line 196 of file pns_line_placer.h.

196 { return m_placingVia; }

References m_placingVia.

◆ Logger()

LOGGER * PNS::ALGO_BASE::Logger ( )
virtualinherited

Reimplemented in PNS::SHOVE.

Definition at line 34 of file pns_algo_base.cpp.

35 {
36  return nullptr;
37 }

Referenced by rhShoveOnly(), rhWalkOnly(), PNS::DRAGGER::Start(), and PNS::DRAGGER::tryWalkaround().

◆ makeVia()

const VIA PNS::LINE_PLACER::makeVia ( const VECTOR2I aP)
private

◆ mergeHead()

bool PNS::LINE_PLACER::mergeHead ( )
private

Moves "established" segments from the head to the tail if certain conditions are met.

Returns
true, if the line has been changed.

Definition at line 324 of file pns_line_placer.cpp.

325 {
326  SHAPE_LINE_CHAIN& head = m_head.Line();
327  SHAPE_LINE_CHAIN& tail = m_tail.Line();
328 
329  const int ForbiddenAngles = DIRECTION_45::ANG_ACUTE
332 
333  head.Simplify();
334  tail.Simplify();
335 
336  int n_head = head.ShapeCount();
337  int n_tail = tail.ShapeCount();
338 
339  if( n_head < 3 )
340  {
341  wxLogTrace( "PNS", "Merge failed: not enough head segs." );
342  return false;
343  }
344 
345  if( n_tail && head.CPoint( 0 ) != tail.CPoint( -1 ) )
346  {
347  wxLogTrace( "PNS", "Merge failed: head and tail discontinuous." );
348  return false;
349  }
350 
351  if( m_head.CountCorners( ForbiddenAngles ) != 0 )
352  return false;
353 
354  DIRECTION_45 dir_tail, dir_head;
355 
356  if( !head.IsPtOnArc( 0 ) )
357  dir_head = DIRECTION_45( head.CSegment( 0 ) );
358  else
359  dir_head = DIRECTION_45( head.CArcs()[head.ArcIndex( 0 )] );
360 
361  if( n_tail )
362  {
363  wxASSERT( tail.PointCount() >= 2 );
364  int lastSegIdx = tail.PointCount() - 2;
365 
366  if( !tail.IsPtOnArc( lastSegIdx ) )
367  dir_tail = DIRECTION_45( tail.CSegment( -1 ) );
368  else
369  dir_tail = DIRECTION_45( tail.CArcs()[tail.ArcIndex( lastSegIdx )] );
370 
371  if( dir_head.Angle( dir_tail ) & ForbiddenAngles )
372  return false;
373  }
374 
375  tail.Append( head );
376 
377  tail.Simplify();
378 
379  SEG last = tail.CSegment( -1 );
380  m_p_start = last.B;
381 
382  int lastSegIdx = tail.PointCount() - 2;
383 
384  if( !tail.IsArcSegment( lastSegIdx ) )
385  m_direction = DIRECTION_45( tail.CSegment( -1 ) );
386  else
387  m_direction = DIRECTION_45( tail.CArcs()[tail.ArcIndex( lastSegIdx )] );
388 
389  head.Remove( 0, -1 );
390 
391  wxLogTrace( "PNS", "Placer: merge %d, new direction: %s", n_head,
392  m_direction.Format().c_str() );
393 
394  head.Simplify();
395  tail.Simplify();
396 
397  return true;
398 }
SHAPE_LINE_CHAIN & Simplify(bool aRemoveColinear=true)
Simplify the line chain by removing colinear adjacent segments and duplicate vertices.
const std::string Format() const
Format the direction in a human readable word.
Definition: direction45.h:117
LINE m_head
the volatile part of the track from the previously analyzed point to the current routing destination
const std::vector< SHAPE_ARC > & CArcs() const
int PointCount() const
Return the number of points (vertices) in this line chain.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
ssize_t ArcIndex(size_t aSegment) const
Return the arc index for the given segment index.
AngleType Angle(const DIRECTION_45 &aOther) const
Return the type of angle between directions (this) and aOther.
Definition: direction45.h:169
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
bool IsArcSegment(size_t aSegment) const
LINE m_tail
routing "tail": part of the track that has been already fixed due to collisions with obstacles
Represent route directions & corner angles in a 45-degree metric.
Definition: direction45.h:36
DIRECTION_45 m_direction
current routing direction
int ShapeCount() const
Return the number of shapes (line segments or arcs) in this line chain.
void Remove(int aStartIndex, int aEndIndex)
Remove the range of points [start_index, end_index] from the line chain.
bool IsPtOnArc(size_t aPtIndex) const
SHAPE_LINE_CHAIN & Line()
Definition: pns_line.h:136
Definition: seg.h:40
const SEG CSegment(int aIndex) const
Return a constant copy of the aIndex segment in the line chain.
Represent a polyline (an zero-thickness chain of connected line segments).
VECTOR2I m_p_start
current routing start (end of tail, beginning of head)
int CountCorners(int aAngles) const
Definition: pns_line.cpp:135
VECTOR2I B
Definition: seg.h:49

References DIRECTION_45::ANG_ACUTE, DIRECTION_45::ANG_HALF_FULL, DIRECTION_45::ANG_UNDEFINED, DIRECTION_45::Angle(), SHAPE_LINE_CHAIN::Append(), SHAPE_LINE_CHAIN::ArcIndex(), SEG::B, SHAPE_LINE_CHAIN::CArcs(), PNS::LINE::CountCorners(), SHAPE_LINE_CHAIN::CPoint(), SHAPE_LINE_CHAIN::CSegment(), DIRECTION_45::Format(), SHAPE_LINE_CHAIN::IsArcSegment(), SHAPE_LINE_CHAIN::IsPtOnArc(), PNS::LINE::Line(), m_direction, m_head, m_p_start, m_tail, SHAPE_LINE_CHAIN::PointCount(), SHAPE_LINE_CHAIN::Remove(), SHAPE_LINE_CHAIN::ShapeCount(), and SHAPE_LINE_CHAIN::Simplify().

Referenced by routeStep().

◆ Move()

bool PNS::LINE_PLACER::Move ( const VECTOR2I aP,
ITEM aEndItem 
)
overridevirtual

Move the end of the currently routed trace to the point aP, taking aEndItem as anchor (if not NULL).

Implements PNS::PLACEMENT_ALGO.

Definition at line 1196 of file pns_line_placer.cpp.

1197 {
1198  LINE current;
1199  VECTOR2I p = aP;
1200  int eiDepth = -1;
1201 
1202  if( aEndItem && aEndItem->Owner() )
1203  eiDepth = static_cast<NODE*>( aEndItem->Owner() )->Depth();
1204 
1205  if( m_lastNode )
1206  {
1207  delete m_lastNode;
1208  m_lastNode = nullptr;
1209  }
1210 
1211  bool reachesEnd = route( p );
1212 
1213  current = Trace();
1214 
1215  if( !current.PointCount() )
1217  else
1218  m_currentEnd = current.CLine().CPoint( -1 );
1219 
1220  NODE* latestNode = m_currentNode;
1221  m_lastNode = latestNode->Branch();
1222 
1223  if( reachesEnd
1224  && eiDepth >= 0
1225  && aEndItem && latestNode->Depth() > eiDepth
1226  && current.SegmentCount() )
1227  {
1228  SplitAdjacentSegments( m_lastNode, aEndItem, current.CPoint( -1 ) );
1229 
1230  if( Settings().RemoveLoops() )
1231  removeLoops( m_lastNode, current );
1232  }
1233 
1236  return true;
1237 }
NODE * m_lastNode
Postprocessed world state (including marked collisions & removed loops)
void removeLoops(NODE *aNode, LINE &aLatest)
Searches aNode for traces concurrent to aLatest and removes them.
const LINE Trace() const
Return the complete routed line.
NODE * Branch()
Create a lightweight copy (called branch) of self that tracks the changes (added/removed items) wrs t...
Definition: pns_node.cpp:137
bool RemoveLoops() const
Enable/disable loop (redundant track) removal.
ROUTING_SETTINGS & Settings() const
Return the logger object, allowing to dump geometry to a file.
bool SplitAdjacentSegments(NODE *aNode, ITEM *aSeg, const VECTOR2I &aP)
Check if point aP lies on segment aSeg.
void AddTrailPoint(const VECTOR2I &aP)
void updateLeadingRatLine()
Draw the "leading" rats nest line, which connects the end of currently routed track and the nearest y...
MOUSE_TRAIL_TRACER m_mouseTrailTracer
bool route(const VECTOR2I &aP)
Re-route the current track to point aP.
NODE * m_currentNode
Current world state.
VECTOR2I m_p_start
current routing start (end of tail, beginning of head)

References PNS::MOUSE_TRAIL_TRACER::AddTrailPoint(), PNS::NODE::Branch(), PNS::LINE::CLine(), PNS::LINE::CPoint(), SHAPE_LINE_CHAIN::CPoint(), PNS::NODE::Depth(), m_currentEnd, m_currentNode, m_lastNode, m_mouseTrailTracer, m_p_start, PNS::ITEM::Owner(), PNS::LINE::PointCount(), PNS::ROUTING_SETTINGS::RemoveLoops(), removeLoops(), route(), PNS::LINE::SegmentCount(), PNS::ALGO_BASE::Settings(), SplitAdjacentSegments(), Trace(), and updateLeadingRatLine().

Referenced by SetLayer().

◆ optimizeTailHeadTransition()

bool PNS::LINE_PLACER::optimizeTailHeadTransition ( )
private

Try to reduce the corner count of the most recent part of tail/head by merging obtuse/collinear segments.

Returns
true if the line has been changed.

Definition at line 824 of file pns_line_placer.cpp.

825 {
826  LINE linetmp = Trace();
827 
828  PNS_DBG( Dbg(), Message, "optimize HT" );
829 
830  // NOTE: FANOUT_CLEANUP can override posture setting at the moment
833  {
834  if( linetmp.SegmentCount() < 1 )
835  return false;
836 
837  m_head = linetmp;
838  m_p_start = linetmp.CLine().CPoint( 0 );
839  m_direction = DIRECTION_45( linetmp.CSegment( 0 ) );
840  m_tail.Line().Clear();
841 
842  PNS_DBG( Dbg(), Message, wxString::Format( "Placer: optimize fanout-cleanup" ) );
843 
844 
845  return true;
846  }
847 
848  SHAPE_LINE_CHAIN& head = m_head.Line();
849  SHAPE_LINE_CHAIN& tail = m_tail.Line();
850 
851  int tailLookbackSegments = 3;
852 
853  //if(m_currentMode() == RM_Walkaround)
854  // tailLookbackSegments = 10000;
855 
856  int threshold = std::min( tail.PointCount(), tailLookbackSegments + 1 );
857 
858  if( tail.ShapeCount() < 3 )
859  return false;
860 
861  // assemble TailLookbackSegments tail segments with the current head
862  SHAPE_LINE_CHAIN opt_line = tail.Slice( -threshold, -1 );
863 
864  int end = std::min(2, head.PointCount() - 1 );
865 
866  opt_line.Append( head.Slice( 0, end ) );
867 
868  LINE new_head( m_tail, opt_line );
869 
870  // and see if it could be made simpler by merging obtuse/collnear segments.
871  // If so, replace the (threshold) last tail points and the head with
872  // the optimized line
873 
874 
875  PNS_DBG( Dbg(), AddLine, new_head.CLine(), LIGHTCYAN, 10000, "ht-newline" );
876 
878  {
879  LINE tmp( m_tail, opt_line );
880 
881  PNS_DBG( Dbg(), Message, wxString::Format( "Placer: optimize tail-head [%d]", threshold ) );
882 
883  head.Clear();
884  tail.Replace( -threshold, -1, new_head.CLine() );
885  tail.Simplify();
886 
887  m_p_start = new_head.CLine().CPoint( -1 );
888  m_direction = DIRECTION_45( new_head.CSegment( -1 ) );
889 
890  return true;
891  }
892 
893  return false;
894 }
SHAPE_LINE_CHAIN & Simplify(bool aRemoveColinear=true)
Simplify the line chain by removing colinear adjacent segments and duplicate vertices.
const SHAPE_LINE_CHAIN Slice(int aStartIndex, int aEndIndex=-1) const
Return a subset of this line chain containing the [start_index, end_index] range of points.
Simplify pad-pad and pad-via connections if possible.
LINE m_head
the volatile part of the track from the previously analyzed point to the current routing destination
const LINE Trace() const
Return the complete routed line.
int PointCount() const
Return the number of points (vertices) in this line chain.
static bool Optimize(LINE *aLine, int aEffortLevel, NODE *aWorld, const VECTOR2I &aV=VECTOR2I(0, 0))
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
LINE m_tail
routing "tail": part of the track that has been already fixed due to collisions with obstacles
Represent route directions & corner angles in a 45-degree metric.
Definition: direction45.h:36
DIRECTION_45 m_direction
current routing direction
#define PNS_DBG(dbg, method,...)
DEBUG_DECORATOR * Dbg() const
Definition: pns_algo_base.h:78
int ShapeCount() const
Return the number of shapes (line segments or arcs) in this line chain.
MOUSE_TRAIL_TRACER m_mouseTrailTracer
Reduce corner cost iteratively.
Definition: pns_optimizer.h:99
SHAPE_LINE_CHAIN & Line()
Definition: pns_line.h:136
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
NODE * m_currentNode
Current world state.
Represent a polyline (an zero-thickness chain of connected line segments).
void Clear()
Remove all points from the line chain.
VECTOR2I m_p_start
current routing start (end of tail, beginning of head)
void Replace(int aStartIndex, int aEndIndex, const VECTOR2I &aP)
Replace points with indices in range [start_index, end_index] with a single point aP.

References SHAPE_LINE_CHAIN::Append(), SHAPE_LINE_CHAIN::Clear(), PNS::LINE::CLine(), SHAPE_LINE_CHAIN::CPoint(), PNS::LINE::CSegment(), PNS::ALGO_BASE::Dbg(), PNS::OPTIMIZER::FANOUT_CLEANUP, Format(), PNS::MOUSE_TRAIL_TRACER::IsManuallyForced(), LIGHTCYAN, PNS::LINE::Line(), m_currentNode, m_direction, m_head, m_mouseTrailTracer, m_p_start, m_tail, PNS::OPTIMIZER::MERGE_SEGMENTS, PNS::OPTIMIZER::Optimize(), PNS_DBG, SHAPE_LINE_CHAIN::PointCount(), SHAPE_LINE_CHAIN::Replace(), PNS::LINE::SegmentCount(), SHAPE_LINE_CHAIN::ShapeCount(), SHAPE_LINE_CHAIN::Simplify(), SHAPE_LINE_CHAIN::Slice(), and Trace().

Referenced by routeStep().

◆ reduceTail()

bool PNS::LINE_PLACER::reduceTail ( const VECTOR2I aEnd)
private

Attempt to reduce the number of segments in the tail by trying to replace a certain number of latest tail segments with a direct trace leading to aEnd that does not collide with anything.

Parameters
aEndis the current routing destination point.
Returns
true if the line has been changed.

Definition at line 259 of file pns_line_placer.cpp.

260 {
261  SHAPE_LINE_CHAIN& head = m_head.Line();
262  SHAPE_LINE_CHAIN& tail = m_tail.Line();
263 
264  int n = tail.SegmentCount();
265 
266  if( head.SegmentCount() < 1 )
267  return false;
268 
269  // Don't attempt this for too short tails
270  if( n < 2 )
271  return false;
272 
273  // Start from the segment farthest from the end of the tail
274  // int start_index = std::max(n - 1 - ReductionDepth, 0);
275 
276  DIRECTION_45 new_direction;
277  VECTOR2I new_start;
278  int reduce_index = -1;
279 
280  for( int i = tail.SegmentCount() - 1; i >= 0; i-- )
281  {
282  const SEG s = tail.CSegment( i );
283  DIRECTION_45 dir( s );
284 
285  // calculate a replacement route and check if it matches
286  // the direction of the segment to be replaced
287  SHAPE_LINE_CHAIN replacement = dir.BuildInitialTrace( s.A, aEnd );
288 
289  if( replacement.SegmentCount() < 1 )
290  continue;
291 
292  LINE tmp( m_tail, replacement );
293 
295  break;
296 
297  if( DIRECTION_45( replacement.CSegment( 0 ) ) == dir )
298  {
299  new_start = s.A;
300  new_direction = dir;
301  reduce_index = i;
302  }
303  }
304 
305  if( reduce_index >= 0 )
306  {
307  wxLogTrace( "PNS", "Placer: reducing tail: %d", reduce_index );
308  SHAPE_LINE_CHAIN reducedLine = new_direction.BuildInitialTrace( new_start, aEnd );
309 
310  m_p_start = new_start;
311  m_direction = new_direction;
312  tail.Remove( reduce_index + 1, -1 );
313  head.Clear();
314  return true;
315  }
316 
317  if( !tail.SegmentCount() )
319 
320  return false;
321 }
LINE m_head
the volatile part of the track from the previously analyzed point to the current routing destination
DIRECTION_45 m_initial_direction
routing direction for new traces
LINE m_tail
routing "tail": part of the track that has been already fixed due to collisions with obstacles
Represent route directions & corner angles in a 45-degree metric.
Definition: direction45.h:36
DIRECTION_45 m_direction
current routing direction
const SHAPE_LINE_CHAIN BuildInitialTrace(const VECTOR2I &aP0, const VECTOR2I &aP1, bool aStartDiagonal=false, bool aFillet=false) const
Build a 2-segment line chain between points aP0 and aP1 and following 45-degree routing regime.
void Remove(int aStartIndex, int aEndIndex)
Remove the range of points [start_index, end_index] from the line chain.
int SegmentCount() const
Return the number of segments in this line chain.
SHAPE_LINE_CHAIN & Line()
Definition: pns_line.h:136
Definition: seg.h:40
NODE * m_currentNode
Current world state.
const SEG CSegment(int aIndex) const
Return a constant copy of the aIndex segment in the line chain.
Represent a polyline (an zero-thickness chain of connected line segments).
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.
Definition: pns_node.cpp:450
VECTOR2I A
Definition: seg.h:48
void Clear()
Remove all points from the line chain.
VECTOR2I m_p_start
current routing start (end of tail, beginning of head)

References SEG::A, PNS::ITEM::ANY_T, DIRECTION_45::BuildInitialTrace(), PNS::NODE::CheckColliding(), SHAPE_LINE_CHAIN::Clear(), SHAPE_LINE_CHAIN::CSegment(), PNS::LINE::Line(), m_currentNode, m_direction, m_head, m_initial_direction, m_p_start, m_tail, SHAPE_LINE_CHAIN::Remove(), and SHAPE_LINE_CHAIN::SegmentCount().

Referenced by routeStep().

◆ removeLoops()

void PNS::LINE_PLACER::removeLoops ( NODE aNode,
LINE aLatest 
)
private

Searches aNode for traces concurrent to aLatest and removes them.

Updated topology is stored in aNode.

Definition at line 1480 of file pns_line_placer.cpp.

1481 {
1482  if( !aLatest.SegmentCount() )
1483  return;
1484 
1485  if( aLatest.CLine().CPoint( 0 ) == aLatest.CLine().CPoint( -1 ) )
1486  return;
1487 
1488  std::set<LINKED_ITEM *> toErase;
1489  aNode->Add( aLatest, true );
1490 
1491  for( int s = 0; s < aLatest.LinkCount(); s++ )
1492  {
1493  LINKED_ITEM* seg = aLatest.GetLink(s);
1494  LINE ourLine = aNode->AssembleLine( seg );
1495  JOINT a, b;
1496  std::vector<LINE> lines;
1497 
1498  aNode->FindLineEnds( ourLine, a, b );
1499 
1500  if( a == b )
1501  aNode->FindLineEnds( aLatest, a, b );
1502 
1503  aNode->FindLinesBetweenJoints( a, b, lines );
1504 
1505  int removedCount = 0;
1506  int total = 0;
1507 
1508  for( LINE& line : lines )
1509  {
1510  total++;
1511 
1512  if( !( line.ContainsLink( seg ) ) && line.SegmentCount() )
1513  {
1514  for( LINKED_ITEM* ss : line.Links() )
1515  toErase.insert( ss );
1516 
1517  removedCount++;
1518  }
1519  }
1520 
1521  wxLogTrace( "PNS", "total segs removed: %d/%d", removedCount, total );
1522  }
1523 
1524  for( LINKED_ITEM* s : toErase )
1525  aNode->Remove( s );
1526 
1527  aNode->Remove( aLatest );
1528 }

References PNS::NODE::Add(), PNS::NODE::AssembleLine(), PNS::LINE::CLine(), SHAPE_LINE_CHAIN::CPoint(), PNS::NODE::FindLineEnds(), PNS::NODE::FindLinesBetweenJoints(), PNS::LINK_HOLDER::GetLink(), PNS::LINK_HOLDER::LinkCount(), PNS::NODE::Remove(), and PNS::LINE::SegmentCount().

Referenced by Move().

◆ rhMarkObstacles()

bool PNS::LINE_PLACER::rhMarkObstacles ( const VECTOR2I aP,
LINE aNewHead 
)
private

Definition at line 677 of file pns_line_placer.cpp.

678 {
679  buildInitialLine( aP, m_head );
680  m_head.SetBlockingObstacle( nullptr );
681 
682  // Note: Something like the below could be used to implement a "stop at first obstacle" mode,
683  // but we don't have one right now and there isn't a lot of demand for one. If we do end up
684  // doing that, put it in a new routing mode as "highlight collisions" mode should not have
685  // collision handling other than highlighting.
686 #if 0
687  if( !Settings().AllowDRCViolations() )
688  {
690 
691  if( obs && obs->m_distFirst != INT_MAX )
692  {
693  buildInitialLine( obs->m_ipFirst, m_head );
694  m_head.SetBlockingObstacle( obs->m_item );
695  }
696  }
697 #endif
698 
699  aNewHead = m_head;
700 
701  return true;
702 }
LINE m_head
the volatile part of the track from the previously analyzed point to the current routing destination
ROUTING_SETTINGS & Settings() const
Return the logger object, allowing to dump geometry to a file.
OPT_OBSTACLE NearestObstacle(const LINE *aLine, int aKindMask=ITEM::ANY_T, const std::set< ITEM * > *aRestrictedSet=nullptr)
Follow the line in search of an obstacle that is nearest to the starting to the line's starting point...
Definition: pns_node.cpp:296
NODE * m_currentNode
Current world state.
OPT< OBSTACLE > OPT_OBSTACLE
Definition: pns_node.h:147
bool buildInitialLine(const VECTOR2I &aP, LINE &aHead, bool aForceNoVia=false)
void SetBlockingObstacle(ITEM *aObstacle)
Definition: pns_line.h:205

References buildInitialLine(), m_currentNode, m_head, PNS::NODE::NearestObstacle(), PNS::LINE::SetBlockingObstacle(), and PNS::ALGO_BASE::Settings().

Referenced by routeHead().

◆ rhShoveOnly()

bool PNS::LINE_PLACER::rhShoveOnly ( const VECTOR2I aP,
LINE aNewHead 
)
private

Route step mark obstacles mode.

Definition at line 705 of file pns_line_placer.cpp.

706 {
707  LINE initTrack( m_head );
708  LINE walkSolids, l2;
709 
710  bool viaOk = buildInitialLine( aP, initTrack );
711 
712  m_currentNode = m_shove->CurrentNode();
713 
714  m_shove->SetLogger( Logger() );
715  m_shove->SetDebugDecorator( Dbg() );
716 
717  OPTIMIZER optimizer( m_currentNode );
718 
719  WALKAROUND walkaround( m_currentNode, Router() );
720 
721  walkaround.SetSolidsOnly( true );
722  walkaround.SetIterationLimit( 10 );
723  walkaround.SetDebugDecorator( Dbg() );
724  walkaround.SetLogger( Logger() );
725  WALKAROUND::WALKAROUND_STATUS stat_solids = walkaround.Route( initTrack, walkSolids );
726 
727  optimizer.SetEffortLevel( OPTIMIZER::MERGE_SEGMENTS );
728  optimizer.SetCollisionMask( ITEM::SOLID_T );
729  optimizer.Optimize( &walkSolids );
730 
731  if( stat_solids == WALKAROUND::DONE )
732  l2 = walkSolids;
733  else
734  l2 = initTrack.ClipToNearestObstacle( m_shove->CurrentNode() );
735 
736  LINE l( m_tail );
737  l.Line().Append( l2.CLine() );
738  l.Line().Simplify();
739 
740  if( l.PointCount() == 0 || l2.PointCount() == 0 )
741  {
742  aNewHead = m_head;
743  return false;
744  }
745 
746  if( m_placingVia && viaOk )
747  {
748  VIA v1( makeVia( l.CPoint( -1 ) ) );
749  VIA v2( makeVia( l2.CPoint( -1 ) ) );
750 
751  l.AppendVia( v1 );
752  l2.AppendVia( v2 );
753  }
754 
755  l.Line().Simplify();
756 
757  // in certain, uncommon cases there may be loops in the head+tail, In such case, we don't
758  // shove to avoid screwing up the database.
759  if( l.HasLoops() )
760  {
761  aNewHead = m_head;
762  return false;
763  }
764 
765  SHOVE::SHOVE_STATUS status = m_shove->ShoveLines( l );
766 
767  m_currentNode = m_shove->CurrentNode();
768 
769  if( status == SHOVE::SH_OK || status == SHOVE::SH_HEAD_MODIFIED )
770  {
771  if( status == SHOVE::SH_HEAD_MODIFIED )
772  l2 = m_shove->NewHead();
773 
774  optimizer.SetWorld( m_currentNode );
775 
776  int effortLevel = OPTIMIZER::MERGE_OBTUSE;
777 
778  if( Settings().SmartPads() && !m_mouseTrailTracer.IsManuallyForced() )
779  effortLevel = OPTIMIZER::SMART_PADS;
780 
781  optimizer.SetEffortLevel( effortLevel );
782 
783  optimizer.SetCollisionMask( ITEM::ANY_T );
784  optimizer.Optimize( &l2 );
785 
786  aNewHead = l2;
787 
788  return true;
789  }
790  else
791  {
792  walkaround.SetWorld( m_currentNode );
793  walkaround.SetSolidsOnly( false );
794  walkaround.SetIterationLimit( 10 );
795  walkaround.SetApproachCursor( true, aP );
796  walkaround.Route( initTrack, l2 );
797  aNewHead = l2.ClipToNearestObstacle( m_shove->CurrentNode() );
798 
799  return false;
800  }
801 
802  return false;
803 }
ROUTER * Router() const
Return current router settings.
Definition: pns_algo_base.h:54
VECTOR2I v2(1, 0)
Test suite for KiCad math code.
virtual LOGGER * Logger()
LINE m_head
the volatile part of the track from the previously analyzed point to the current routing destination
ROUTING_SETTINGS & Settings() const
Return the logger object, allowing to dump geometry to a file.
Normal via.
Definition: router_tool.cpp:72
LINE m_tail
routing "tail": part of the track that has been already fixed due to collisions with obstacles
std::unique_ptr< SHOVE > m_shove
The shove engine.
DEBUG_DECORATOR * Dbg() const
Definition: pns_algo_base.h:78
MOUSE_TRAIL_TRACER m_mouseTrailTracer
Reduce corner cost iteratively.
Definition: pns_optimizer.h:99
NODE * m_currentNode
Current world state.
Reduce corner cost by merging obtuse segments.
const VIA makeVia(const VECTOR2I &aP)
Reroute pad exits.
bool buildInitialLine(const VECTOR2I &aP, LINE &aHead, bool aForceNoVia=false)

References PNS::ITEM::ANY_T, SHAPE_LINE_CHAIN::Append(), PNS::LINE::AppendVia(), buildInitialLine(), PNS::LINE::CLine(), PNS::LINE::ClipToNearestObstacle(), PNS::LINE::CPoint(), PNS::ALGO_BASE::Dbg(), PNS::WALKAROUND::DONE, PNS::LINE::HasLoops(), PNS::MOUSE_TRAIL_TRACER::IsManuallyForced(), PNS::LINE::Line(), PNS::ALGO_BASE::Logger(), m_currentNode, m_head, m_mouseTrailTracer, m_placingVia, m_shove, m_tail, makeVia(), PNS::OPTIMIZER::MERGE_OBTUSE, PNS::OPTIMIZER::MERGE_SEGMENTS, PNS::OPTIMIZER::Optimize(), PNS::LINE::PointCount(), PNS::WALKAROUND::Route(), PNS::ALGO_BASE::Router(), PNS::WALKAROUND::SetApproachCursor(), PNS::OPTIMIZER::SetCollisionMask(), PNS::ALGO_BASE::SetDebugDecorator(), PNS::OPTIMIZER::SetEffortLevel(), PNS::WALKAROUND::SetIterationLimit(), PNS::ALGO_BASE::SetLogger(), PNS::WALKAROUND::SetSolidsOnly(), PNS::ALGO_BASE::Settings(), PNS::WALKAROUND::SetWorld(), PNS::OPTIMIZER::SetWorld(), PNS::SHOVE::SH_HEAD_MODIFIED, PNS::SHOVE::SH_OK, SHAPE_LINE_CHAIN::Simplify(), PNS::OPTIMIZER::SMART_PADS, PNS::ITEM::SOLID_T, and v2.

Referenced by routeHead().

◆ rhWalkOnly()

bool PNS::LINE_PLACER::rhWalkOnly ( const VECTOR2I aP,
LINE aNewHead 
)
private

Route step shove mode.

Definition at line 526 of file pns_line_placer.cpp.

527 {
528  LINE initTrack( m_head );
529  LINE walkFull( m_head );
530 
531  initTrack.RemoveVia();
532  walkFull.RemoveVia();
533 
534  int effort = 0;
535  bool viaOk = false;
536 
537  VECTOR2I walkP = aP;
538 
539  WALKAROUND walkaround( m_currentNode, Router() );
540 
541  walkaround.SetSolidsOnly( false );
542  walkaround.SetDebugDecorator( Dbg() );
543  walkaround.SetLogger( Logger() );
544  walkaround.SetIterationLimit( Settings().WalkaroundIterationLimit() );
545 
546  char name[50];
547  int round = 0;
548 
549  do {
550  snprintf( name, sizeof( name ), "walk-round-%d", round );
551  PNS_DBG( Dbg(), BeginGroup, name );
552 
553  viaOk = buildInitialLine( walkP, initTrack, round == 0 );
554 
555  double initialLength = initTrack.CLine().Length();
556  double hugThresholdLength = initialLength * Settings().WalkaroundHugLengthThreshold();
557 
558  WALKAROUND::RESULT wr = walkaround.Route( initTrack );
559 
560  SHAPE_LINE_CHAIN l_cw = wr.lineCw.CLine();
561  SHAPE_LINE_CHAIN l_ccw = wr.lineCcw.CLine();
562 
563  if( wr.statusCcw == WALKAROUND::DONE || wr.statusCw == WALKAROUND::DONE )
564  {
565  int len_cw = wr.statusCw == WALKAROUND::DONE ? l_cw.Length() : INT_MAX;
566  int len_ccw = wr.statusCcw == WALKAROUND::DONE ? l_ccw.Length() : INT_MAX;
567 
568  PNS_DBG( Dbg(), AddLine, wr.lineCw.CLine(), CYAN, 10000, "wf-result-cw" );
569  PNS_DBG( Dbg(), AddLine, wr.lineCcw.CLine(), BLUE, 20000, "wf-result-ccw" );
570 
571  int bestLength = len_cw < len_ccw ? len_cw : len_ccw;
572 
573  if( bestLength > hugThresholdLength )
574  {
575  wr.statusCw = WALKAROUND::ALMOST_DONE;
576  wr.statusCcw = WALKAROUND::ALMOST_DONE;
577  }
578 
579  SHAPE_LINE_CHAIN& bestLine = len_cw < len_ccw ? l_cw : l_ccw;
580  walkFull.SetShape( bestLine );
581  }
582 
583  if( wr.statusCcw == WALKAROUND::ALMOST_DONE || wr.statusCw == WALKAROUND::ALMOST_DONE )
584  {
585  bool valid_cw = false, valid_ccw = false;
586  VECTOR2I p_cw, p_ccw;
587  int dist_ccw = 0, dist_cw = 0;
588 
589  if( wr.statusCcw == WALKAROUND::ALMOST_DONE )
590  {
591  valid_ccw = cursorDistMinimum( l_ccw, aP, hugThresholdLength, dist_ccw, p_ccw );
592 
593  if( valid_ccw )
594  {
595  int idx_ccw = l_ccw.Split( p_ccw );
596  l_ccw = l_ccw.Slice( 0, idx_ccw );
597  PNS_DBG( Dbg(), AddPoint, p_ccw, BLUE, 500000, "hug-target-ccw" );
598  PNS_DBG( Dbg(), AddLine, l_ccw, MAGENTA, 200000, "wh-result-ccw" );
599  }
600  }
601 
602  if( wr.statusCw == WALKAROUND::ALMOST_DONE )
603  {
604  valid_cw = cursorDistMinimum( l_cw, aP, hugThresholdLength, dist_cw, p_cw );
605 
606  if( valid_cw )
607  {
608  int idx_cw = l_cw.Split( p_cw );
609  l_cw = l_cw.Slice( 0, idx_cw );
610  PNS_DBG( Dbg(), AddPoint, p_cw, YELLOW, 500000, "hug-target-cw" );
611  PNS_DBG( Dbg(), AddLine, l_cw, BLUE, 200000, "wh-result-cw" );
612  }
613  }
614 
615  if( dist_cw < dist_ccw && valid_cw )
616  {
617  walkFull.SetShape( l_cw );
618  walkP = p_cw;
619  }
620  else if ( valid_ccw )
621  {
622  walkFull.SetShape( l_ccw );
623  walkP = p_ccw;
624  }
625  else
626  {
627  PNS_DBGN( Dbg(), EndGroup );
628  return false;
629  }
630  }
631  else if ( wr.statusCcw == WALKAROUND::STUCK || wr.statusCw == WALKAROUND::STUCK )
632  {
633  PNS_DBGN( Dbg(), EndGroup );
634  return false;
635  }
636 
637  PNS_DBGN( Dbg(), EndGroup );
638 
639  round++;
640  } while( round < 2 && m_placingVia );
641 
642  PNS_DBG( Dbg(), AddLine, walkFull.CLine(), GREEN, 200000, "walk-full" );
643 
644  switch( Settings().OptimizerEffort() )
645  {
646  case OE_LOW:
647  effort = 0;
648  break;
649 
650  case OE_MEDIUM:
651  case OE_FULL:
652  effort = OPTIMIZER::MERGE_SEGMENTS;
653  break;
654  }
655 
657  effort |= OPTIMIZER::SMART_PADS;
658 
659  if( m_placingVia && viaOk )
660  {
661  walkFull.AppendVia( makeVia( walkFull.CPoint( -1 ) ) );
662  }
663 
664  OPTIMIZER::Optimize( &walkFull, effort, m_currentNode );
665 
666  if( m_currentNode->CheckColliding( &walkFull ) )
667  {
668  return false;
669  }
670 
671  aNewHead = walkFull;
672 
673  return true;
674 }
#define PNS_DBGN(dbg, method)
bool SmartPads() const
Enable/disable Smart Pads (optimized connections).
ROUTER * Router() const
Return current router settings.
Definition: pns_algo_base.h:54
long long int Length() const
Return length of the line chain in Euclidean metric.
int Split(const VECTOR2I &aP)
Insert the point aP belonging to one of the our segments, splitting the adjacent segment in two.
const SHAPE_LINE_CHAIN Slice(int aStartIndex, int aEndIndex=-1) const
Return a subset of this line chain containing the [start_index, end_index] range of points.
virtual LOGGER * Logger()
LINE m_head
the volatile part of the track from the previously analyzed point to the current routing destination
static bool Optimize(LINE *aLine, int aEffortLevel, NODE *aWorld, const VECTOR2I &aV=VECTOR2I(0, 0))
ROUTING_SETTINGS & Settings() const
Return the logger object, allowing to dump geometry to a file.
Definition: color4d.h:67
static bool cursorDistMinimum(const SHAPE_LINE_CHAIN &aL, const VECTOR2I &aCursor, double lengthThreshold, int &theDist, VECTOR2I &aNearest)
PNS_OPTIMIZATION_EFFORT OptimizerEffort() const
Set the optimizer effort. Bigger means cleaner traces, but slower routing.
Definition: color4d.h:57
#define PNS_DBG(dbg, method,...)
DEBUG_DECORATOR * Dbg() const
Definition: pns_algo_base.h:78
Definition: color4d.h:58
MOUSE_TRAIL_TRACER m_mouseTrailTracer
Reduce corner cost iteratively.
Definition: pns_optimizer.h:99
NODE * m_currentNode
Current world state.
Definition: color4d.h:56
const char * name
Definition: DXF_plotter.cpp:56
Represent a polyline (an zero-thickness chain of connected line segments).
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.
Definition: pns_node.cpp:450
double WalkaroundHugLengthThreshold() const
const VIA makeVia(const VECTOR2I &aP)
Reroute pad exits.
bool buildInitialLine(const VECTOR2I &aP, LINE &aHead, bool aForceNoVia=false)

References PNS::WALKAROUND::ALMOST_DONE, PNS::LINE::AppendVia(), BLUE, buildInitialLine(), PNS::NODE::CheckColliding(), PNS::LINE::CLine(), PNS::LINE::CPoint(), PNS::cursorDistMinimum(), CYAN, PNS::ALGO_BASE::Dbg(), PNS::WALKAROUND::DONE, GREEN, PNS::MOUSE_TRAIL_TRACER::IsManuallyForced(), SHAPE_LINE_CHAIN::Length(), PNS::WALKAROUND::RESULT::lineCcw, PNS::WALKAROUND::RESULT::lineCw, PNS::ALGO_BASE::Logger(), m_currentNode, m_head, m_mouseTrailTracer, m_placingVia, MAGENTA, makeVia(), PNS::OPTIMIZER::MERGE_SEGMENTS, name, PNS::OE_FULL, PNS::OE_LOW, PNS::OE_MEDIUM, PNS::OPTIMIZER::Optimize(), PNS::ROUTING_SETTINGS::OptimizerEffort(), PNS_DBG, PNS_DBGN, PNS::LINE::RemoveVia(), PNS::WALKAROUND::Route(), PNS::ALGO_BASE::Router(), PNS::ALGO_BASE::SetDebugDecorator(), PNS::WALKAROUND::SetIterationLimit(), PNS::ALGO_BASE::SetLogger(), PNS::LINE::SetShape(), PNS::WALKAROUND::SetSolidsOnly(), PNS::ALGO_BASE::Settings(), SHAPE_LINE_CHAIN::Slice(), PNS::OPTIMIZER::SMART_PADS, PNS::ROUTING_SETTINGS::SmartPads(), SHAPE_LINE_CHAIN::Split(), PNS::WALKAROUND::RESULT::statusCcw, PNS::WALKAROUND::RESULT::statusCw, PNS::WALKAROUND::STUCK, PNS::ROUTING_SETTINGS::WalkaroundHugLengthThreshold(), and YELLOW.

Referenced by routeHead().

◆ route()

bool PNS::LINE_PLACER::route ( const VECTOR2I aP)
private

Re-route the current track to point aP.

Returns true, when routing has completed successfully (i.e. the trace end has reached point aP), and false if the trace was stuck somewhere on the way. May call routeStep() repetitively due to mouse smoothing.

Parameters
aPending point of current route.
Returns
true, if the routing is complete.

Definition at line 994 of file pns_line_placer.cpp.

995 {
996  routeStep( aP );
997 
998  if (!m_head.PointCount() )
999  return false;
1000 
1001  return m_head.CPoint(-1) == aP;
1002 }
void routeStep(const VECTOR2I &aP)
Perform a single routing algorithm step, for the end point aP.
LINE m_head
the volatile part of the track from the previously analyzed point to the current routing destination
int PointCount() const
Definition: pns_line.h:140
const VECTOR2I & CPoint(int aIdx) const
Definition: pns_line.h:145

References PNS::LINE::CPoint(), m_head, PNS::LINE::PointCount(), and routeStep().

Referenced by Move().

◆ routeHead()

bool PNS::LINE_PLACER::routeHead ( const VECTOR2I aP,
LINE aNewHead 
)
private

Compute the head trace between the current start point (m_p_start) and point aP, starting with direction defined in m_direction.

The trace walks around all colliding solid or non-movable items. Movable segments are ignored, as they'll be handled later by the shove algorithm.

Definition at line 806 of file pns_line_placer.cpp.

807 {
808  switch( Settings().Mode() )
809  {
810  case RM_MarkObstacles:
811  return rhMarkObstacles( aP, aNewHead );
812  case RM_Walkaround:
813  return rhWalkOnly( aP, aNewHead );
814  case RM_Shove:
815  return rhShoveOnly( aP, aNewHead );
816  default:
817  break;
818  }
819 
820  return false;
821 }
bool rhWalkOnly(const VECTOR2I &aP, LINE &aNewHead)
Route step shove mode.
ROUTING_SETTINGS & Settings() const
Return the logger object, allowing to dump geometry to a file.
bool rhMarkObstacles(const VECTOR2I &aP, LINE &aNewHead)
bool rhShoveOnly(const VECTOR2I &aP, LINE &aNewHead)
Route step mark obstacles mode.
Ignore collisions, mark obstacles.
Only walk around.

References rhMarkObstacles(), rhShoveOnly(), rhWalkOnly(), PNS::RM_MarkObstacles, PNS::RM_Shove, PNS::RM_Walkaround, and PNS::ALGO_BASE::Settings().

Referenced by routeStep().

◆ Router()

◆ routeStep()

void PNS::LINE_PLACER::routeStep ( const VECTOR2I aP)
private

Perform a single routing algorithm step, for the end point aP.

Parameters
aPis the ending point of current route.
Returns
true if the line has been changed.Route step walk around mode.

Definition at line 897 of file pns_line_placer.cpp.

898 {
899  bool fail = false;
900  bool go_back = false;
901 
902  int i, n_iter = 1;
903 
904  LINE new_head;
905 
906  wxLogTrace( "PNS", "routeStep: direction: %s head: %d, tail: %d shapes",
907  m_direction.Format().c_str(),
908  m_head.ShapeCount(),
909  m_tail.ShapeCount() );
910 
911  PNS_DBG( Dbg(), BeginGroup, "route-step" );
912 
913  PNS_DBG( Dbg(), AddLine, m_tail.CLine(), WHITE, 10000, "tail-init" );
914  PNS_DBG( Dbg(), AddLine, m_head.CLine(), GREEN, 10000, "head-init" );
915 
916  for( i = 0; i < n_iter; i++ )
917  {
918  if( !go_back && Settings().FollowMouse() )
919  reduceTail( aP );
920 
921  PNS_DBG( Dbg(), AddLine, m_tail.CLine(), WHITE, 10000, "tail-after-reduce" );
922  PNS_DBG( Dbg(), AddLine, m_head.CLine(), GREEN, 10000, "head-after-reduce" );
923 
924  go_back = false;
925 
926  if( !routeHead( aP, new_head ) )
927  fail = true;
928 
929  if( !new_head.Is45Degree() &&
931  fail = true;
932 
933  if( fail )
934  break;
935 
936  m_head = new_head;
937 
938  PNS_DBG( Dbg(), AddLine, m_head.CLine(), LIGHTGREEN, 100000, "head-new" );
939 
941  {
942  n_iter++;
943  go_back = true;
944  }
945 
946  PNS_DBG( Dbg(), AddLine, m_tail.CLine(), WHITE, 10000, "tail-after-si" );
947  PNS_DBG( Dbg(), AddLine, m_head.CLine(), GREEN, 10000, "head-after-si" );
948 
949  if( !go_back && handlePullback() )
950  {
951  n_iter++;
952  go_back = true;
953  }
954 
955  PNS_DBG( Dbg(), AddLine, m_tail.CLine(), WHITE, 100000, "tail-after-pb" );
956  PNS_DBG( Dbg(), AddLine, m_head.CLine(), GREEN, 100000, "head-after-pb" );
957  }
958 
959  if( fail )
960  {
961  if( m_last_head.PointCount() > 0 )
962  {
964  }
965  else
966  {
967  m_head.RemoveVia();
968  m_head.Clear();
969  }
970  }
971  else
972  {
974  }
975 
976  if( !fail && Settings().FollowMouse() )
977  {
978  PNS_DBG( Dbg(), AddLine, m_tail.CLine(), WHITE, 10000, "tail-pre-merge" );
979  PNS_DBG( Dbg(), AddLine, m_head.CLine(), GREEN, 10000, "head-pre-merge" );
980 
982  {
983  mergeHead();
984  }
985 
986  PNS_DBG( Dbg(), AddLine, m_tail.CLine(), WHITE, 100000, "tail-post-merge" );
987  PNS_DBG( Dbg(), AddLine, m_head.CLine(), GREEN, 100000, "head-post-merge" );
988  }
989 
990  PNS_DBGN( Dbg(), EndGroup );
991 }
const SHAPE_LINE_CHAIN & CLine() const
Definition: pns_line.h:137
#define PNS_DBGN(dbg, method)
LINE m_last_head
Most recent successful (non-colliding) head.
const std::string Format() const
Format the direction in a human readable word.
Definition: direction45.h:117
LINE m_head
the volatile part of the track from the previously analyzed point to the current routing destination
void RemoveVia()
Definition: pns_line.h:194
bool reduceTail(const VECTOR2I &aEnd)
Attempt to reduce the number of segments in the tail by trying to replace a certain number of latest ...
int PointCount() const
Definition: pns_line.h:140
bool handlePullback()
Deal with pull-back: reduces the tail if head trace is moved backwards wrs to the current tail direct...
bool FollowMouse() const
Return true if smoothing segments during dragging is enabled.
ROUTING_SETTINGS & Settings() const
Return the logger object, allowing to dump geometry to a file.
LINE m_tail
routing "tail": part of the track that has been already fixed due to collisions with obstacles
DIRECTION_45 m_direction
current routing direction
Definition: color4d.h:57
#define PNS_DBG(dbg, method,...)
DEBUG_DECORATOR * Dbg() const
Definition: pns_algo_base.h:78
PNS_MODE Mode() const
Set the routing mode.
bool routeHead(const VECTOR2I &aP, LINE &aNewHead)
Compute the head trace between the current start point (m_p_start) and point aP, starting with direct...
bool handleSelfIntersections()
Check if the head of the track intersects its tail.
Definition: color4d.h:48
int ShapeCount() const
Return the aIdx-th point of the line.
Definition: pns_line.h:142
bool optimizeTailHeadTransition()
Try to reduce the corner count of the most recent part of tail/head by merging obtuse/collinear segme...
Ignore collisions, mark obstacles.
bool mergeHead()
Moves "established" segments from the head to the tail if certain conditions are met.
void Clear()
Definition: pns_line.cpp:1242

References PNS::LINE::Clear(), PNS::LINE::CLine(), PNS::ALGO_BASE::Dbg(), PNS::ROUTING_SETTINGS::FollowMouse(), DIRECTION_45::Format(), PNS::ROUTING_SETTINGS::GetFreeAngleMode(), GREEN, handlePullback(), handleSelfIntersections(), PNS::LINE::Is45Degree(), LIGHTGREEN, m_direction, m_head, m_last_head, m_tail, mergeHead(), PNS::ROUTING_SETTINGS::Mode(), optimizeTailHeadTransition(), PNS_DBG, PNS_DBGN, PNS::LINE::PointCount(), reduceTail(), PNS::LINE::RemoveVia(), PNS::RM_MarkObstacles, routeHead(), PNS::ALGO_BASE::Settings(), PNS::LINE::ShapeCount(), and WHITE.

Referenced by route().

◆ SetDebugDecorator()

void PNS::ALGO_BASE::SetDebugDecorator ( DEBUG_DECORATOR aDecorator)
inlineinherited

Assign a debug decorator allowing this algo to draw extra graphics for visual debugging.

Definition at line 73 of file pns_algo_base.h.

74  {
75  m_debugDecorator = aDecorator;
76  }
DEBUG_DECORATOR * m_debugDecorator
Definition: pns_algo_base.h:86

References PNS::ALGO_BASE::m_debugDecorator.

Referenced by rhShoveOnly(), rhWalkOnly(), PNS::SHOVE::SHOVE(), and PNS::DRAGGER::tryWalkaround().

◆ setInitialDirection()

void PNS::LINE_PLACER::setInitialDirection ( const DIRECTION_45 aDirection)
private

Set preferred direction of the very first track segment to be laid.

Used by posture switching mechanism.

Definition at line 92 of file pns_line_placer.cpp.

93 {
94  m_initial_direction = aDirection;
95 
96  if( m_tail.SegmentCount() == 0 )
97  m_direction = aDirection;
98 }
int SegmentCount() const
Definition: pns_line.h:139
DIRECTION_45 m_initial_direction
routing direction for new traces
LINE m_tail
routing "tail": part of the track that has been already fixed due to collisions with obstacles
DIRECTION_45 m_direction
current routing direction

References m_direction, m_initial_direction, m_tail, and PNS::LINE::SegmentCount().

Referenced by FixRoute(), and Start().

◆ SetLayer()

bool PNS::LINE_PLACER::SetLayer ( int  aLayer)
overridevirtual

Set the current routing layer.

Reimplemented from PNS::PLACEMENT_ALGO.

Definition at line 1066 of file pns_line_placer.cpp.

1067 {
1068  if( m_idle )
1069  {
1070  m_currentLayer = aLayer;
1071  return true;
1072  }
1073  else if( m_chainedPlacement )
1074  {
1075  return false;
1076  }
1077  else if( !m_startItem
1078  || ( m_startItem->OfKind( ITEM::VIA_T ) && m_startItem->Layers().Overlaps( aLayer ) )
1079  || ( m_startItem->OfKind( ITEM::SOLID_T ) && m_startItem->Layers().Overlaps( aLayer ) ) )
1080  {
1081  m_currentLayer = aLayer;
1082  m_head.Line().Clear();
1083  m_tail.Line().Clear();
1084  m_last_head.Line().Clear();
1085  m_head.RemoveVia();
1086  m_tail.RemoveVia();
1090  Move( m_currentEnd, nullptr );
1091  return true;
1092  }
1093 
1094  return false;
1095 }
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).
LINE m_last_head
Most recent successful (non-colliding) head.
void SetLayer(int aLayer)
Definition: pns_item.h:155
LINE m_head
the volatile part of the track from the previously analyzed point to the current routing destination
bool Overlaps(const LAYER_RANGE &aOther) const
Definition: pns_layerset.h:67
void RemoveVia()
Definition: pns_line.h:194
LINE m_tail
routing "tail": part of the track that has been already fixed due to collisions with obstacles
SHAPE_LINE_CHAIN & Line()
Definition: pns_line.h:136
bool OfKind(int aKindMask) const
Return true if the item's type matches the mask aKindMask.
Definition: pns_item.h:136
void Clear()
Remove all points from the line chain.
const LAYER_RANGE & Layers() const
Definition: pns_item.h:152

References SHAPE_LINE_CHAIN::Clear(), PNS::ITEM::Layers(), PNS::LINE::Line(), m_chainedPlacement, m_currentEnd, m_currentLayer, m_head, m_idle, m_last_head, m_startItem, m_tail, Move(), PNS::ITEM::OfKind(), LAYER_RANGE::Overlaps(), PNS::LINE::RemoveVia(), PNS::ITEM::SetLayer(), PNS::ITEM::SOLID_T, and PNS::ITEM::VIA_T.

◆ SetLogger()

void PNS::ALGO_BASE::SetLogger ( LOGGER aLogger)
inlineinherited

Definition at line 65 of file pns_algo_base.h.

66  {
67  m_logger = aLogger;
68  }
LOGGER * m_logger
Definition: pns_algo_base.h:88

References PNS::ALGO_BASE::m_logger.

Referenced by rhShoveOnly(), rhWalkOnly(), and PNS::DRAGGER::tryWalkaround().

◆ SetOrthoMode()

void PNS::LINE_PLACER::SetOrthoMode ( bool  aOrthoMode)
overridevirtual

Function SetOrthoMode()

Forces the router to place a straight 90/45 degree trace (with the end as near to the cursor as possible) instead of a standard 135 degree two-segment bend.

Reimplemented from PNS::PLACEMENT_ALGO.

Definition at line 1645 of file pns_line_placer.cpp.

1646 {
1647  m_orthoMode = aOrthoMode;
1648 }

References m_orthoMode.

◆ Settings()

◆ setWorld()

void PNS::LINE_PLACER::setWorld ( NODE aWorld)
private

Set the board to route.

Definition at line 66 of file pns_line_placer.cpp.

67 {
68  m_world = aWorld;
69 }
NODE * m_world
pointer to world to search colliding items

References m_world.

Referenced by initPlacement().

◆ simplifyNewLine()

void PNS::LINE_PLACER::simplifyNewLine ( NODE aNode,
LINKED_ITEM aLatest 
)
private

Assemble a line starting from segment or arc aLatest, removes collinear segments and redundant vertices.

If a simplification has been found, replaces the old line with the simplified one in aNode.

Definition at line 1531 of file pns_line_placer.cpp.

1532 {
1533  wxASSERT( aLatest->OfKind( ITEM::SEGMENT_T | ITEM::ARC_T ) );
1534 
1535  // Before we assemble the final line and run the optimizer, do a separate pass to clean up
1536  // colinear segments that exist on non-line-corner joints, as these will prevent proper assembly
1537  // of the line and won't get cleaned up by the optimizer.
1538  NODE::ITEM_VECTOR removed, added;
1539  aNode->GetUpdatedItems( removed, added );
1540 
1541  std::set<ITEM*> cleanup;
1542 
1543  auto processJoint =
1544  [&]( JOINT* aJoint, ITEM* aItem )
1545  {
1546  if( !aJoint || aJoint->IsLineCorner() )
1547  return;
1548 
1549  SEG refSeg = static_cast<SEGMENT*>( aItem )->Seg();
1550 
1551  NODE::ITEM_VECTOR toRemove;
1552 
1553  for( ITEM* neighbor : aJoint->Links() )
1554  {
1555  if( neighbor == aItem || !neighbor->LayersOverlap( aItem ) )
1556  continue;
1557 
1558  const SEG& testSeg = static_cast<SEGMENT*>( neighbor )->Seg();
1559 
1560  if( refSeg.Contains( testSeg ) )
1561  {
1562  JOINT* nA = aNode->FindJoint( neighbor->Anchor( 0 ), neighbor );
1563  JOINT* nB = aNode->FindJoint( neighbor->Anchor( 1 ), neighbor );
1564 
1565  if( ( nA == aJoint && nB->LinkCount() == 1 ) ||
1566  ( nB == aJoint && nA->LinkCount() == 1 ) )
1567  {
1568  cleanup.insert( neighbor );
1569  }
1570  }
1571  }
1572  };
1573 
1574  for( ITEM* item : added )
1575  {
1576  if( !item->OfKind( ITEM::SEGMENT_T ) || cleanup.count( item ) )
1577  continue;
1578 
1579  JOINT* jA = aNode->FindJoint( item->Anchor( 0 ), item );
1580  JOINT* jB = aNode->FindJoint( item->Anchor( 1 ), item );
1581 
1582  processJoint( jA, item );
1583  processJoint( jB, item );
1584  }
1585 
1586  for( ITEM* seg : cleanup )
1587  aNode->Remove( seg );
1588 
1589  // And now we can proceed with assembling the final line and optimizing it.
1590 
1591  LINE l = aNode->AssembleLine( aLatest );
1592 
1593  bool optimized = OPTIMIZER::Optimize( &l, OPTIMIZER::MERGE_COLINEAR, aNode );
1594 
1595  SHAPE_LINE_CHAIN simplified( l.CLine() );
1596 
1597  simplified.Simplify();
1598 
1599  if( optimized || simplified.PointCount() != l.PointCount() )
1600  {
1601  aNode->Remove( l );
1602  l.SetShape( simplified );
1603  aNode->Add( l );
1604  }
1605 }
SHAPE_LINE_CHAIN & Simplify(bool aRemoveColinear=true)
Simplify the line chain by removing colinear adjacent segments and duplicate vertices.
static bool Optimize(LINE *aLine, int aEffortLevel, NODE *aWorld, const VECTOR2I &aV=VECTOR2I(0, 0))
void Remove(int aStartIndex, int aEndIndex)
Remove the range of points [start_index, end_index] from the line chain.
Definition: seg.h:40
Represent a polyline (an zero-thickness chain of connected line segments).
Merge co-linear segments.
std::vector< ITEM * > ITEM_VECTOR
Definition: pns_node.h:148
bool Contains(const SEG &aSeg) const
Definition: seg.h:331

References PNS::NODE::Add(), PNS::ITEM::ARC_T, PNS::NODE::AssembleLine(), PNS::LINE::CLine(), SEG::Contains(), PNS::NODE::FindJoint(), PNS::NODE::GetUpdatedItems(), PNS::JOINT::IsLineCorner(), PNS::JOINT::LinkCount(), PNS::JOINT::Links(), PNS::OPTIMIZER::MERGE_COLINEAR, PNS::ITEM::OfKind(), PNS::OPTIMIZER::Optimize(), PNS::LINE::PointCount(), PNS::NODE::Remove(), PNS::ITEM::SEGMENT_T, PNS::LINE::SetShape(), and SHAPE_LINE_CHAIN::Simplify().

Referenced by FixRoute().

◆ SplitAdjacentSegments()

bool PNS::LINE_PLACER::SplitAdjacentSegments ( NODE aNode,
ITEM aSeg,
const VECTOR2I aP 
)

Check if point aP lies on segment aSeg.

If so, splits the segment in two, forming a joint at aP and stores updated topology in node aNode.

Definition at line 1038 of file pns_line_placer.cpp.

1039 {
1040  if( !aSeg )
1041  return false;
1042 
1043  if( !aSeg->OfKind( ITEM::SEGMENT_T ) )
1044  return false;
1045 
1046  JOINT* jt = aNode->FindJoint( aP, aSeg );
1047 
1048  if( jt && jt->LinkCount() >= 1 )
1049  return false;
1050 
1051  SEGMENT* s_old = static_cast<SEGMENT*>( aSeg );
1052 
1053  std::unique_ptr<SEGMENT> s_new[2] = { Clone( *s_old ), Clone( *s_old ) };
1054 
1055  s_new[0]->SetEnds( s_old->Seg().A, aP );
1056  s_new[1]->SetEnds( aP, s_old->Seg().B );
1057 
1058  aNode->Remove( s_old );
1059  aNode->Add( std::move( s_new[0] ), true );
1060  aNode->Add( std::move( s_new[1] ), true );
1061 
1062  return true;
1063 }
std::unique_ptr< typename std::remove_const< T >::type > Clone(const T &aItem)
Definition: pns_item.h:265

References SEG::A, PNS::NODE::Add(), SEG::B, PNS::Clone(), PNS::NODE::FindJoint(), PNS::JOINT::LinkCount(), PNS::ITEM::OfKind(), PNS::NODE::Remove(), PNS::SEGMENT::Seg(), and PNS::ITEM::SEGMENT_T.

Referenced by PNS::ROUTER::BreakSegment(), initPlacement(), and Move().

◆ Start()

bool PNS::LINE_PLACER::Start ( const VECTOR2I aP,
ITEM aStartItem 
)
overridevirtual

Start routing a single track at point aP, taking item aStartItem as anchor (unless NULL).

Implements PNS::PLACEMENT_ALGO.

Definition at line 1098 of file pns_line_placer.cpp.

1099 {
1100  m_placementCorrect = false;
1101  m_currentStart = VECTOR2I( aP );
1102  m_currentEnd = VECTOR2I( aP );
1103  m_currentNet = std::max( 0, aStartItem ? aStartItem->Net() : 0 );
1104  m_startItem = aStartItem;
1105  m_placingVia = false;
1106  m_chainedPlacement = false;
1107  m_fixedTail.Clear();
1108 
1109  setInitialDirection( Settings().InitialDirection() );
1110 
1111  initPlacement();
1112 
1113  DIRECTION_45 initialDir = m_initial_direction;
1115 
1116  if( aStartItem && aStartItem->Kind() == ITEM::SEGMENT_T )
1117  {
1118  // If we land on a segment endpoint, assume the starting direction is continuing along
1119  // the same direction as the endpoint. If we started in the middle, don't set a
1120  // direction so that the posture solver is not biased.
1121  SEG seg = static_cast<SEGMENT*>( aStartItem )->Seg();
1122 
1123  if( aP == seg.A )
1124  lastSegDir = DIRECTION_45( seg.Reversed() );
1125  else if( aP == seg.B )
1126  lastSegDir = DIRECTION_45( seg );
1127  }
1128  else if( aStartItem && aStartItem->Kind() == ITEM::SOLID_T &&
1129  static_cast<SOLID*>( aStartItem )->Parent()->Type() == PCB_PAD_T )
1130  {
1131  double angle = static_cast<SOLID*>( aStartItem )->GetOrientation() / 10.0;
1132  angle = ( angle + 22.5 ) / 45.0;
1133  initialDir = DIRECTION_45( static_cast<DIRECTION_45::Directions>( int( angle ) ) );
1134  }
1135 
1136  wxLogTrace( "PNS", "Posture: init %s, last seg %s", initialDir.Format(), lastSegDir.Format() );
1137 
1142  m_mouseTrailTracer.SetMouseDisabled( !Settings().GetAutoPosture() );
1143 
1144  NODE *n;
1145 
1146  if ( Settings().Mode() == PNS::RM_Shove || Settings().Mode() == PNS::RM_Smart )
1147  n = m_shove->CurrentNode();
1148  else
1149  n = m_currentNode;
1150 
1152 
1153  return true;
1154 }
const std::string Format() const
Format the direction in a human readable word.
Definition: direction45.h:117
LINE m_head
the volatile part of the track from the previously analyzed point to the current routing destination
class PAD, a pad in a footprint
Definition: typeinfo.h:89
VECTOR2< int > VECTOR2I
Definition: vector2d.h:623
ROUTING_SETTINGS & Settings() const
Return the logger object, allowing to dump geometry to a file.
DIRECTION_45 m_initial_direction
routing direction for new traces
void setInitialDirection(const DIRECTION_45 &aDirection)
Set preferred direction of the very first track segment to be laid.
Represent route directions & corner angles in a 45-degree metric.
Definition: direction45.h:36
std::unique_ptr< SHOVE > m_shove
The shove engine.
DIRECTION_45 m_direction
current routing direction
void initPlacement()
Initialize placement of a new line with given parameters.
void AddTrailPoint(const VECTOR2I &aP)
MOUSE_TRAIL_TRACER m_mouseTrailTracer
FIXED_TAIL m_fixedTail
void AddStage(const VECTOR2I &aStart, int aLayer, bool placingVias, DIRECTION_45 direction, NODE *aNode)
SEG Reversed() const
Returns the center point of the line.
Definition: seg.h:380
Definition: seg.h:40
Guess what's better, try to make least mess on the PCB.
NODE * m_currentNode
Current world state.
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
void SetDefaultDirections(DIRECTION_45 aInitDirection, DIRECTION_45 aLastSegDir)
VECTOR2I A
Definition: seg.h:48
int Width() const
Return true if the line is geometrically identical as line aOther.
Definition: pns_line.h:156
void SetMouseDisabled(bool aDisabled=true)
Disables the mouse-trail portion of the posture solver; leaving only the manual posture switch and th...
VECTOR2I B
Definition: seg.h:49

References SEG::A, PNS::FIXED_TAIL::AddStage(), PNS::MOUSE_TRAIL_TRACER::AddTrailPoint(), PNS::angle(), SEG::B, PNS::MOUSE_TRAIL_TRACER::Clear(), PNS::FIXED_TAIL::Clear(), DIRECTION_45::Format(), initPlacement(), PNS::ITEM::Kind(), m_chainedPlacement, m_currentEnd, m_currentLayer, m_currentNet, m_currentNode, m_currentStart, m_direction, m_fixedTail, m_head, m_initial_direction, m_mouseTrailTracer, m_placementCorrect, m_placingVia, m_shove, m_startItem, PNS::ITEM::Net(), PCB_PAD_T, SEG::Reversed(), PNS::RM_Shove, PNS::RM_Smart, PNS::ITEM::SEGMENT_T, PNS::MOUSE_TRAIL_TRACER::SetDefaultDirections(), setInitialDirection(), PNS::MOUSE_TRAIL_TRACER::SetMouseDisabled(), PNS::ALGO_BASE::Settings(), PNS::MOUSE_TRAIL_TRACER::SetTolerance(), PNS::ITEM::SOLID_T, DIRECTION_45::UNDEFINED, and PNS::LINE::Width().

◆ Tail()

const LINE& PNS::LINE_PLACER::Tail ( ) const
inline

Return the "tail" of the line being placed, the part which has already wrapped around and shoved some obstacles.

Definition at line 139 of file pns_line_placer.h.

139 { return m_tail; }
LINE m_tail
routing "tail": part of the track that has been already fixed due to collisions with obstacles

References m_tail.

◆ ToggleVia()

bool PNS::LINE_PLACER::ToggleVia ( bool  aEnabled)
overridevirtual

Enable/disable a via at the end of currently routed trace.

Reimplemented from PNS::PLACEMENT_ALGO.

Definition at line 81 of file pns_line_placer.cpp.

82 {
83  m_placingVia = aEnabled;
84 
85  if( !aEnabled )
86  m_head.RemoveVia();
87 
88  return true;
89 }
LINE m_head
the volatile part of the track from the previously analyzed point to the current routing destination
void RemoveVia()
Definition: pns_line.h:194

References m_head, m_placingVia, and PNS::LINE::RemoveVia().

◆ Trace()

const LINE PNS::LINE_PLACER::Trace ( ) const

Return the complete routed line.

Definition at line 1005 of file pns_line_placer.cpp.

1006 {
1007  LINE tmp( m_head );
1008 
1009  tmp.SetShape( m_tail.CLine() );
1010  tmp.Line().Append( m_head.CLine() );
1011  tmp.Line().Simplify();
1012  return tmp;
1013 }
const SHAPE_LINE_CHAIN & CLine() const
Definition: pns_line.h:137
LINE m_head
the volatile part of the track from the previously analyzed point to the current routing destination
LINE m_tail
routing "tail": part of the track that has been already fixed due to collisions with obstacles

References SHAPE_LINE_CHAIN::Append(), PNS::LINE::CLine(), PNS::LINE::Line(), m_head, m_tail, PNS::LINE::SetShape(), and SHAPE_LINE_CHAIN::Simplify().

Referenced by FixRoute(), Move(), optimizeTailHeadTransition(), Traces(), and updateLeadingRatLine().

◆ Traces()

const ITEM_SET PNS::LINE_PLACER::Traces ( )
overridevirtual

Return the complete routed line, as a single-member ITEM_SET.

Implements PNS::PLACEMENT_ALGO.

Definition at line 1016 of file pns_line_placer.cpp.

1017 {
1018  m_currentTrace = Trace();
1019  return ITEM_SET( &m_currentTrace );
1020 }
const LINE Trace() const
Return the complete routed line.

References m_currentTrace, and Trace().

◆ UnfixRoute()

bool PNS::LINE_PLACER::UnfixRoute ( )
overridevirtual

Reimplemented from PNS::PLACEMENT_ALGO.

Definition at line 1424 of file pns_line_placer.cpp.

1425 {
1426  FIXED_TAIL::STAGE st;
1427 
1428  if ( !m_fixedTail.PopStage( st ) )
1429  return false;
1430 
1431  m_head.Line().Clear();
1432  m_tail.Line().Clear();
1433  m_startItem = nullptr;
1434  m_p_start = st.pts[0].p;
1435  m_direction = st.pts[0].direction;
1436  m_placingVia = st.pts[0].placingVias;
1437  m_currentNode = st.commit;
1438  m_currentLayer = st.pts[0].layer;
1441  m_head.RemoveVia();
1442  m_tail.RemoveVia();
1443 
1447 
1448  m_shove->RewindSpringbackTo( m_currentNode );
1449  m_shove->UnlockSpringbackNode( m_currentNode );
1450 
1451  if( Settings().Mode() == PNS::RM_Shove || Settings().Mode() == PNS::RM_Smart )
1452  {
1453  m_currentNode = m_shove->CurrentNode();
1455  }
1456 
1458 
1459  return true;
1460 }
NODE * m_lastNode
Postprocessed world state (including marked collisions & removed loops)
void SetLayer(int aLayer)
Definition: pns_item.h:155
LINE m_head
the volatile part of the track from the previously analyzed point to the current routing destination
void RemoveVia()
Definition: pns_line.h:194
bool PopStage(STAGE &aStage)
NODE * Branch()
Create a lightweight copy (called branch) of self that tracks the changes (added/removed items) wrs t...
Definition: pns_node.cpp:137
ROUTING_SETTINGS & Settings() const
Return the logger object, allowing to dump geometry to a file.
DIRECTION_45 m_initial_direction
routing direction for new traces
void KillChildren()
Definition: pns_node.cpp:1405
LINE m_tail
routing "tail": part of the track that has been already fixed due to collisions with obstacles
std::unique_ptr< SHOVE > m_shove
The shove engine.
DIRECTION_45 m_direction
current routing direction
void AddTrailPoint(const VECTOR2I &aP)
MOUSE_TRAIL_TRACER m_mouseTrailTracer
FIXED_TAIL m_fixedTail
SHAPE_LINE_CHAIN & Line()
Definition: pns_line.h:136
Guess what's better, try to make least mess on the PCB.
NODE * m_currentNode
Current world state.
void SetDefaultDirections(DIRECTION_45 aInitDirection, DIRECTION_45 aLastSegDir)
void Clear()
Remove all points from the line chain.
VECTOR2I m_p_start
current routing start (end of tail, beginning of head)

References PNS::MOUSE_TRAIL_TRACER::AddTrailPoint(), PNS::NODE::Branch(), PNS::MOUSE_TRAIL_TRACER::Clear(), SHAPE_LINE_CHAIN::Clear(), PNS::FIXED_TAIL::STAGE::commit, PNS::NODE::KillChildren(), PNS::LINE::Line(), m_currentLayer, m_currentNode, m_direction, m_fixedTail, m_head, m_initial_direction, m_lastNode, m_mouseTrailTracer, m_p_start, m_placingVia, m_shove, m_startItem, m_tail, PNS::FIXED_TAIL::PopStage(), PNS::FIXED_TAIL::STAGE::pts, PNS::LINE::RemoveVia(), PNS::RM_Shove, PNS::RM_Smart, PNS::MOUSE_TRAIL_TRACER::SetDefaultDirections(), PNS::ITEM::SetLayer(), and PNS::ALGO_BASE::Settings().

◆ updateLeadingRatLine()

void PNS::LINE_PLACER::updateLeadingRatLine ( )
private

Draw the "leading" rats nest line, which connects the end of currently routed track and the nearest yet unrouted item.

If the routing for current net is complete, draws nothing.

Definition at line 1634 of file pns_line_placer.cpp.

1635 {
1636  LINE current = Trace();
1637  SHAPE_LINE_CHAIN ratLine;
1638  TOPOLOGY topo( m_lastNode );
1639 
1640  if( topo.LeadingRatLine( &current, ratLine ) )
1641  m_router->GetInterface()->DisplayRatline( ratLine, 5 );
1642 }
NODE * m_lastNode
Postprocessed world state (including marked collisions & removed loops)
const LINE Trace() const
Return the complete routed line.
virtual void DisplayRatline(const SHAPE_LINE_CHAIN &aRatline, int aColor=-1)=0
ROUTER * m_router
Definition: pns_algo_base.h:87
Represent a polyline (an zero-thickness chain of connected line segments).
ROUTER_IFACE * GetInterface() const
Definition: pns_router.h:207

References PNS::ROUTER_IFACE::DisplayRatline(), PNS::ROUTER::GetInterface(), PNS::TOPOLOGY::LeadingRatLine(), m_lastNode, PNS::ALGO_BASE::m_router, and Trace().

Referenced by Move().

◆ UpdateSizes()

void PNS::LINE_PLACER::UpdateSizes ( const SIZES_SETTINGS aSizes)
overridevirtual

Perform on-the-fly update of the width, via diameter & drill size from a settings class.

Performs on-the-fly update of the width, via diameter & drill size from a settings class. Used to dynamically change these parameters as the track is routed.

Reimplemented from PNS::PLACEMENT_ALGO.

Definition at line 1608 of file pns_line_placer.cpp.

1609 {
1610  m_sizes = aSizes;
1611 
1612  if( !m_idle )
1613  {
1614  // If the track width continues from an existing track, we don't want to change the width.
1615  // Disallow changing width after the first segment has been fixed because we don't want to
1616  // go back and rip up tracks or allow DRC errors
1618  && ( !m_startItem || m_startItem->Kind() != ITEM::SEGMENT_T ) ) )
1619  {
1623  }
1624 
1625  if( m_head.EndsWithVia() )
1626  {
1629  }
1630  }
1631 }
void SetViaDiameter(int aDiameter)
Definition: pns_line.h:198
LINE m_head
the volatile part of the track from the previously analyzed point to the current routing destination
SIZES_SETTINGS m_sizes
bool EndsWithVia() const
Definition: pns_line.h:191
void SetWidth(int aWidth)
Return line width.
Definition: pns_line.h:149
LINE m_tail
routing "tail": part of the track that has been already fixed due to collisions with obstacles
bool TrackWidthIsExplicit() const
bool HasPlacedAnything() const override
void SetViaDrill(int aDrill)
Definition: pns_line.h:199
PnsKind Kind() const
Return the type (kind) of the item.
Definition: pns_item.h:128

References PNS::LINE::EndsWithVia(), HasPlacedAnything(), PNS::ITEM::Kind(), m_currentTrace, m_head, m_idle, m_sizes, m_startItem, m_tail, PNS::ITEM::SEGMENT_T, PNS::LINE::SetViaDiameter(), PNS::LINE::SetViaDrill(), PNS::LINE::SetWidth(), PNS::SIZES_SETTINGS::TrackWidth(), PNS::SIZES_SETTINGS::TrackWidthIsExplicit(), PNS::SIZES_SETTINGS::ViaDiameter(), and PNS::SIZES_SETTINGS::ViaDrill().

◆ VisibleViewArea()

const BOX2I & PNS::ALGO_BASE::VisibleViewArea ( ) const
inherited

Definition at line 40 of file pns_algo_base.cpp.

41 {
42  return m_router->VisibleViewArea();
43 }
ROUTER * m_router
Definition: pns_algo_base.h:87
const BOX2I & VisibleViewArea() const
Definition: pns_router.h:210

References PNS::ALGO_BASE::m_router, and PNS::ROUTER::VisibleViewArea().

Referenced by PNS::DRAGGER::optimizeAndUpdateDraggedLine(), and PNS::SHOVE::runOptimizer().

Member Data Documentation

◆ m_chainedPlacement

bool PNS::LINE_PLACER::m_chainedPlacement
private

Definition at line 358 of file pns_line_placer.h.

Referenced by FixRoute(), LINE_PLACER(), SetLayer(), and Start().

◆ m_currentEnd

VECTOR2I PNS::LINE_PLACER::m_currentEnd
private

Definition at line 351 of file pns_line_placer.h.

Referenced by CurrentEnd(), Move(), SetLayer(), and Start().

◆ m_currentLayer

int PNS::LINE_PLACER::m_currentLayer
private

◆ m_currentNet

int PNS::LINE_PLACER::m_currentNet
private

◆ m_currentNode

◆ m_currentStart

VECTOR2I PNS::LINE_PLACER::m_currentStart
private

Definition at line 352 of file pns_line_placer.h.

Referenced by FixRoute(), initPlacement(), and Start().

◆ m_currentTrace

LINE PNS::LINE_PLACER::m_currentTrace
private

Definition at line 353 of file pns_line_placer.h.

Referenced by Traces(), and UpdateSizes().

◆ m_debugDecorator

DEBUG_DECORATOR* PNS::ALGO_BASE::m_debugDecorator
protectedinherited

Definition at line 86 of file pns_algo_base.h.

Referenced by PNS::ALGO_BASE::Dbg(), and PNS::ALGO_BASE::SetDebugDecorator().

◆ m_direction

◆ m_fixedTail

FIXED_TAIL PNS::LINE_PLACER::m_fixedTail
private

Definition at line 362 of file pns_line_placer.h.

Referenced by FixRoute(), HasPlacedAnything(), Start(), and UnfixRoute().

◆ m_head

LINE PNS::LINE_PLACER::m_head
private

the volatile part of the track from the previously analyzed point to the current routing destination

Definition at line 327 of file pns_line_placer.h.

Referenced by FixRoute(), handlePullback(), handleSelfIntersections(), Head(), initPlacement(), mergeHead(), optimizeTailHeadTransition(), reduceTail(), rhMarkObstacles(), rhShoveOnly(), rhWalkOnly(), route(), routeStep(), SetLayer(), Start(), ToggleVia(), Trace(), UnfixRoute(), and UpdateSizes().

◆ m_idle

bool PNS::LINE_PLACER::m_idle
private

Definition at line 357 of file pns_line_placer.h.

Referenced by FixRoute(), initPlacement(), LINE_PLACER(), SetLayer(), and UpdateSizes().

◆ m_initial_direction

DIRECTION_45 PNS::LINE_PLACER::m_initial_direction
private

◆ m_last_head

LINE PNS::LINE_PLACER::m_last_head
private

Most recent successful (non-colliding) head.

Definition at line 330 of file pns_line_placer.h.

Referenced by routeStep(), and SetLayer().

◆ m_lastNode

NODE* PNS::LINE_PLACER::m_lastNode
private

Postprocessed world state (including marked collisions & removed loops)

Definition at line 341 of file pns_line_placer.h.

Referenced by CommitPlacement(), CurrentNode(), FixRoute(), initPlacement(), LINE_PLACER(), Move(), UnfixRoute(), and updateLeadingRatLine().

◆ m_logger

LOGGER* PNS::ALGO_BASE::m_logger
protectedinherited

Definition at line 88 of file pns_algo_base.h.

Referenced by PNS::ALGO_BASE::SetLogger().

◆ m_mouseTrailTracer

MOUSE_TRAIL_TRACER PNS::LINE_PLACER::m_mouseTrailTracer
private

◆ m_orthoMode

bool PNS::LINE_PLACER::m_orthoMode
private

Definition at line 359 of file pns_line_placer.h.

Referenced by buildInitialLine(), LINE_PLACER(), and SetOrthoMode().

◆ m_p_start

VECTOR2I PNS::LINE_PLACER::m_p_start
private

current routing start (end of tail, beginning of head)

Definition at line 336 of file pns_line_placer.h.

Referenced by buildInitialLine(), FixRoute(), handlePullback(), handleSelfIntersections(), initPlacement(), mergeHead(), Move(), optimizeTailHeadTransition(), reduceTail(), and UnfixRoute().

◆ m_placementCorrect

bool PNS::LINE_PLACER::m_placementCorrect
private

Definition at line 360 of file pns_line_placer.h.

Referenced by FixRoute(), HasPlacedAnything(), LINE_PLACER(), and Start().

◆ m_placingVia

bool PNS::LINE_PLACER::m_placingVia
private

◆ m_router

◆ m_shove

std::unique_ptr<SHOVE> PNS::LINE_PLACER::m_shove
private

The shove engine.

Definition at line 338 of file pns_line_placer.h.

Referenced by FixRoute(), initPlacement(), LINE_PLACER(), rhShoveOnly(), Start(), and UnfixRoute().

◆ m_sizes

SIZES_SETTINGS PNS::LINE_PLACER::m_sizes
private

Definition at line 344 of file pns_line_placer.h.

Referenced by initPlacement(), makeVia(), and UpdateSizes().

◆ m_startItem

ITEM* PNS::LINE_PLACER::m_startItem
private

◆ m_tail

LINE PNS::LINE_PLACER::m_tail
private

routing "tail": part of the track that has been already fixed due to collisions with obstacles

Definition at line 332 of file pns_line_placer.h.

Referenced by buildInitialLine(), FixRoute(), handlePullback(), handleSelfIntersections(), initPlacement(), mergeHead(), optimizeTailHeadTransition(), reduceTail(), rhShoveOnly(), routeStep(), setInitialDirection(), SetLayer(), Tail(), Trace(), UnfixRoute(), and UpdateSizes().

◆ m_world

NODE* PNS::LINE_PLACER::m_world
private

pointer to world to search colliding items

Definition at line 335 of file pns_line_placer.h.

Referenced by AbortPlacement(), FixRoute(), initPlacement(), LINE_PLACER(), and setWorld().


The documentation for this class was generated from the following files: