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 vertexes. 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)
 

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_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
 
PNS_MODE m_currentMode
 
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 38 of file pns_line_placer.cpp.

38  :
39  PLACEMENT_ALGO( aRouter )
40 {
42  m_world = nullptr;
43  m_shove = nullptr;
44  m_currentNode = nullptr;
45  m_idle = true;
46 
47  // Init temporary variables (do not leave uninitialized members)
48  m_lastNode = nullptr;
49  m_placingVia = false;
50  m_currentNet = 0;
51  m_currentLayer = 0;
53  m_startItem = nullptr;
54  m_chainedPlacement = false;
55  m_orthoMode = false;
56  m_placementCorrect = false;
57 }
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.
Ignore collisions, mark obstacles.
PLACEMENT_ALGO(ROUTER *aRouter)

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

◆ ~LINE_PLACER()

PNS::LINE_PLACER::~LINE_PLACER ( )

Definition at line 60 of file pns_line_placer.cpp.

61 {
62 }

Member Function Documentation

◆ AbortPlacement()

bool PNS::LINE_PLACER::AbortPlacement ( )
overridevirtual

Reimplemented from PNS::PLACEMENT_ALGO.

Definition at line 1440 of file pns_line_placer.cpp.

1441 {
1442  m_world->KillChildren();
1443  return true;
1444 }
NODE * m_world
pointer to world to search colliding items
void KillChildren()
Definition: pns_node.cpp:1292

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

◆ buildInitialLine()

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

Definition at line 1362 of file pns_line_placer.cpp.

1363 {
1364  SHAPE_LINE_CHAIN l;
1365  DIRECTION_45 guessedDir = m_mouseTrailTracer.GetPosture( aP );
1366 
1367  wxLogTrace( "PNS", "buildInitialLine: m_direction %s, guessedDir %s, tail points %d",
1368  m_direction.Format(), guessedDir.Format(), m_tail.PointCount() );
1369 
1370  // Rounded corners don't make sense when routing orthogonally (single track at a time)
1371  bool fillet = !m_orthoMode && Settings().GetCornerMode() == CORNER_MODE::ROUNDED_45;
1372 
1373  if( m_p_start == aP )
1374  {
1375  l.Clear();
1376  }
1377  else
1378  {
1379  if( Settings().GetFreeAngleMode() && Settings().Mode() == RM_MarkObstacles )
1380  {
1381  l = SHAPE_LINE_CHAIN( { m_p_start, aP } );
1382  }
1383  else
1384  {
1385  if( !m_tail.PointCount() )
1386  l = guessedDir.BuildInitialTrace( m_p_start, aP, false, fillet );
1387  else
1388  l = m_direction.BuildInitialTrace( m_p_start, aP, false, fillet );
1389  }
1390 
1391  if( l.SegmentCount() > 1 && m_orthoMode )
1392  {
1393  VECTOR2I newLast = l.CSegment( 0 ).LineProject( l.CPoint( -1 ) );
1394 
1395  l.Remove( -1, -1 );
1396  l.SetPoint( 1, newLast );
1397  }
1398  }
1399 
1400  aHead.SetLayer( m_currentLayer );
1401  aHead.SetShape( l );
1402 
1403  if( !m_placingVia )
1404  return true;
1405 
1406  VIA v( makeVia( aP ) );
1407  v.SetNet( aHead.Net() );
1408 
1410  {
1411  aHead.AppendVia( v );
1412  return true;
1413  }
1414 
1415  VECTOR2I force;
1416  VECTOR2I lead = aP - m_p_start;
1417 
1418  bool solidsOnly = ( m_currentMode != RM_Walkaround );
1419 
1420  if( v.PushoutForce( m_currentNode, lead, force, solidsOnly, 40 ) )
1421  {
1422  SHAPE_LINE_CHAIN line = guessedDir.BuildInitialTrace( m_p_start, aP + force, false,
1423  fillet );
1424  aHead = LINE( aHead, line );
1425 
1426  v.SetPos( v.Pos() + force );
1427  return true;
1428  }
1429 
1430  return false; // via placement unsuccessful
1431 }
Definition: track.h:343
void SetPoint(int aIndex, const VECTOR2I &aPos)
Accessor Function to 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
Function Point()
VECTOR2I LineProject(const VECTOR2I &aP) const
Compute the perpendicular projection point of aP on a line passing through ends of the segment.
Definition: seg.h:389
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.
MOUSE_TRAIL_TRACER m_mouseTrailTracer
void Remove(int aStartIndex, int aEndIndex)
Function Remove()
int SegmentCount() const
Function SegmentCount()
NODE * m_currentNode
Current world state.
Ignore collisions, mark obstacles.
CORNER_MODE GetCornerMode() const
const SEG CSegment(int aIndex) const
Function CSegment()
SHAPE_LINE_CHAIN.
Only walk around.
DIRECTION_45 GetPosture(const VECTOR2I &aP)
void Clear()
Function Clear() Removes 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_currentMode, m_currentNode, m_direction, m_mouseTrailTracer, m_orthoMode, m_p_start, m_placingVia, m_tail, makeVia(), 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 1238 of file pns_line_placer.cpp.

1239 {
1240  if( m_lastNode )
1242 
1243  m_lastNode = nullptr;
1244  m_currentNode = nullptr;
1245  return true;
1246 }
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:655
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 811 of file pns_line_placer.cpp.

812 {
813  if( aLoopsRemoved && m_lastNode )
814  return m_lastNode;
815 
816  return m_currentNode;
817 }
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 1022 of file pns_line_placer.cpp.

1023 {
1024  bool fixAll = Settings().GetFixAllSegments();
1025  bool realEnd = false;
1026 
1027  LINE pl = Trace();
1028 
1030  {
1031  // Mark Obstacles is sort of a half-manual, half-automated mode in which the
1032  // user has more responsibility and authority.
1033 
1034  if( aEndItem )
1035  {
1036  // The user has indicated a connection should be made. If either the trace or
1037  // endItem is net-less, then allow the connection by adopting the net of the other.
1038  if( m_currentNet <= 0 )
1039  {
1040  m_currentNet = aEndItem->Net();
1041  pl.SetNet( m_currentNet );
1042  }
1043  else if (aEndItem->Net() <= 0 )
1044  {
1045  aEndItem->SetNet( m_currentNet );
1046  }
1047  }
1048 
1049  // Collisions still prevent fixing unless "Allow DRC violations" is checked
1050  if( !Settings().CanViolateDRC() && m_world->CheckColliding( &pl ) )
1051  return false;
1052  }
1053 
1054  const SHAPE_LINE_CHAIN& l = pl.CLine();
1055 
1056  if( !l.SegmentCount() )
1057  {
1058  if( m_lastNode )
1059  {
1060  // Do a final optimization to the stored state
1061  NODE::ITEM_VECTOR removed, added;
1062  m_lastNode->GetUpdatedItems( removed, added );
1063 
1064  if( !added.empty() && added.back()->Kind() == ITEM::SEGMENT_T )
1065  simplifyNewLine( m_lastNode, static_cast<SEGMENT*>( added.back() ) );
1066  }
1067 
1068  // Nothing to commit if we have an empty line
1069  if( !pl.EndsWithVia() )
1070  return false;
1071 
1074  if( m_lastNode )
1075  m_lastNode->Add( Clone( pl.Via() ) );
1076 
1077  m_currentNode = nullptr;
1078 
1079  m_idle = true;
1080  m_placementCorrect = true;
1081  return true;
1082  }
1083 
1084  VECTOR2I p_pre_last = l.CPoint( -1 );
1085  const VECTOR2I p_last = l.CPoint( -1 );
1086 
1087  if( l.PointCount() > 2 )
1088  p_pre_last = l.CPoint( -2 );
1089 
1090  if( aEndItem && m_currentNet >= 0 && m_currentNet == aEndItem->Net() )
1091  realEnd = true;
1092 
1093  if( aForceFinish )
1094  realEnd = true;
1095 
1096  // TODO: Rollback doesn't work properly if fix-all isn't enabled and we are placing arcs,
1097  // so if we are, act as though we are in fix-all mode.
1098  if( !fixAll && l.ArcCount() )
1099  fixAll = true;
1100 
1101  // TODO: lastDirSeg will be calculated incorrectly if we end on an arc
1102  SEG lastDirSeg = ( !fixAll && l.SegmentCount() > 1 ) ? l.CSegment( -2 ) : l.CSegment( -1 );
1103  DIRECTION_45 d_last( lastDirSeg );
1104 
1105  int lastV;
1106 
1107  if( realEnd || m_placingVia || fixAll )
1108  lastV = l.SegmentCount();
1109  else
1110  lastV = std::max( 1, l.SegmentCount() - 1 );
1111 
1112  ARC arc;
1113  SEGMENT seg;
1114  LINKED_ITEM* lastItem = nullptr;
1115  int lastArc = -1;
1116 
1117  for( int i = 0; i < lastV; i++ )
1118  {
1119  ssize_t arcIndex = l.ArcIndex( i );
1120 
1121  if( arcIndex < 0 || ( lastArc >= 0 && i == lastV - 1 && l.CShapes()[lastV] == -1 ) )
1122  {
1123  seg = SEGMENT( pl.CSegment( i ), m_currentNet );
1124  seg.SetWidth( pl.Width() );
1125  seg.SetLayer( m_currentLayer );
1126 
1127  if( m_lastNode->Add( std::make_unique<SEGMENT>( seg ) ) )
1128  lastItem = &seg;
1129  }
1130  else
1131  {
1132  if( arcIndex == lastArc )
1133  continue;
1134 
1135  arc = ARC( l.Arc( arcIndex ), m_currentNet );
1136  arc.SetWidth( pl.Width() );
1137  arc.SetLayer( m_currentLayer );
1138 
1139  m_lastNode->Add( std::make_unique<ARC>( arc ) );
1140  lastItem = &arc;
1141  lastArc = arcIndex;
1142  }
1143  }
1144 
1145  if( pl.EndsWithVia() )
1146  m_lastNode->Add( Clone( pl.Via() ) );
1147 
1148  if( realEnd && lastItem )
1149  simplifyNewLine( m_lastNode, lastItem );
1150 
1151  if( !realEnd )
1152  {
1153  setInitialDirection( d_last );
1154  m_currentStart = ( m_placingVia || fixAll ) ? p_last : p_pre_last;
1155 
1157 
1158  m_startItem = nullptr;
1159  m_placingVia = false;
1160  m_chainedPlacement = !pl.EndsWithVia();
1161 
1164 
1165  m_head.Line().Clear();
1166  m_tail.Line().Clear();
1167  m_head.RemoveVia();
1168  m_tail.RemoveVia();
1171 
1172  if( m_shove )
1173  m_shove->AddLockedSpringbackNode( m_currentNode );
1174 
1175  DIRECTION_45 lastSegDir = pl.EndsWithVia() ? DIRECTION_45::UNDEFINED : d_last;
1176 
1181 
1182  m_placementCorrect = true;
1183  }
1184  else
1185  {
1186  m_placementCorrect = true;
1187  m_idle = true;
1188  }
1189 
1190  return realEnd;
1191 }
const SHAPE_ARC & Arc(size_t aArc) const
NODE * m_lastNode
Postprocessed world state (including marked collisions & removed loops)
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 vertex...
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
Function PointCount()
NODE * Branch()
Create a lightweight copy (called branch) of self that tracks the changes (added/removed items) wrs t...
Definition: pns_node.cpp:124
void SetWidth(int aWidth)
Definition: track.h:109
const std::vector< ssize_t > & CShapes() const
ssize_t ArcIndex(size_t aSegment) const
ROUTING_SETTINGS & Settings() const
Return the logger object, allowing to dump geometry to a file.
const VECTOR2I & CPoint(int aIndex) const
Function Point()
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
Function SegmentCount()
SHAPE_LINE_CHAIN & Line()
Definition: pns_line.h:136
Definition: seg.h:41
NODE * m_currentNode
Current world state.
Ignore collisions, mark obstacles.
void AddStage(VECTOR2I aStart, int aLayer, bool placingVias, DIRECTION_45 direction, NODE *aNode)
const SEG CSegment(int aIndex) const
Function CSegment()
std::unique_ptr< typename std::remove_const< T >::type > Clone(const T &aItem)
Definition: pns_item.h:257
Definition: track.h:262
SHAPE_LINE_CHAIN.
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:427
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:1225
void Clear()
Function Clear() Removes 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:615
std::vector< ITEM * > ITEM_VECTOR
Definition: pns_node.h:153

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(), SHAPE_LINE_CHAIN::CPoint(), PNS::LINE::CSegment(), SHAPE_LINE_CHAIN::CSegment(), SHAPE_LINE_CHAIN::CShapes(), PNS::LINE::EndsWithVia(), PNS::ROUTING_SETTINGS::GetFixAllSegments(), PNS::NODE::GetUpdatedItems(), PNS::LINE::Line(), m_chainedPlacement, m_currentLayer, m_currentMode, 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, 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 805 of file pns_line_placer.cpp.

806 {
808 }
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 1434 of file pns_line_placer.cpp.

1435 {
1436  aNets.push_back( m_currentNet );
1437 }

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 171 of file pns_line_placer.cpp.

172 {
173  SHAPE_LINE_CHAIN& head = m_head.Line();
174  SHAPE_LINE_CHAIN& tail = m_tail.Line();
175 
176  if( head.PointCount() < 2 )
177  return false;
178 
179  int n = tail.PointCount();
180 
181  if( n == 0 )
182  {
183  return false;
184  }
185  else if( n == 1 )
186  {
187  m_p_start = tail.CPoint( 0 );
188  tail.Clear();
189  return true;
190  }
191 
192  DIRECTION_45 first_head, last_tail;
193 
194  const std::vector<ssize_t>& headShapes = head.CShapes();
195  const std::vector<ssize_t>& tailShapes = tail.CShapes();
196 
197  wxASSERT( tail.PointCount() >= 2 );
198 
199  if( headShapes[0] == -1 )
200  first_head = DIRECTION_45( head.CSegment( 0 ) );
201  else
202  first_head = DIRECTION_45( head.CArcs()[ headShapes[0] ] );
203 
204  int lastSegIdx = tail.PointCount() - 2;
205 
206  if( tailShapes[lastSegIdx] == -1 )
207  last_tail = DIRECTION_45( tail.CSegment( lastSegIdx ) );
208  else
209  last_tail = DIRECTION_45( tail.CArcs()[tailShapes[lastSegIdx]] );
210 
211  DIRECTION_45::AngleType angle = first_head.Angle( last_tail );
212 
213  // case 1: we have a defined routing direction, and the currently computed
214  // head goes in different one.
215  bool pullback_1 = false; // (m_direction != DIRECTION_45::UNDEFINED && m_direction != first_head);
216 
217  // case 2: regardless of the current routing direction, if the tail/head
218  // extremities form an acute or right angle, reduce the tail by one segment
219  // (and hope that further iterations) will result with a cleaner trace
220  bool pullback_2 = ( angle == DIRECTION_45::ANG_RIGHT || angle == DIRECTION_45::ANG_ACUTE );
221 
222  if( pullback_1 || pullback_2 )
223  {
224  lastSegIdx = tail.PrevShape( -1 );
225 
226  if( tailShapes[lastSegIdx] == -1 )
227  {
228  const SEG& seg = tail.CSegment( lastSegIdx );
229  m_direction = DIRECTION_45( seg );
230  m_p_start = seg.A;
231  }
232  else
233  {
234  const SHAPE_ARC& arc = tail.CArcs()[tailShapes[lastSegIdx]];
235  m_direction = DIRECTION_45( arc );
236  m_p_start = arc.GetP0();
237  }
238 
239  wxLogTrace( "PNS", "Placer: pullback triggered [%d] [%s %s]",
240  n, last_tail.Format().c_str(), first_head.Format().c_str() );
241 
242  // erase the last point in the tail, hoping that the next iteration will
243  // result with a head trace that starts with a segment following our
244  // current direction.
245  if( n < 2 )
246  tail.Clear(); // don't leave a single-point tail
247  else
248  tail.RemoveShape( -1 );
249 
250  if( !tail.SegmentCount() )
252 
253  return true;
254  }
255 
256  return false;
257 }
int PrevShape(int aPointIndex) const
void RemoveShape(int aPointIndex)
Removes 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
Function PointCount()
const std::vector< ssize_t > & CShapes() const
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
Function Point()
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:95
int SegmentCount() const
Function SegmentCount()
SHAPE_LINE_CHAIN & Line()
Definition: pns_line.h:136
Definition: seg.h:41
AngleType
Represent kind of angle formed by vectors heading in two DIRECTION_45s.
Definition: direction45.h:65
const SEG CSegment(int aIndex) const
Function CSegment()
SHAPE_LINE_CHAIN.
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
VECTOR2I A
Definition: seg.h:49
void Clear()
Function Clear() Removes 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::CArcs(), SHAPE_LINE_CHAIN::Clear(), SHAPE_LINE_CHAIN::CPoint(), SHAPE_LINE_CHAIN::CSegment(), SHAPE_LINE_CHAIN::CShapes(), DIRECTION_45::Format(), SHAPE_ARC::GetP0(), 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 99 of file pns_line_placer.cpp.

100 {
102  SHAPE_LINE_CHAIN& head = m_head.Line();
103  SHAPE_LINE_CHAIN& tail = m_tail.Line();
104 
105  // if there is no tail, there is nothing to intersect with
106  if( tail.PointCount() < 2 )
107  return false;
108 
109  if( head.PointCount() < 2 )
110  return false;
111 
112  // completely new head trace? chop off the tail
113  if( tail.CPoint(0) == head.CPoint(0) )
114  {
115  m_p_start = tail.CPoint( 0 );
117  tail.Clear();
118  return true;
119  }
120 
121  tail.Intersect( head, ips );
122 
123  // no intesection points - nothing to reduce
124  if( ips.empty() )
125  return false;
126 
127  int n = INT_MAX;
128  VECTOR2I ipoint;
129 
130  // if there is more than one intersection, find the one that is
131  // closest to the beginning of the tail.
132  for( const SHAPE_LINE_CHAIN::INTERSECTION& i : ips )
133  {
134  if( i.our.Index() < n )
135  {
136  n = i.our.Index();
137  ipoint = i.p;
138  }
139  }
140 
141  // ignore the point where head and tail meet
142  if( ipoint == head.CPoint( 0 ) || ipoint == tail.CPoint( -1 ) )
143  return false;
144 
145  // Intersection point is on the first or the second segment: just start routing
146  // from the beginning
147  if( n < 2 )
148  {
149  m_p_start = tail.CPoint( 0 );
151  tail.Clear();
152  head.Clear();
153 
154  return true;
155  }
156  else
157  {
158  // Clip till the last tail segment before intersection.
159  // Set the direction to the one of this segment.
160  const SEG last = tail.CSegment( n - 1 );
161  m_p_start = last.A;
162  m_direction = DIRECTION_45( last );
163  tail.Remove( n, -1 );
164  return true;
165  }
166 
167  return false;
168 }
int Intersect(const SEG &aSeg, INTERSECTIONS &aIp) const
Function Intersect()
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
Function PointCount()
const VECTOR2I & CPoint(int aIndex) const
Function Point()
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)
Function Remove()
SHAPE_LINE_CHAIN & Line()
Definition: pns_line.h:136
Definition: seg.h:41
const SEG CSegment(int aIndex) const
Function CSegment()
SHAPE_LINE_CHAIN.
VECTOR2I A
Definition: seg.h:49
void Clear()
Function Clear() Removes 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 1232 of file pns_line_placer.cpp.

1233 {
1234  return m_placementCorrect || m_fixedTail.StageCount() > 1;
1235 }
FIXED_TAIL m_fixedTail
int StageCount() const

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

◆ 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 935 of file pns_line_placer.cpp.

936 {
937  m_idle = false;
938 
939  m_head.Line().Clear();
940  m_tail.Line().Clear();
947  m_head.RemoveVia();
948  m_tail.RemoveVia();
949 
952 
953  NODE* world = Router()->GetWorld();
954 
955  world->KillChildren();
956  NODE* rootNode = world->Branch();
957 
959 
960  setWorld( rootNode );
961 
962  wxLogTrace( "PNS", "world %p, intitial-direction %s layer %d",
963  m_world,
964  m_direction.Format().c_str(),
965  m_currentLayer );
966 
967  m_lastNode = nullptr;
970 
971  m_shove.reset();
972 
974  m_shove = std::make_unique<SHOVE>( m_world->Branch(), Router() );
975 }
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:153
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:124
void SetWidth(int aWidth)
Return line width.
Definition: pns_line.h:149
void SetNet(int aNet)
Definition: pns_item.h:147
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:1292
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
PNS_MODE Mode() const
Set the routing mode.
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 setWorld(NODE *aWorld)
Set the board to route.
void Clear()
Function Clear() Removes 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:158

References PNS::NODE::Branch(), SHAPE_LINE_CHAIN::Clear(), DIRECTION_45::Format(), PNS::ROUTER::GetWorld(), PNS::NODE::KillChildren(), PNS::LINE::Line(), m_currentLayer, m_currentMode, 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::ROUTING_SETTINGS::Mode(), PNS::LINE::RemoveVia(), PNS::RM_Shove, PNS::RM_Smart, PNS::ALGO_BASE::Router(), PNS::ITEM::SetLayer(), PNS::ITEM::SetNet(), PNS::ALGO_BASE::Settings(), PNS::LINE::SetWidth(), setWorld(), SplitAdjacentSegments(), and PNS::SIZES_SETTINGS::TrackWidth().

Referenced by Start(), and UpdateSizes().

◆ 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 NULL;
37 }
#define NULL

References NULL.

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 325 of file pns_line_placer.cpp.

326 {
327  SHAPE_LINE_CHAIN& head = m_head.Line();
328  SHAPE_LINE_CHAIN& tail = m_tail.Line();
329 
330  const int ForbiddenAngles = DIRECTION_45::ANG_ACUTE
333 
334  head.Simplify();
335  tail.Simplify();
336 
337  int n_head = head.ShapeCount();
338  int n_tail = tail.ShapeCount();
339 
340  if( n_head < 3 )
341  {
342  wxLogTrace( "PNS", "Merge failed: not enough head segs." );
343  return false;
344  }
345 
346  if( n_tail && head.CPoint( 0 ) != tail.CPoint( -1 ) )
347  {
348  wxLogTrace( "PNS", "Merge failed: head and tail discontinuous." );
349  return false;
350  }
351 
352  if( m_head.CountCorners( ForbiddenAngles ) != 0 )
353  return false;
354 
355  DIRECTION_45 dir_tail, dir_head;
356 
357  const std::vector<ssize_t>& headShapes = head.CShapes();
358  const std::vector<ssize_t>& tailShapes = tail.CShapes();
359 
360  if( headShapes[0] == -1 )
361  dir_head = DIRECTION_45( head.CSegment( 0 ) );
362  else
363  dir_head = DIRECTION_45( head.CArcs()[ headShapes[0] ] );
364 
365  if( n_tail )
366  {
367  wxASSERT( tail.PointCount() >= 2 );
368  int lastSegIdx = tail.PointCount() - 2;
369 
370  if( tailShapes[lastSegIdx] == -1 )
371  dir_tail = DIRECTION_45( tail.CSegment( -1 ) );
372  else
373  dir_tail = DIRECTION_45( tail.CArcs()[ tailShapes[lastSegIdx] ] );
374 
375  if( dir_head.Angle( dir_tail ) & ForbiddenAngles )
376  return false;
377  }
378 
379  tail.Append( head );
380 
381  tail.Simplify();
382 
383  SEG last = tail.CSegment( -1 );
384  m_p_start = last.B;
385 
386  int lastSegIdx = tail.PointCount() - 2;
387 
388  if( tailShapes[lastSegIdx] == -1 )
389  m_direction = DIRECTION_45( tail.CSegment( -1 ) );
390  else
391  m_direction = DIRECTION_45( tail.CArcs()[ tailShapes[lastSegIdx] ] );
392 
393  head.Remove( 0, -1 );
394 
395  wxLogTrace( "PNS", "Placer: merge %d, new direction: %s", n_head,
396  m_direction.Format().c_str() );
397 
398  head.Simplify();
399  tail.Simplify();
400 
401  return true;
402 }
SHAPE_LINE_CHAIN & Simplify(bool aRemoveColinear=true)
Function Simplify()
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
Function PointCount()
void Append(int aX, int aY, bool aAllowDuplication=false)
Function Append()
const std::vector< ssize_t > & CShapes() const
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
Function Point()
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
Returns the number of shapes (line segments or arcs) in this line chain.
void Remove(int aStartIndex, int aEndIndex)
Function Remove()
SHAPE_LINE_CHAIN & Line()
Definition: pns_line.h:136
Definition: seg.h:41
const SEG CSegment(int aIndex) const
Function CSegment()
SHAPE_LINE_CHAIN.
VECTOR2I m_p_start
current routing start (end of tail, beginning of head)
int CountCorners(int aAngles) const
Definition: pns_line.cpp:136
VECTOR2I B
Definition: seg.h:50

References DIRECTION_45::ANG_ACUTE, DIRECTION_45::ANG_HALF_FULL, DIRECTION_45::ANG_UNDEFINED, DIRECTION_45::Angle(), SHAPE_LINE_CHAIN::Append(), SEG::B, SHAPE_LINE_CHAIN::CArcs(), PNS::LINE::CountCorners(), SHAPE_LINE_CHAIN::CPoint(), SHAPE_LINE_CHAIN::CSegment(), SHAPE_LINE_CHAIN::CShapes(), DIRECTION_45::Format(), 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 978 of file pns_line_placer.cpp.

979 {
980  LINE current;
981  VECTOR2I p = aP;
982  int eiDepth = -1;
983 
984  if( aEndItem && aEndItem->Owner() )
985  eiDepth = static_cast<NODE*>( aEndItem->Owner() )->Depth();
986 
987  if( m_lastNode )
988  {
989  delete m_lastNode;
990  m_lastNode = nullptr;
991  }
992 
993  bool reachesEnd = route( p );
994 
995  current = Trace();
996 
997  if( !current.PointCount() )
999  else
1000  m_currentEnd = current.CLine().CPoint( -1 );
1001 
1002  NODE* latestNode = m_currentNode;
1003  m_lastNode = latestNode->Branch();
1004 
1005  if( reachesEnd
1006  && eiDepth >= 0
1007  && aEndItem && latestNode->Depth() > eiDepth
1008  && current.SegmentCount() )
1009  {
1010  SplitAdjacentSegments( m_lastNode, aEndItem, current.CPoint( -1 ) );
1011 
1012  if( Settings().RemoveLoops() )
1013  removeLoops( m_lastNode, current );
1014  }
1015 
1018  return true;
1019 }
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:124
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 658 of file pns_line_placer.cpp.

659 {
660  LINE linetmp = Trace();
661 
663  {
664  if( linetmp.SegmentCount() < 1 )
665  return false;
666 
667  m_head = linetmp;
668  m_p_start = linetmp.CLine().CPoint( 0 );
669  m_direction = DIRECTION_45( linetmp.CSegment( 0 ) );
670  m_tail.Line().Clear();
671 
672  return true;
673  }
674 
675  SHAPE_LINE_CHAIN& head = m_head.Line();
676  SHAPE_LINE_CHAIN& tail = m_tail.Line();
677 
678  int tailLookbackSegments = 3;
679 
680  //if(m_currentMode() == RM_Walkaround)
681  // tailLookbackSegments = 10000;
682 
683  int threshold = std::min( tail.PointCount(), tailLookbackSegments + 1 );
684 
685  if( tail.ShapeCount() < 3 )
686  return false;
687 
688  // assemble TailLookbackSegments tail segments with the current head
689  SHAPE_LINE_CHAIN opt_line = tail.Slice( -threshold, -1 );
690 
691  int end = std::min(2, head.PointCount() - 1 );
692 
693  opt_line.Append( head.Slice( 0, end ) );
694 
695  LINE new_head( m_tail, opt_line );
696 
697  // and see if it could be made simpler by merging obtuse/collnear segments.
698  // If so, replace the (threshold) last tail points and the head with
699  // the optimized line
700 
702  {
703  LINE tmp( m_tail, opt_line );
704 
705  wxLogTrace( "PNS", "Placer: optimize tail-head [%d]", threshold );
706 
707  head.Clear();
708  tail.Replace( -threshold, -1, new_head.CLine() );
709  tail.Simplify();
710 
711  m_p_start = new_head.CLine().CPoint( -1 );
712  m_direction = DIRECTION_45( new_head.CSegment( -1 ) );
713 
714  return true;
715  }
716 
717  return false;
718 }
SHAPE_LINE_CHAIN & Simplify(bool aRemoveColinear=true)
Function Simplify()
const SHAPE_LINE_CHAIN Slice(int aStartIndex, int aEndIndex=-1) const
Function Slice()
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
Function PointCount()
void Append(int aX, int aY, bool aAllowDuplication=false)
Function Append()
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
static bool Optimize(LINE *aLine, int aEffortLevel, NODE *aWorld, const VECTOR2I aV=VECTOR2I(0, 0))
int ShapeCount() const
Returns the number of shapes (line segments or arcs) in this line chain.
SHAPE_LINE_CHAIN & Line()
Definition: pns_line.h:136
NODE * m_currentNode
Current world state.
Reduce corner cost by merging obtuse segments.
SHAPE_LINE_CHAIN.
void Clear()
Function Clear() Removes 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)
Function Replace()

References SHAPE_LINE_CHAIN::Append(), SHAPE_LINE_CHAIN::Clear(), PNS::LINE::CLine(), SHAPE_LINE_CHAIN::CPoint(), PNS::LINE::CSegment(), PNS::OPTIMIZER::FANOUT_CLEANUP, PNS::LINE::Line(), m_currentNode, m_direction, m_head, m_p_start, m_tail, PNS::OPTIMIZER::MERGE_OBTUSE, PNS::OPTIMIZER::Optimize(), 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 260 of file pns_line_placer.cpp.

261 {
262  SHAPE_LINE_CHAIN& head = m_head.Line();
263  SHAPE_LINE_CHAIN& tail = m_tail.Line();
264 
265  int n = tail.SegmentCount();
266 
267  if( head.SegmentCount() < 1 )
268  return false;
269 
270  // Don't attempt this for too short tails
271  if( n < 2 )
272  return false;
273 
274  // Start from the segment farthest from the end of the tail
275  // int start_index = std::max(n - 1 - ReductionDepth, 0);
276 
277  DIRECTION_45 new_direction;
278  VECTOR2I new_start;
279  int reduce_index = -1;
280 
281  for( int i = tail.SegmentCount() - 1; i >= 0; i-- )
282  {
283  const SEG s = tail.CSegment( i );
284  DIRECTION_45 dir( s );
285 
286  // calculate a replacement route and check if it matches
287  // the direction of the segment to be replaced
288  SHAPE_LINE_CHAIN replacement = dir.BuildInitialTrace( s.A, aEnd );
289 
290  if( replacement.SegmentCount() < 1 )
291  continue;
292 
293  LINE tmp( m_tail, replacement );
294 
296  break;
297 
298  if( DIRECTION_45( replacement.CSegment( 0 ) ) == dir )
299  {
300  new_start = s.A;
301  new_direction = dir;
302  reduce_index = i;
303  }
304  }
305 
306  if( reduce_index >= 0 )
307  {
308  wxLogTrace( "PNS", "Placer: reducing tail: %d", reduce_index );
309  SHAPE_LINE_CHAIN reducedLine = new_direction.BuildInitialTrace( new_start, aEnd );
310 
311  m_p_start = new_start;
312  m_direction = new_direction;
313  tail.Remove( reduce_index + 1, -1 );
314  head.Clear();
315  return true;
316  }
317 
318  if( !tail.SegmentCount() )
320 
321  return false;
322 }
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)
Function Remove()
int SegmentCount() const
Function SegmentCount()
SHAPE_LINE_CHAIN & Line()
Definition: pns_line.h:136
Definition: seg.h:41
NODE * m_currentNode
Current world state.
const SEG CSegment(int aIndex) const
Function CSegment()
SHAPE_LINE_CHAIN.
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:427
VECTOR2I A
Definition: seg.h:49
void Clear()
Function Clear() Removes 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 1249 of file pns_line_placer.cpp.

1250 {
1251  if( !aLatest.SegmentCount() )
1252  return;
1253 
1254  if( aLatest.CLine().CPoint( 0 ) == aLatest.CLine().CPoint( -1 ) )
1255  return;
1256 
1257  std::set<LINKED_ITEM *> toErase;
1258  aNode->Add( aLatest, true );
1259 
1260  for( int s = 0; s < aLatest.LinkCount(); s++ )
1261  {
1262  LINKED_ITEM* seg = aLatest.GetLink(s);
1263  LINE ourLine = aNode->AssembleLine( seg );
1264  JOINT a, b;
1265  std::vector<LINE> lines;
1266 
1267  aNode->FindLineEnds( ourLine, a, b );
1268 
1269  if( a == b )
1270  aNode->FindLineEnds( aLatest, a, b );
1271 
1272  aNode->FindLinesBetweenJoints( a, b, lines );
1273 
1274  int removedCount = 0;
1275  int total = 0;
1276 
1277  for( LINE& line : lines )
1278  {
1279  total++;
1280 
1281  if( !( line.ContainsLink( seg ) ) && line.SegmentCount() )
1282  {
1283  for( LINKED_ITEM* ss : line.Links() )
1284  toErase.insert( ss );
1285 
1286  removedCount++;
1287  }
1288  }
1289 
1290  wxLogTrace( "PNS", "total segs removed: %d/%d", removedCount, total );
1291  }
1292 
1293  for( LINKED_ITEM* s : toErase )
1294  aNode->Remove( s );
1295 
1296  aNode->Remove( aLatest );
1297 }

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 516 of file pns_line_placer.cpp.

517 {
518  buildInitialLine( aP, m_head );
519  m_head.SetBlockingObstacle( nullptr );
520 
521  // If we are enforcing DRC violations, push back to the hull
522  if( !Settings().CanViolateDRC() )
523  {
525 
526  if( obs && obs->m_distFirst != INT_MAX )
527  {
528  buildInitialLine( obs->m_ipFirst, m_head );
529  m_head.SetBlockingObstacle( obs->m_item );
530  }
531  }
532 
533  aNewHead = m_head;
534 
535  return static_cast<bool>( m_currentNode->CheckColliding( &m_head ) );
536 }
OPT_OBSTACLE NearestObstacle(const LINE *aLine, int aKindMask=ITEM::ANY_T, const std::set< ITEM * > *aRestrictedSet=NULL)
Follow the line in search of an obstacle that is nearest to the starting to the line's starting point...
Definition: pns_node.cpp:285
LINE m_head
the volatile part of the track from the previously analyzed point to the current routing destination
bool buildInitialLine(const VECTOR2I &aP, LINE &aHead)
ROUTING_SETTINGS & Settings() const
Return the logger object, allowing to dump geometry to a file.
NODE * m_currentNode
Current world state.
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:427
OPT< OBSTACLE > OPT_OBSTACLE
Definition: pns_node.h:152
void SetBlockingObstacle(ITEM *aObstacle)
Definition: pns_line.h:205

References buildInitialLine(), PNS::NODE::CheckColliding(), 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 539 of file pns_line_placer.cpp.

540 {
541  LINE initTrack( m_head );
542  LINE walkSolids, l2;
543 
544  bool viaOk = buildInitialLine( aP, initTrack );
545 
546  m_currentNode = m_shove->CurrentNode();
547 
548  m_shove->SetLogger( Logger() );
549  m_shove->SetDebugDecorator( Dbg() );
550 
551  OPTIMIZER optimizer( m_currentNode );
552 
553  WALKAROUND walkaround( m_currentNode, Router() );
554 
555  walkaround.SetSolidsOnly( true );
556  walkaround.SetIterationLimit( 10 );
557  walkaround.SetDebugDecorator( Dbg() );
558  walkaround.SetLogger( Logger() );
559  WALKAROUND::WALKAROUND_STATUS stat_solids = walkaround.Route( initTrack, walkSolids );
560 
561  optimizer.SetEffortLevel( OPTIMIZER::MERGE_SEGMENTS );
562  optimizer.SetCollisionMask( ITEM::SOLID_T );
563  optimizer.Optimize( &walkSolids );
564 
565  if( stat_solids == WALKAROUND::DONE )
566  l2 = walkSolids;
567  else
568  l2 = initTrack.ClipToNearestObstacle( m_shove->CurrentNode() );
569 
570  LINE l( m_tail );
571  l.Line().Append( l2.CLine() );
572  l.Line().Simplify();
573 
574  if( l.PointCount() == 0 || l2.PointCount() == 0 )
575  {
576  aNewHead = m_head;
577  return false;
578  }
579 
580  if( m_placingVia && viaOk )
581  {
582  VIA v1( makeVia( l.CPoint( -1 ) ) );
583  VIA v2( makeVia( l2.CPoint( -1 ) ) );
584 
585  l.AppendVia( v1 );
586  l2.AppendVia( v2 );
587  }
588 
589  l.Line().Simplify();
590 
591  // in certain, uncommon cases there may be loops in the head+tail, In such case, we don't
592  // shove to avoid screwing up the database.
593  if( l.HasLoops() )
594  {
595  aNewHead = m_head;
596  return false;
597  }
598 
599  SHOVE::SHOVE_STATUS status = m_shove->ShoveLines( l );
600 
601  m_currentNode = m_shove->CurrentNode();
602 
603  if( status == SHOVE::SH_OK || status == SHOVE::SH_HEAD_MODIFIED )
604  {
605  if( status == SHOVE::SH_HEAD_MODIFIED )
606  l2 = m_shove->NewHead();
607 
608  optimizer.SetWorld( m_currentNode );
609 
610  int effortLevel = OPTIMIZER::MERGE_OBTUSE;
611 
612  if( Settings().SmartPads() && !m_mouseTrailTracer.IsManuallyForced() )
613  effortLevel = OPTIMIZER::SMART_PADS;
614 
615  optimizer.SetEffortLevel( effortLevel );
616 
617  optimizer.SetCollisionMask( ITEM::ANY_T );
618  optimizer.Optimize( &l2 );
619 
620  aNewHead = l2;
621 
622  return true;
623  }
624  else
625  {
626  walkaround.SetWorld( m_currentNode );
627  walkaround.SetSolidsOnly( false );
628  walkaround.SetIterationLimit( 10 );
629  walkaround.SetApproachCursor( true, aP );
630  walkaround.Route( initTrack, l2 );
631  aNewHead = l2.ClipToNearestObstacle( m_shove->CurrentNode() );
632 
633  return false;
634  }
635 
636  return false;
637 }
ROUTER * Router() const
Return current router settings.
Definition: pns_algo_base.h:54
Definition: track.h:343
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
bool buildInitialLine(const VECTOR2I &aP, LINE &aHead)
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
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.

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 428 of file pns_line_placer.cpp.

429 {
430  LINE initTrack( m_head );
431  LINE walkFull( m_head );
432  int effort = 0;
433  bool rv = true, viaOk;
434 
435  viaOk = buildInitialLine( aP, initTrack );
436 
437  WALKAROUND walkaround( m_currentNode, Router() );
438 
439  walkaround.SetSolidsOnly( false );
440  walkaround.SetDebugDecorator( Dbg() );
441  walkaround.SetLogger( Logger() );
442  walkaround.SetIterationLimit( Settings().WalkaroundIterationLimit() );
443 
444  WALKAROUND::RESULT wr = walkaround.Route( initTrack );
445  //WALKAROUND::WALKAROUND_STATUS wf = walkaround.Route( initTrack, walkFull, false );
446 
447  SHAPE_LINE_CHAIN l_cw = wr.lineCw.CLine();
448  SHAPE_LINE_CHAIN l_ccw = wr.lineCcw.CLine();
449 
450  if( wr.statusCcw == WALKAROUND::ALMOST_DONE || wr.statusCw == WALKAROUND::ALMOST_DONE )
451  {
452 
453  VECTOR2I p_cw = closestProjectedPoint( l_cw, aP );
454  VECTOR2I p_ccw = closestProjectedPoint( l_ccw, aP );
455 
456  int idx_cw = l_cw.Split( p_cw );
457  int idx_ccw = l_ccw.Split( p_ccw );
458 
459  l_cw = l_cw.Slice( 0, idx_cw );
460  l_ccw = l_ccw.Slice( 0, idx_ccw );
461 
462  //Dbg()->AddLine( wr.lineCw.CLine(), 3, 40000 );
463 
464  //Dbg()->AddPoint( p_cw, 4 );
465  //Dbg()->AddPoint( p_ccw, 5 );
466 
467  Dbg()->AddLine( wr.lineCw.CLine(), 4, 1000 );
468  Dbg()->AddLine( wr.lineCcw.CLine(), 5, 1000 );
469 
470  }
471 
472  walkFull.SetShape( l_ccw.Length() < l_cw.Length() ? l_ccw : l_cw );
473 
474  Dbg()->AddLine( walkFull.CLine(), 2, 100000, "walk-full" );
475 
476  switch( Settings().OptimizerEffort() )
477  {
478  case OE_LOW:
479  effort = 0;
480  break;
481 
482  case OE_MEDIUM:
483  case OE_FULL:
484  effort = OPTIMIZER::MERGE_SEGMENTS;
485  break;
486  }
487 
489  effort |= OPTIMIZER::SMART_PADS;
490 
491  if( wr.statusCw == WALKAROUND::STUCK || wr.statusCcw == WALKAROUND::STUCK )
492  {
493  walkFull = walkFull.ClipToNearestObstacle( m_currentNode );
494  rv = true;
495  }
496  else if( m_placingVia && viaOk )
497  {
498  walkFull.AppendVia( makeVia( walkFull.CPoint( -1 ) ) );
499  }
500 
501  OPTIMIZER::Optimize( &walkFull, effort, m_currentNode );
502 
503  if( m_currentNode->CheckColliding( &walkFull ) )
504  {
505  aNewHead = m_head;
506  return false;
507  }
508 
509  m_head = walkFull;
510  aNewHead = walkFull;
511 
512  return rv;
513 }
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
Function Length()
int Split(const VECTOR2I &aP)
Function Split()
virtual void AddLine(const SHAPE_LINE_CHAIN &aLine, int aType=0, int aWidth=0, const std::string aName="")
const SHAPE_LINE_CHAIN Slice(int aStartIndex, int aEndIndex=-1) const
Function Slice()
virtual LOGGER * Logger()
LINE m_head
the volatile part of the track from the previously analyzed point to the current routing destination
bool buildInitialLine(const VECTOR2I &aP, LINE &aHead)
ROUTING_SETTINGS & Settings() const
Return the logger object, allowing to dump geometry to a file.
PNS_OPTIMIZATION_EFFORT OptimizerEffort() const
Set the optimizer effort. Bigger means cleaner traces, but slower routing.
static bool Optimize(LINE *aLine, int aEffortLevel, NODE *aWorld, const VECTOR2I aV=VECTOR2I(0, 0))
DEBUG_DECORATOR * Dbg() const
Definition: pns_algo_base.h:78
MOUSE_TRAIL_TRACER m_mouseTrailTracer
VECTOR2I closestProjectedPoint(const SHAPE_LINE_CHAIN &line, const VECTOR2I &p)
Reduce corner cost iteratively.
Definition: pns_optimizer.h:99
NODE * m_currentNode
Current world state.
SHAPE_LINE_CHAIN.
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:427
const VIA makeVia(const VECTOR2I &aP)
Reroute pad exits.

References PNS::DEBUG_DECORATOR::AddLine(), PNS::WALKAROUND::ALMOST_DONE, PNS::LINE::AppendVia(), buildInitialLine(), PNS::NODE::CheckColliding(), PNS::LINE::CLine(), PNS::LINE::ClipToNearestObstacle(), PNS::closestProjectedPoint(), PNS::LINE::CPoint(), PNS::ALGO_BASE::Dbg(), 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, makeVia(), PNS::OPTIMIZER::MERGE_SEGMENTS, PNS::OE_FULL, PNS::OE_LOW, PNS::OE_MEDIUM, PNS::OPTIMIZER::Optimize(), PNS::ROUTING_SETTINGS::OptimizerEffort(), 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, and PNS::WALKAROUND::STUCK.

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 776 of file pns_line_placer.cpp.

777 {
778  routeStep( aP );
779 
780  if (!m_head.PointCount() )
781  return false;
782 
783  return m_head.CPoint(-1) == aP;
784 }
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 640 of file pns_line_placer.cpp.

641 {
642  switch( m_currentMode )
643  {
644  case RM_MarkObstacles:
645  return rhMarkObstacles( aP, aNewHead );
646  case RM_Walkaround:
647  return rhWalkOnly( aP, aNewHead );
648  case RM_Shove:
649  return rhShoveOnly( aP, aNewHead );
650  default:
651  break;
652  }
653 
654  return false;
655 }
bool rhWalkOnly(const VECTOR2I &aP, LINE &aNewHead)
Route step shove mode.
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 m_currentMode, rhMarkObstacles(), rhShoveOnly(), rhWalkOnly(), PNS::RM_MarkObstacles, PNS::RM_Shove, and PNS::RM_Walkaround.

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 721 of file pns_line_placer.cpp.

722 {
723  bool fail = false;
724  bool go_back = false;
725 
726  int i, n_iter = 1;
727 
728  LINE new_head;
729 
730  wxLogTrace( "PNS", "routeStep: direction: %s head: %d, tail: %d shapes",
731  m_direction.Format().c_str(),
732  m_head.ShapeCount(),
733  m_tail.ShapeCount() );
734 
735  for( i = 0; i < n_iter; i++ )
736  {
737  if( !go_back && Settings().FollowMouse() )
738  reduceTail( aP );
739 
740  go_back = false;
741 
742  if( !routeHead( aP, new_head ) )
743  fail = true;
744 
745  if( !new_head.Is45Degree() )
746  fail = true;
747 
748  if( !Settings().FollowMouse() )
749  return;
750 
751  m_head = new_head;
752 
754  {
755  n_iter++;
756  go_back = true;
757  }
758 
759  if( !go_back && handlePullback() )
760  {
761  n_iter++;
762  go_back = true;
763  }
764  }
765 
766  if( !fail )
767  {
769  return;
770 
771  mergeHead();
772  }
773 }
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
bool reduceTail(const VECTOR2I &aEnd)
Attempt to reduce the number of segments in the tail by trying to replace a certain number of latest ...
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
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.
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...
bool mergeHead()
Moves "established" segments from the head to the tail if certain conditions are met.

References PNS::ROUTING_SETTINGS::FollowMouse(), DIRECTION_45::Format(), handlePullback(), handleSelfIntersections(), PNS::LINE::Is45Degree(), m_direction, m_head, m_tail, mergeHead(), optimizeTailHeadTransition(), reduceTail(), routeHead(), PNS::ALGO_BASE::Settings(), and PNS::LINE::ShapeCount().

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 90 of file pns_line_placer.cpp.

91 {
92  m_initial_direction = aDirection;
93 
94  if( m_tail.SegmentCount() == 0 )
95  m_direction = aDirection;
96 }
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 848 of file pns_line_placer.cpp.

849 {
850  if( m_idle )
851  {
852  m_currentLayer = aLayer;
853  return true;
854  }
855  else if( m_chainedPlacement )
856  {
857  return false;
858  }
859  else if( !m_startItem
860  || ( m_startItem->OfKind( ITEM::VIA_T ) && m_startItem->Layers().Overlaps( aLayer ) )
861  || ( m_startItem->OfKind( ITEM::SOLID_T ) && m_startItem->Layers().Overlaps( aLayer ) ) )
862  {
863  m_currentLayer = aLayer;
864  m_head.Line().Clear();
865  m_tail.Line().Clear();
868  Move( m_currentEnd, nullptr );
869  return true;
870  }
871 
872  return false;
873 }
bool Move(const VECTOR2I &aP, ITEM *aEndItem) override
Move the end of the currently routed trace to the point aP, taking aEndItem as anchor (if not NULL).
void SetLayer(int aLayer)
Definition: pns_item.h:153
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
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:134
void Clear()
Function Clear() Removes all points from the line chain.
const LAYER_RANGE & Layers() const
Definition: pns_item.h:150

References SHAPE_LINE_CHAIN::Clear(), PNS::ITEM::Layers(), PNS::LINE::Line(), m_chainedPlacement, m_currentEnd, m_currentLayer, m_head, m_idle, m_startItem, m_tail, Move(), PNS::ITEM::OfKind(), LAYER_RANGE::Overlaps(), 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 1356 of file pns_line_placer.cpp.

1357 {
1358  m_orthoMode = aOrthoMode;
1359 }

References m_orthoMode.

◆ Settings()

◆ setWorld()

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

Set the board to route.

Definition at line 65 of file pns_line_placer.cpp.

66 {
67  m_world = aWorld;
68 }
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 vertexes.

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

Definition at line 1300 of file pns_line_placer.cpp.

1301 {
1302  wxASSERT( aLatest->OfKind( ITEM::SEGMENT_T | ITEM::ARC_T ) );
1303  LINE l = aNode->AssembleLine( aLatest );
1304 
1305  bool optimized = OPTIMIZER::Optimize( &l, OPTIMIZER::MERGE_COLINEAR, aNode );
1306 
1307  SHAPE_LINE_CHAIN simplified( l.CLine() );
1308 
1309  simplified.Simplify();
1310 
1311  if( optimized || simplified.PointCount() != l.PointCount() )
1312  {
1313  aNode->Remove( l );
1314  l.SetShape( simplified );
1315  aNode->Add( l );
1316  }
1317 }
SHAPE_LINE_CHAIN & Simplify(bool aRemoveColinear=true)
Function Simplify()
static bool Optimize(LINE *aLine, int aEffortLevel, NODE *aWorld, const VECTOR2I aV=VECTOR2I(0, 0))
void Remove(int aStartIndex, int aEndIndex)
Function Remove()
SHAPE_LINE_CHAIN.
Merge co-linear segments.

References PNS::NODE::Add(), PNS::ITEM::ARC_T, PNS::NODE::AssembleLine(), PNS::OPTIMIZER::MERGE_COLINEAR, PNS::ITEM::OfKind(), PNS::OPTIMIZER::Optimize(), PNS::NODE::Remove(), PNS::ITEM::SEGMENT_T, 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 820 of file pns_line_placer.cpp.

821 {
822  if( !aSeg )
823  return false;
824 
825  if( !aSeg->OfKind( ITEM::SEGMENT_T ) )
826  return false;
827 
828  JOINT* jt = aNode->FindJoint( aP, aSeg );
829 
830  if( jt && jt->LinkCount() >= 1 )
831  return false;
832 
833  SEGMENT* s_old = static_cast<SEGMENT*>( aSeg );
834 
835  std::unique_ptr<SEGMENT> s_new[2] = { Clone( *s_old ), Clone( *s_old ) };
836 
837  s_new[0]->SetEnds( s_old->Seg().A, aP );
838  s_new[1]->SetEnds( aP, s_old->Seg().B );
839 
840  aNode->Remove( s_old );
841  aNode->Add( std::move( s_new[0] ), true );
842  aNode->Add( std::move( s_new[1] ), true );
843 
844  return true;
845 }
std::unique_ptr< typename std::remove_const< T >::type > Clone(const T &aItem)
Definition: pns_item.h:257

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 876 of file pns_line_placer.cpp.

877 {
878  m_placementCorrect = false;
879  m_currentStart = VECTOR2I( aP );
880  m_currentEnd = VECTOR2I( aP );
881  m_currentNet = std::max( 0, aStartItem ? aStartItem->Net() : 0 );
882  m_startItem = aStartItem;
883  m_placingVia = false;
884  m_chainedPlacement = false;
885  m_fixedTail.Clear();
886 
887  setInitialDirection( Settings().InitialDirection() );
888 
889  initPlacement();
890 
891  DIRECTION_45 initialDir = m_initial_direction;
893 
894  if( aStartItem && aStartItem->Kind() == ITEM::SEGMENT_T )
895  {
896  // If we land on a segment endpoint, assume the starting direction is continuing along
897  // the same direction as the endpoint. If we started in the middle, don't set a
898  // direction so that the posture solver is not biased.
899  SEG seg = static_cast<SEGMENT*>( aStartItem )->Seg();
900 
901  if( aP == seg.A )
902  lastSegDir = DIRECTION_45( seg.Reversed() );
903  else if( aP == seg.B )
904  lastSegDir = DIRECTION_45( seg );
905  }
906  else if( aStartItem && aStartItem->Kind() == ITEM::SOLID_T &&
907  static_cast<SOLID*>( aStartItem )->Parent()->Type() == PCB_PAD_T )
908  {
909  double angle = static_cast<SOLID*>( aStartItem )->GetOrientation() / 10.0;
910  angle = ( angle + 22.5 ) / 45.0;
911  initialDir = DIRECTION_45( static_cast<DIRECTION_45::Directions>( int( angle ) ) );
912  }
913 
914  wxLogTrace( "PNS", "Posture: init %s, last seg %s", initialDir.Format(), lastSegDir.Format() );
915 
920  m_mouseTrailTracer.SetMouseDisabled( !Settings().GetAutoPosture() );
921 
922  NODE *n;
923 
924  if ( m_shove )
925  n = m_shove->CurrentNode();
926  else
927  n = m_currentNode;
928 
930 
931  return true;
932 }
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
SEG Reversed() const
Returns the center point of the line.
Definition: seg.h:370
Definition: seg.h:41
NODE * m_currentNode
Current world state.
void AddStage(VECTOR2I aStart, int aLayer, bool placingVias, DIRECTION_45 direction, NODE *aNode)
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
void SetDefaultDirections(DIRECTION_45 aInitDirection, DIRECTION_45 aLastSegDir)
VECTOR2I A
Definition: seg.h:49
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:50

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::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 79 of file pns_line_placer.cpp.

80 {
81  m_placingVia = aEnabled;
82 
83  if( !aEnabled )
84  m_head.RemoveVia();
85 
86  return true;
87 }
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 787 of file pns_line_placer.cpp.

788 {
789  LINE tmp( m_head );
790 
791  tmp.SetShape( m_tail.CLine() );
792  tmp.Line().Append( m_head.CLine() );
793  tmp.Line().Simplify();
794  return tmp;
795 }
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 798 of file pns_line_placer.cpp.

799 {
800  m_currentTrace = Trace();
801  return ITEM_SET( &m_currentTrace );
802 }
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 1194 of file pns_line_placer.cpp.

1195 {
1196  FIXED_TAIL::STAGE st;
1197 
1198  if ( !m_fixedTail.PopStage( st ) )
1199  return false;
1200 
1201  m_head.Line().Clear();
1202  m_tail.Line().Clear();
1203  m_startItem = nullptr;
1204  m_p_start = st.pts[0].p;
1205  m_direction = st.pts[0].direction;
1206  m_placingVia = st.pts[0].placingVias;
1207  m_currentNode = st.commit;
1208  m_currentLayer = st.pts[0].layer;
1211  m_head.RemoveVia();
1212  m_tail.RemoveVia();
1213 
1217 
1218  if( m_shove )
1219  {
1220  m_shove->RewindSpringbackTo( m_currentNode );
1221  m_shove->UnlockSpringbackNode( m_currentNode );
1222  m_currentNode = m_shove->CurrentNode();
1224  }
1225 
1227 
1228  return true;
1229 }
NODE * m_lastNode
Postprocessed world state (including marked collisions & removed loops)
void SetLayer(int aLayer)
Definition: pns_item.h:153
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:124
DIRECTION_45 m_initial_direction
routing direction for new traces
void KillChildren()
Definition: pns_node.cpp:1292
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
NODE * m_currentNode
Current world state.
void SetDefaultDirections(DIRECTION_45 aInitDirection, DIRECTION_45 aLastSegDir)
void Clear()
Function Clear() Removes 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::MOUSE_TRAIL_TRACER::SetDefaultDirections(), and PNS::ITEM::SetLayer().

◆ 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 1345 of file pns_line_placer.cpp.

1346 {
1347  LINE current = Trace();
1348  SHAPE_LINE_CHAIN ratLine;
1349  TOPOLOGY topo( m_lastNode );
1350 
1351  if( topo.LeadingRatLine( &current, ratLine ) )
1352  m_router->GetInterface()->DisplayRatline( ratLine, 5 );
1353 }
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
SHAPE_LINE_CHAIN.
ROUTER_IFACE * GetInterface() const
Definition: pns_router.h:215

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 1320 of file pns_line_placer.cpp.

1321 {
1322  // initPlacement will kill the tail, don't do that unless the track size has changed
1323  if( !m_idle && aSizes.TrackWidth() != m_sizes.TrackWidth() )
1324  {
1325  m_sizes = aSizes;
1326  initPlacement();
1327  }
1328 
1329  m_sizes = aSizes;
1330 
1331  if( !m_idle )
1332  {
1335 
1336  if( m_head.EndsWithVia() )
1337  {
1340  }
1341  }
1342 }
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
void initPlacement()
Initialize placement of a new line with given parameters.
void SetViaDrill(int aDrill)
Definition: pns_line.h:199

References PNS::LINE::EndsWithVia(), initPlacement(), m_head, m_idle, m_sizes, m_tail, PNS::LINE::SetViaDiameter(), PNS::LINE::SetViaDrill(), PNS::LINE::SetWidth(), PNS::SIZES_SETTINGS::TrackWidth(), PNS::SIZES_SETTINGS::ViaDiameter(), and PNS::SIZES_SETTINGS::ViaDrill().

◆ VisibleViewArea()

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

Definition at line 39 of file pns_algo_base.cpp.

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

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

Referenced by 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 350 of file pns_line_placer.h.

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

◆ m_currentLayer

int PNS::LINE_PLACER::m_currentLayer
private

◆ m_currentMode

PNS_MODE PNS::LINE_PLACER::m_currentMode
private

Definition at line 354 of file pns_line_placer.h.

Referenced by buildInitialLine(), FixRoute(), initPlacement(), LINE_PLACER(), and routeHead().

◆ m_currentNet

int PNS::LINE_PLACER::m_currentNet
private

◆ m_currentNode

◆ m_currentStart

VECTOR2I PNS::LINE_PLACER::m_currentStart
private

Definition at line 351 of file pns_line_placer.h.

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

◆ m_currentTrace

LINE PNS::LINE_PLACER::m_currentTrace
private

Definition at line 352 of file pns_line_placer.h.

Referenced by Traces().

◆ 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 328 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_lastNode

NODE* PNS::LINE_PLACER::m_lastNode
private

Postprocessed world state (including marked collisions & removed loops)

Definition at line 340 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(), and PNS::WALKAROUND::singleStep().

◆ 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 335 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 337 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 343 of file pns_line_placer.h.

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

◆ m_startItem

ITEM* PNS::LINE_PLACER::m_startItem
private

Definition at line 355 of file pns_line_placer.h.

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

◆ 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 331 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 334 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: