KiCad PCB EDA Suite
PNS::LINE_PLACER Class Reference

LINE_PLACER. 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
 Function Start() More...
 
bool Move (const VECTOR2I &aP, ITEM *aEndItem) override
 Function Move() More...
 
bool FixRoute (const VECTOR2I &aP, ITEM *aEndItem, bool aForceFinish) override
 Function FixRoute() More...
 
bool UnfixRoute () override
 
bool CommitPlacement () override
 
bool AbortPlacement () override
 
bool HasPlacedAnything () const override
 
bool ToggleVia (bool aEnabled) override
 Function ToggleVia() More...
 
bool SetLayer (int aLayer) override
 Function SetLayer() More...
 
const LINEHead () const
 Function Head() More...
 
const LINETail () const
 Function Tail() More...
 
const LINE Trace () const
 Function Trace() More...
 
const ITEM_SET Traces () override
 Function Traces() More...
 
const VECTOR2ICurrentEnd () const override
 Function CurrentEnd() More...
 
const std::vector< int > CurrentNets () const override
 Function CurrentNet() More...
 
int CurrentLayer () const override
 Function CurrentLayer() More...
 
NODECurrentNode (bool aLoopsRemoved=false) const override
 Function CurrentNode() More...
 
void FlipPosture () override
 Function FlipPosture() More...
 
void UpdateSizes (const SIZES_SETTINGS &aSizes) override
 Function UpdateSizes() 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)
 Function SplitAdjacentSegments() More...
 
ROUTERRouter () const
 

Returns the instance of our router

More...
 
ROUTING_SETTINGSSettings () const
 

Returns current router settings

More...
 
virtual LOGGERLogger ()
 

Returns the logger object, allowing to dump geometry to a file.

More...
 
void SetLogger (LOGGER *aLogger)
 
void SetDebugDecorator (DEBUG_DECORATOR *aDecorator)
 Function SetDebugDecorator. More...
 
DEBUG_DECORATORDbg () const
 

Protected Attributes

DEBUG_DECORATORm_debugDecorator
 
ROUTERm_router
 
LOGGERm_logger
 

Private Member Functions

bool route (const VECTOR2I &aP)
 Function route() More...
 
void updateLeadingRatLine ()
 Function updateLeadingRatLine() More...
 
void setWorld (NODE *aWorld)
 Function setWorld() More...
 
void initPlacement ()
 Function startPlacement() More...
 
void setInitialDirection (const DIRECTION_45 &aDirection)
 Function setInitialDirection() More...
 
void removeLoops (NODE *aNode, LINE &aLatest)
 Function removeLoops() More...
 
void simplifyNewLine (NODE *aNode, SEGMENT *aLatest)
 Function simplifyNewLine() More...
 
bool checkObtusity (const SEG &aA, const SEG &aB) const
 Function checkObtusity() More...
 
bool handleSelfIntersections ()
 Function handleSelfIntersections() More...
 
bool handlePullback ()
 Function handlePullback() More...
 
bool mergeHead ()
 Function mergeHead() More...
 
bool reduceTail (const VECTOR2I &aEnd)
 Function reduceTail() More...
 
bool optimizeTailHeadTransition ()
 Function optimizeTailHeadTransition() More...
 
bool routeHead (const VECTOR2I &aP, LINE &aNewHead)
 Function routeHead() More...
 
void routeStep (const VECTOR2I &aP)
 Function routeStep() More...
 
const LINE reduceToNearestObstacle (const LINE &aOriginalLine)
 
bool rhStopAtNearestObstacle (const VECTOR2I &aP, LINE &aNewHead)
 
bool rhWalkOnly (const VECTOR2I &aP, LINE &aNewHead)
 

route step, walkaround mode

More...
 
bool rhShoveOnly (const VECTOR2I &aP, LINE &aNewHead)
 

route step, shove mode

More...
 
bool rhMarkObstacles (const VECTOR2I &aP, LINE &aNewHead)
 

route step, mark obstacles mode

More...
 
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
 

routing "head": 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 point (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
 

Are we placing a via?

More...
 
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
 
POSTURE_SOLVER m_postureSolver
 

Detailed Description

LINE_PLACER.

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

Definition at line 110 of file pns_line_placer.h.

Constructor & Destructor Documentation

◆ LINE_PLACER()

PNS::LINE_PLACER::LINE_PLACER ( ROUTER aRouter)

Definition at line 40 of file pns_line_placer.cpp.

40  :
41  PLACEMENT_ALGO( aRouter )
42 {
44  m_world = NULL;
45  m_shove = NULL;
47  m_idle = true;
48 
49  // Init temporary variables (do not leave uninitialized members)
50  m_lastNode = NULL;
51  m_placingVia = false;
52  m_currentNet = 0;
53  m_currentLayer = 0;
55  m_startItem = NULL;
56  m_chainedPlacement = false;
57  m_orthoMode = false;
58  m_placementCorrect = false;
59 }
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
#define NULL
std::unique_ptr< SHOVE > m_shove
The shove engine
NODE * m_currentNode
Current world state
bool m_placingVia
Are we placing a via?
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, NULL, and PNS::RM_MarkObstacles.

◆ ~LINE_PLACER()

PNS::LINE_PLACER::~LINE_PLACER ( )

Definition at line 62 of file pns_line_placer.cpp.

63 {
64 }

Member Function Documentation

◆ AbortPlacement()

bool PNS::LINE_PLACER::AbortPlacement ( )
overridevirtual

Reimplemented from PNS::PLACEMENT_ALGO.

Definition at line 1458 of file pns_line_placer.cpp.

1459 {
1460  m_world->KillChildren();
1461  return true;
1462 }
NODE * m_world
pointer to world to search colliding items
void KillChildren()
Destroys all child nodes. Applicable only to the root node.
Definition: pns_node.cpp:1288

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

◆ buildInitialLine()

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

Definition at line 1380 of file pns_line_placer.cpp.

1381 {
1382  SHAPE_LINE_CHAIN l;
1383  int initial_radius = 0;
1384 
1385  auto guessedDir = m_postureSolver.GetPosture( aP );
1386 
1387  if( m_p_start == aP )
1388  {
1389  l.Clear();
1390  }
1391  else
1392  {
1393  if( Settings().GetFreeAngleMode() && Settings().Mode() == RM_MarkObstacles )
1394  {
1395  l = SHAPE_LINE_CHAIN( { m_p_start, aP } );
1396  }
1397  else
1398  {
1399  // Rounded corners don't make sense when routing orthogonally (single track at a time)
1400  if( Settings().GetRounded() && !m_orthoMode )
1401  initial_radius = Settings().GetMaxRadius();
1402 
1403 
1404  if( !m_tail.PointCount() )
1405  l = guessedDir.BuildInitialTrace( m_p_start, aP, false, initial_radius );
1406  else
1407  l = m_direction.BuildInitialTrace( m_p_start, aP, false, initial_radius );
1408  }
1409 
1410  if( l.SegmentCount() > 1 && m_orthoMode )
1411  {
1412  VECTOR2I newLast = l.CSegment( 0 ).LineProject( l.CPoint( -1 ) );
1413 
1414  l.Remove( -1, -1 );
1415  l.SetPoint( 1, newLast );
1416  }
1417  }
1418 
1419  aHead.SetLayer( m_currentLayer );
1420  aHead.SetShape( l );
1421 
1422  if( !m_placingVia )
1423  return true;
1424 
1425  VIA v( makeVia( aP ) );
1426  v.SetNet( aHead.Net() );
1427 
1429  {
1430  aHead.AppendVia( v );
1431  return true;
1432  }
1433 
1434  VECTOR2I force;
1435  VECTOR2I lead = aP - m_p_start;
1436 
1437  bool solidsOnly = ( m_currentMode != RM_Walkaround );
1438 
1439  if( v.PushoutForce( m_currentNode, lead, force, solidsOnly, 40 ) )
1440  {
1441  SHAPE_LINE_CHAIN line = m_direction.BuildInitialTrace( m_p_start, aP + force, initial_radius );
1442  aHead = LINE( aHead, line );
1443 
1444  v.SetPos( v.Pos() + force );
1445  return true;
1446  }
1447 
1448  return false; // via placement unsuccessful
1449 }
void SetPoint(int aIndex, const VECTOR2I &aPos)
Accessor Function to move a point to a specific location.
POSTURE_SOLVER m_postureSolver
int PointCount() const
Returns the number of points in the line
Definition: pns_line.h:161
DIRECTION_45 GetPosture(const VECTOR2I &aP)
ROUTING_SETTINGS & Settings() const
Returns current router settings
const VECTOR2I & CPoint(int aIndex) const
Function Point()
VECTOR2I LineProject(const VECTOR2I &aP) const
Function LineProject()
Definition: seg.h:362
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
void Remove(int aStartIndex, int aEndIndex)
Function Remove()
int SegmentCount() const
Function SegmentCount()
const SHAPE_LINE_CHAIN BuildInitialTrace(const VECTOR2I &aP0, const VECTOR2I &aP1, bool aStartDiagonal=false, int aMaxRadius=0) const
Function BuildInitialTrace()
NODE * m_currentNode
Current world state
const SEG CSegment(int aIndex) const
Function CSegment()
bool m_placingVia
Are we placing a via?
SHAPE_LINE_CHAIN.
void Clear()
Function Clear() Removes all points from the line chain.
VECTOR2I m_p_start
current routing start point (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(), PNS::ROUTING_SETTINGS::GetMaxRadius(), PNS::POSTURE_SOLVER::GetPosture(), SEG::LineProject(), m_currentLayer, m_currentMode, m_currentNode, m_direction, m_orthoMode, m_p_start, m_placingVia, m_postureSolver, 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, 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(), rhStopAtNearestObstacle(), and rhWalkOnly().

◆ checkObtusity()

bool PNS::LINE_PLACER::checkObtusity ( const SEG aA,
const SEG aB 
) const
private

Function checkObtusity()

Helper function, checking if segments a and b form an obtuse angle (in 45-degree regime).

Returns
true, if angle (aA, aB) is obtuse

Definition at line 298 of file pns_line_placer.cpp.

299 {
300  const DIRECTION_45 dir_a( aA );
301  const DIRECTION_45 dir_b( aB );
302 
303  return dir_a.IsObtuse( dir_b ) || dir_a == dir_b;
304 }
DIRECTION_45.
Definition: direction45.h:37

References DIRECTION_45::IsObtuse().

◆ CommitPlacement()

bool PNS::LINE_PLACER::CommitPlacement ( )
overridevirtual

Reimplemented from PNS::PLACEMENT_ALGO.

Definition at line 1270 of file pns_line_placer.cpp.

1271 {
1272  if( m_lastNode )
1274 
1275  m_lastNode = NULL;
1276  m_currentNode = NULL;
1277  return true;
1278 }
ROUTER * Router() const
Returns the instance of our router
Definition: pns_algo_base.h:51
NODE * m_lastNode
Postprocessed world state (including marked collisions & removed loops)
void CommitRouting()
Definition: pns_router.cpp:443
#define NULL
NODE * m_currentNode
Current world state

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

◆ CurrentEnd()

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

Function CurrentEnd()

Returns 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 202 of file pns_line_placer.h.

203  {
204  return m_currentEnd;
205  }

References m_currentEnd.

◆ CurrentLayer()

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

Function CurrentLayer()

Returns the layer of currently routed track.

Implements PNS::PLACEMENT_ALGO.

Definition at line 222 of file pns_line_placer.h.

223  {
224  return m_currentLayer;
225  }

References m_currentLayer.

◆ CurrentNets()

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

Function CurrentNet()

Returns the net code of currently routed track.

Implements PNS::PLACEMENT_ALGO.

Definition at line 212 of file pns_line_placer.h.

213  {
214  return std::vector<int>( 1, m_currentNet );
215  }

References m_currentNet.

◆ CurrentNode()

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

Function CurrentNode()

Returns the most recent world state.

Implements PNS::PLACEMENT_ALGO.

Definition at line 900 of file pns_line_placer.cpp.

901 {
902  if( aLoopsRemoved && m_lastNode )
903  return m_lastNode;
904 
905  return m_currentNode;
906 }
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

Function FixRoute()

Commits 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 commited. May return false if the routing result is violating design rules - in such case, the track is only committed if Settings.CanViolateDRC() is on.

Implements PNS::PLACEMENT_ALGO.

Definition at line 1083 of file pns_line_placer.cpp.

1084 {
1085  bool realEnd = false;
1086  int lastV;
1087 
1088  LINE pl = Trace();
1089 
1091  {
1092  // Mark Obstacles is sort of a half-manual, half-automated mode in which the
1093  // user has more responsibility and authority.
1094 
1095  if( aEndItem )
1096  {
1097  // The user has indicated a connection should be made. If either the
1098  // trace or endItem is netless, then allow the connection by adopting the net of the other.
1099  if( m_currentNet <= 0 )
1100  {
1101  m_currentNet = aEndItem->Net();
1102  pl.SetNet( m_currentNet );
1103  }
1104  else if (aEndItem->Net() <= 0 )
1105  aEndItem->SetNet( m_currentNet );
1106  }
1107 
1108  // Collisions still prevent fixing unless "Allow DRC violations" is checked
1109  if( !Settings().CanViolateDRC() && m_world->CheckColliding( &pl ) )
1110  return false;
1111  }
1112 
1113  const SHAPE_LINE_CHAIN& l = pl.CLine();
1114 
1115  if( !l.SegmentCount() )
1116  {
1117  // Nothing to commit if we have an empty line
1118  if( !pl.EndsWithVia() )
1119  return false;
1120 
1121  m_lastNode->Add( Clone( pl.Via() ) );
1122  m_currentNode = NULL;
1123 
1124  m_idle = true;
1125  m_placementCorrect = true;
1126  return true;
1127  }
1128 
1129  VECTOR2I p_pre_last = l.CPoint( -1 );
1130  const VECTOR2I p_last = l.CPoint( -1 );
1131  DIRECTION_45 d_last( l.CSegment( -1 ) );
1132 
1133  if( l.PointCount() > 2 )
1134  p_pre_last = l.CPoint( -2 );
1135 
1136  if( aEndItem && m_currentNet >= 0 && m_currentNet == aEndItem->Net() )
1137  realEnd = true;
1138 
1139  if( aForceFinish )
1140  realEnd = true;
1141 
1142  if( realEnd || m_placingVia )
1143  lastV = l.SegmentCount();
1144  else
1145  lastV = std::max( 1, l.SegmentCount() - 1 );
1146 
1147  SEGMENT* lastSeg = nullptr;
1148  int lastArc = -1;
1149 
1150  for( int i = 0; i < lastV; i++ )
1151  {
1152  ssize_t arcIndex = l.ArcIndex( i );
1153 
1154  if( arcIndex < 0 )
1155  {
1156  const SEG& s = pl.CSegment( i );
1157  auto seg = std::make_unique<SEGMENT>( s, m_currentNet );
1158  seg->SetWidth( pl.Width() );
1159  seg->SetLayer( m_currentLayer );
1160  if( !m_lastNode->Add( std::move( seg ) ) )
1161  lastSeg = nullptr;
1162  }
1163  else
1164  {
1165  if( arcIndex == lastArc )
1166  continue;
1167 
1168  auto arc = std::make_unique<ARC>( l.Arc( arcIndex ), m_currentNet );
1169  arc->SetWidth( pl.Width() );
1170  arc->SetLayer( m_currentLayer );
1171  m_lastNode->Add( std::move( arc ) );
1172  lastSeg = nullptr;
1173  lastArc = arcIndex;
1174  }
1175  }
1176 
1177  if( pl.EndsWithVia() )
1178  {
1179  m_lastNode->Add( Clone( pl.Via() ) );
1180  }
1181 
1182  if( realEnd && lastSeg )
1183  simplifyNewLine( m_lastNode, lastSeg );
1184 
1185 
1186  if( !realEnd )
1187  {
1188  setInitialDirection( d_last );
1189  m_currentStart = m_placingVia ? p_last : p_pre_last;
1190 
1192 
1193  m_startItem = NULL;
1194  m_placingVia = false;
1195  m_chainedPlacement = !pl.EndsWithVia();
1196 
1199 
1200  m_head.Line().Clear();
1201  m_tail.Line().Clear();
1202  m_head.RemoveVia();
1203  m_tail.RemoveVia();
1206 
1207  if ( m_shove )
1208  {
1209  m_shove->AddLockedSpringbackNode( m_currentNode );
1210  }
1211 
1212 
1217 
1218  m_placementCorrect = true;
1219  }
1220  else
1221  {
1222  m_placementCorrect = true;
1223  m_idle = true;
1224  }
1225 
1226  return realEnd;
1227 }
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
LINE m_head
routing "head": volatile part of the track from the previously analyzed point to the current routing ...
void RemoveVia()
Definition: pns_line.h:237
POSTURE_SOLVER m_postureSolver
const LINE Trace() const
Function Trace()
void simplifyNewLine(NODE *aNode, SEGMENT *aLatest)
Function simplifyNewLine()
int PointCount() const
Function PointCount()
NODE * Branch()
Function Branch()
Definition: pns_node.cpp:106
ssize_t ArcIndex(size_t aSegment) const
ROUTING_SETTINGS & Settings() const
Returns current router settings
void SetTollerance(int toll)
const VECTOR2I & CPoint(int aIndex) const
Function Point()
DIRECTION_45 m_initial_direction
routing direction for new traces
#define NULL
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)
Function setInitialDirection()
void AddTrailPoint(const VECTOR2I &aP)
DIRECTION_45.
Definition: direction45.h:37
DIRECTION_45 m_direction
current routing direction
void SetDefaultDirections(DIRECTION_45 aInitDirection, DIRECTION_45 aLastSegDir)
std::unique_ptr< SHOVE > m_shove
The shove engine
FIXED_TAIL m_fixedTail
int SegmentCount() const
Function SegmentCount()
SHAPE_LINE_CHAIN & Line()
Modifiable accessor to the underlying shape
Definition: pns_line.h:143
std::unique_ptr< typename std::remove_const< T >::type > Clone(const T &aItem)
Definition: pns_item.h:271
Definition: seg.h:39
NODE * m_currentNode
Current world state
void AddStage(VECTOR2I aStart, int aLayer, bool placingVias, DIRECTION_45 direction, NODE *aNode)
const SEG CSegment(int aIndex) const
Function CSegment()
bool m_placingVia
Are we placing a via?
SHAPE_LINE_CHAIN.
OPT_OBSTACLE CheckColliding(const ITEM *aItem, int aKindMask=ITEM::ANY_T)
Function CheckColliding()
Definition: pns_node.cpp:427
int Width() const
Returns line width
Definition: pns_line.h:192
void Clear()
Function Clear() Removes all points from the line chain.
VECTOR2I m_p_start
current routing start point (end of tail, beginning of head)
bool Add(std::unique_ptr< SEGMENT > aSegment, bool aAllowRedundant=false)
Function Add()
Definition: pns_node.cpp:620

References PNS::NODE::Add(), PNS::FIXED_TAIL::AddStage(), PNS::POSTURE_SOLVER::AddTrailPoint(), SHAPE_LINE_CHAIN::Arc(), SHAPE_LINE_CHAIN::ArcIndex(), PNS::NODE::Branch(), PNS::NODE::CheckColliding(), PNS::POSTURE_SOLVER::Clear(), SHAPE_LINE_CHAIN::Clear(), PNS::LINE::CLine(), PNS::Clone(), SHAPE_LINE_CHAIN::CPoint(), PNS::LINE::CSegment(), SHAPE_LINE_CHAIN::CSegment(), PNS::LINE::EndsWithVia(), 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_p_start, m_placementCorrect, m_placingVia, m_postureSolver, m_shove, m_startItem, m_tail, m_world, PNS::ITEM::Net(), NULL, SHAPE_LINE_CHAIN::PointCount(), PNS::LINE::RemoveVia(), PNS::RM_MarkObstacles, SHAPE_LINE_CHAIN::SegmentCount(), PNS::POSTURE_SOLVER::SetDefaultDirections(), setInitialDirection(), PNS::ITEM::SetNet(), PNS::ALGO_BASE::Settings(), PNS::POSTURE_SOLVER::SetTollerance(), simplifyNewLine(), Trace(), PNS::LINE::Via(), and PNS::LINE::Width().

◆ FlipPosture()

void PNS::LINE_PLACER::FlipPosture ( )
overridevirtual

Function FlipPosture()

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

Reimplemented from PNS::PLACEMENT_ALGO.

Definition at line 894 of file pns_line_placer.cpp.

895 {
897 }
POSTURE_SOLVER m_postureSolver

References PNS::POSTURE_SOLVER::FlipPosture(), and m_postureSolver.

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

1453 {
1454  aNets.push_back( m_currentNet );
1455 }

References m_currentNet.

◆ handlePullback()

bool PNS::LINE_PLACER::handlePullback ( )
private

Function handlePullback()

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

175 {
176  SHAPE_LINE_CHAIN& head = m_head.Line();
177  SHAPE_LINE_CHAIN& tail = m_tail.Line();
178 
179  if( head.PointCount() < 2 )
180  return false;
181 
182  int n = tail.PointCount();
183 
184  if( n == 0 )
185  return false;
186  else if( n == 1 )
187  {
188  m_p_start = tail.CPoint( 0 );
189  tail.Clear();
190  return true;
191  }
192 
193  DIRECTION_45 first_head( head.CSegment( 0 ) );
194  DIRECTION_45 last_tail( tail.CSegment( -1 ) );
195  DIRECTION_45::AngleType angle = first_head.Angle( last_tail );
196 
197  // case 1: we have a defined routing direction, and the currently computed
198  // head goes in different one.
199  bool pullback_1 = false; // (m_direction != DIRECTION_45::UNDEFINED && m_direction != first_head);
200 
201  // case 2: regardless of the current routing direction, if the tail/head
202  // extremities form an acute or right angle, reduce the tail by one segment
203  // (and hope that further iterations) will result with a cleaner trace
204  bool pullback_2 = ( angle == DIRECTION_45::ANG_RIGHT || angle == DIRECTION_45::ANG_ACUTE );
205 
206  if( pullback_1 || pullback_2 )
207  {
208  const SEG last = tail.CSegment( -1 );
209  m_direction = DIRECTION_45( last );
210  m_p_start = last.A;
211 
212  wxLogTrace( "PNS", "Placer: pullback triggered [%d] [%s %s]",
213  n, last_tail.Format().c_str(), first_head.Format().c_str() );
214 
215  // erase the last point in the tail, hoping that the next iteration will
216  // result with a head trace that starts with a segment following our
217  // current direction.
218  if( n < 2 )
219  tail.Clear(); // don't leave a single-point tail
220  else
221  tail.Remove( -1, -1 );
222 
223  if( !tail.SegmentCount() )
225 
226  return true;
227  }
228 
229  return false;
230 }
LINE m_head
routing "head": volatile part of the track from the previously analyzed point to the current routing ...
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
DIRECTION_45.
Definition: direction45.h:37
DIRECTION_45 m_direction
current routing direction
void Remove(int aStartIndex, int aEndIndex)
Function Remove()
int SegmentCount() const
Function SegmentCount()
SHAPE_LINE_CHAIN & Line()
Modifiable accessor to the underlying shape
Definition: pns_line.h:143
Definition: seg.h:39
AngleType
Enum AngleType Represents kind of angle formed by vectors heading in two DIRECTION_45s.
Definition: direction45.h:64
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:47
void Clear()
Function Clear() Removes all points from the line chain.
VECTOR2I m_p_start
current routing start point (end of tail, beginning of head)

References SEG::A, DIRECTION_45::ANG_ACUTE, DIRECTION_45::ANG_RIGHT, PNS::angle(), SHAPE_LINE_CHAIN::Clear(), SHAPE_LINE_CHAIN::CPoint(), SHAPE_LINE_CHAIN::CSegment(), PNS::LINE::Line(), m_direction, m_head, m_initial_direction, m_p_start, m_tail, SHAPE_LINE_CHAIN::PointCount(), SHAPE_LINE_CHAIN::Remove(), and SHAPE_LINE_CHAIN::SegmentCount().

Referenced by routeStep().

◆ handleSelfIntersections()

bool PNS::LINE_PLACER::handleSelfIntersections ( )
private

Function handleSelfIntersections()

Checks if the head of the track intersects its tail. If so, cuts the tail up to the intersecting segment and fixes the head direction to match the last segment before the cut.

Returns
true if the line has been changed.

Definition at line 101 of file pns_line_placer.cpp.

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

1265 {
1266  return m_placementCorrect || m_fixedTail.StageCount() > 1;
1267 }
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

Function Head()

Returns the "head" of the line being placed, that is the volatile part that has not "settled" yet.

Definition at line 172 of file pns_line_placer.h.

172 { return m_head; }
LINE m_head
routing "head": volatile part of the track from the previously analyzed point to the current routing ...

References m_head.

◆ initPlacement()

void PNS::LINE_PLACER::initPlacement ( )
private

Function startPlacement()

Initializes placement of a new line with given parameters.

Definition at line 999 of file pns_line_placer.cpp.

1000 {
1001  m_idle = false;
1002 
1003  m_head.Line().Clear();
1004  m_tail.Line().Clear();
1011  m_head.RemoveVia();
1012  m_tail.RemoveVia();
1013 
1016 
1017  NODE* world = Router()->GetWorld();
1018 
1019  world->KillChildren();
1020  NODE* rootNode = world->Branch();
1021 
1023 
1024  setWorld( rootNode );
1025 
1026  wxLogTrace( "PNS", "world %p, intitial-direction %s layer %d",
1027  m_world, m_direction.Format().c_str(), m_currentLayer );
1028 
1029  m_lastNode = NULL;
1031  m_currentMode = Settings().Mode();
1032 
1033  m_shove.reset();
1034 
1036  {
1037  m_shove = std::make_unique<SHOVE>( m_world->Branch(), Router() );
1038  }
1039 }
ROUTER * Router() const
Returns the instance of our router
Definition: pns_algo_base.h:51
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:154
const std::string Format() const
Function Format() Formats the direction in a human readable word.
Definition: direction45.h:101
Ignore collisions, mark obstacles
LINE m_head
routing "head": volatile part of the track from the previously analyzed point to the current routing ...
void RemoveVia()
Definition: pns_line.h:237
SIZES_SETTINGS m_sizes
NODE * Branch()
Function Branch()
Definition: pns_node.cpp:106
void SetWidth(int aWidth)
Sets line width
Definition: pns_line.h:185
void SetNet(int aNet)
Definition: pns_item.h:148
ROUTING_SETTINGS & Settings() const
Returns current router settings
DIRECTION_45 m_initial_direction
routing direction for new traces
void KillChildren()
Destroys all child nodes. Applicable only to the root node.
Definition: pns_node.cpp:1288
#define NULL
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)
Function SplitAdjacentSegments()
DIRECTION_45 m_direction
current routing direction
PNS_MODE Mode() const
Returns the routing mode.
std::unique_ptr< SHOVE > m_shove
The shove engine
SHAPE_LINE_CHAIN & Line()
Modifiable accessor to the underlying shape
Definition: pns_line.h:143
Only walkaround
NODE * m_currentNode
Current world state
void setWorld(NODE *aWorld)
Function setWorld()
void Clear()
Function Clear() Removes all points from the line chain.
VECTOR2I m_p_start
current routing start point (end of tail, beginning of head)
NODE * GetWorld() const
Definition: pns_router.h:154

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(), NULL, 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 252 of file pns_line_placer.h.

252 { return m_placingVia; }
bool m_placingVia
Are we placing a via?

References m_placingVia.

◆ Logger()

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

Returns the logger object, allowing to dump geometry to a file.

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 PNS::DRAGGER::dragWalkaround(), rhShoveOnly(), rhWalkOnly(), and PNS::DRAGGER::Start().

◆ makeVia()

◆ mergeHead()

bool PNS::LINE_PLACER::mergeHead ( )
private

Function mergeHead()

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

Returns
true, if the line has been changed.

Definition at line 307 of file pns_line_placer.cpp.

308 {
309  SHAPE_LINE_CHAIN& head = m_head.Line();
310  SHAPE_LINE_CHAIN& tail = m_tail.Line();
311 
312  const int ForbiddenAngles = DIRECTION_45::ANG_ACUTE |
315 
316  head.Simplify();
317  tail.Simplify();
318 
319  int n_head = head.SegmentCount();
320  int n_tail = tail.SegmentCount();
321 
322  if( n_head < 3 )
323  {
324  wxLogTrace( "PNS", "Merge failed: not enough head segs." );
325  return false;
326  }
327 
328  if( n_tail && head.CPoint( 0 ) != tail.CPoint( -1 ) )
329  {
330  wxLogTrace( "PNS", "Merge failed: head and tail discontinuous." );
331  return false;
332  }
333 
334  if( m_head.CountCorners( ForbiddenAngles ) != 0 )
335  return false;
336 
337  DIRECTION_45 dir_tail, dir_head;
338 
339  dir_head = DIRECTION_45( head.CSegment( 0 ) );
340 
341  if( n_tail )
342  {
343  dir_tail = DIRECTION_45( tail.CSegment( -1 ) );
344 
345  if( dir_head.Angle( dir_tail ) & ForbiddenAngles )
346  return false;
347  }
348 
349  tail.Append( head );
350  tail.Remove( -1 );
351 
352  tail.Simplify();
353 
354  SEG last = tail.CSegment( -1 );
355 
356  m_p_start = last.B;
357  m_direction = DIRECTION_45( last ).Right();
358 
359  head.Remove( 0, -1 );
360 
361  wxLogTrace( "PNS", "Placer: merge %d, new direction: %s", n_head, m_direction.Format().c_str() );
362 
363  head.Simplify();
364  tail.Simplify();
365 
366  return true;
367 }
const std::string Format() const
Function Format() Formats the direction in a human readable word.
Definition: direction45.h:101
LINE m_head
routing "head": volatile part of the track from the previously analyzed point to the current routing ...
const DIRECTION_45 Right() const
Function Right()
Definition: direction45.h:228
void Append(int aX, int aY, bool aAllowDuplication=false)
Function Append()
SHAPE_LINE_CHAIN & Simplify()
Function Simplify()
AngleType Angle(const DIRECTION_45 &aOther) const
Function Angle() Returns the type of angle between directions (this) and aOther.
Definition: direction45.h:153
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
DIRECTION_45.
Definition: direction45.h:37
DIRECTION_45 m_direction
current routing direction
void Remove(int aStartIndex, int aEndIndex)
Function Remove()
int SegmentCount() const
Function SegmentCount()
SHAPE_LINE_CHAIN & Line()
Modifiable accessor to the underlying shape
Definition: pns_line.h:143
Definition: seg.h:39
const SEG CSegment(int aIndex) const
Function CSegment()
SHAPE_LINE_CHAIN.
VECTOR2I m_p_start
current routing start point (end of tail, beginning of head)
int CountCorners(int aAngles) const
Returns the number of corners of angles specified by mask aAngles.
Definition: pns_line.cpp:134
VECTOR2I B
Definition: seg.h:48

References DIRECTION_45::ANG_ACUTE, DIRECTION_45::ANG_HALF_FULL, DIRECTION_45::ANG_UNDEFINED, DIRECTION_45::Angle(), SHAPE_LINE_CHAIN::Append(), SEG::B, PNS::LINE::CountCorners(), SHAPE_LINE_CHAIN::CPoint(), SHAPE_LINE_CHAIN::CSegment(), DIRECTION_45::Format(), PNS::LINE::Line(), m_direction, m_head, m_p_start, m_tail, SHAPE_LINE_CHAIN::Remove(), DIRECTION_45::Right(), SHAPE_LINE_CHAIN::SegmentCount(), and SHAPE_LINE_CHAIN::Simplify().

Referenced by routeStep().

◆ Move()

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

Function Move()

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

Implements PNS::PLACEMENT_ALGO.

Definition at line 1042 of file pns_line_placer.cpp.

1043 {
1044  LINE current;
1045  VECTOR2I p = aP;
1046  int eiDepth = -1;
1047 
1048  if( aEndItem && aEndItem->Owner() )
1049  eiDepth = static_cast<NODE*>( aEndItem->Owner() )->Depth();
1050 
1051  if( m_lastNode )
1052  {
1053  delete m_lastNode;
1054  m_lastNode = NULL;
1055  }
1056 
1057  bool reachesEnd = route( p );
1058 
1059  current = Trace();
1060 
1061  if( !current.PointCount() )
1063  else
1064  m_currentEnd = current.CLine().CPoint( -1 );
1065 
1066  NODE* latestNode = m_currentNode;
1067  m_lastNode = latestNode->Branch();
1068 
1069  if( reachesEnd && eiDepth >= 0 && aEndItem && latestNode->Depth() > eiDepth && current.SegmentCount() )
1070  {
1071  SplitAdjacentSegments( m_lastNode, aEndItem, current.CPoint( -1 ) );
1072 
1073  if( Settings().RemoveLoops() )
1074  removeLoops( m_lastNode, current );
1075  }
1076 
1079  return true;
1080 }
NODE * m_lastNode
Postprocessed world state (including marked collisions & removed loops)
void removeLoops(NODE *aNode, LINE &aLatest)
Function removeLoops()
POSTURE_SOLVER m_postureSolver
const LINE Trace() const
Function Trace()
NODE * Branch()
Function Branch()
Definition: pns_node.cpp:106
bool RemoveLoops() const
Returns true if loop (redundant track) removal is on.
ROUTING_SETTINGS & Settings() const
Returns current router settings
#define NULL
void AddTrailPoint(const VECTOR2I &aP)
bool SplitAdjacentSegments(NODE *aNode, ITEM *aSeg, const VECTOR2I &aP)
Function SplitAdjacentSegments()
void updateLeadingRatLine()
Function updateLeadingRatLine()
bool route(const VECTOR2I &aP)
Function route()
NODE * m_currentNode
Current world state
VECTOR2I m_p_start
current routing start point (end of tail, beginning of head)

References PNS::POSTURE_SOLVER::AddTrailPoint(), PNS::NODE::Branch(), PNS::LINE::CLine(), PNS::LINE::CPoint(), SHAPE_LINE_CHAIN::CPoint(), PNS::NODE::Depth(), m_currentEnd, m_currentNode, m_lastNode, m_p_start, m_postureSolver, NULL, 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

Function optimizeTailHeadTransition()

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

749 {
750  LINE linetmp = Trace();
751 
753  {
754  if( linetmp.SegmentCount() < 1 )
755  return false;
756 
757  m_head = linetmp;
758  m_p_start = linetmp.CLine().CPoint( 0 );
759  m_direction = DIRECTION_45( linetmp.CSegment( 0 ) );
760  m_tail.Line().Clear();
761 
762  return true;
763  }
764 
765  SHAPE_LINE_CHAIN& head = m_head.Line();
766  SHAPE_LINE_CHAIN& tail = m_tail.Line();
767 
768  int tailLookbackSegments = 3;
769 
770  //if(m_currentMode() == RM_Walkaround)
771  // tailLookbackSegments = 10000;
772 
773  int threshold = std::min( tail.PointCount(), tailLookbackSegments + 1 );
774 
775  if( tail.SegmentCount() < 3 )
776  return false;
777 
778  // assemble TailLookbackSegments tail segments with the current head
779  SHAPE_LINE_CHAIN opt_line = tail.Slice( -threshold, -1 );
780 
781  int end = std::min(2, head.PointCount() - 1 );
782 
783  opt_line.Append( head.Slice( 0, end ) );
784 
785  LINE new_head( m_tail, opt_line );
786 
787  // and see if it could be made simpler by merging obtuse/collnear segments.
788  // If so, replace the (threshold) last tail points and the head with
789  // the optimized line
790 
792  {
793  LINE tmp( m_tail, opt_line );
794 
795  wxLogTrace( "PNS", "Placer: optimize tail-head [%d]", threshold );
796 
797  head.Clear();
798  tail.Replace( -threshold, -1, new_head.CLine() );
799  tail.Simplify();
800 
801  m_p_start = new_head.CLine().CPoint( -1 );
802  m_direction = DIRECTION_45( new_head.CSegment( -1 ) );
803 
804  return true;
805  }
806 
807  return false;
808 }
const SHAPE_LINE_CHAIN Slice(int aStartIndex, int aEndIndex=-1) const
Function Slice()
LINE m_head
routing "head": volatile part of the track from the previously analyzed point to the current routing ...
const LINE Trace() const
Function Trace()
int PointCount() const
Function PointCount()
void Append(int aX, int aY, bool aAllowDuplication=false)
Function Append()
SHAPE_LINE_CHAIN & Simplify()
Function Simplify()
LINE m_tail
routing "tail": part of the track that has been already fixed due to collisions with obstacles
DIRECTION_45.
Definition: direction45.h:37
DIRECTION_45 m_direction
current routing direction
static bool Optimize(LINE *aLine, int aEffortLevel, NODE *aWorld, const VECTOR2I aV=VECTOR2I(0, 0))
a quick shortcut to optmize a line without creating and setting up an optimizer
int SegmentCount() const
Function SegmentCount()
SHAPE_LINE_CHAIN & Line()
Modifiable accessor to the underlying shape
Definition: pns_line.h:143
NODE * m_currentNode
Current world state
SHAPE_LINE_CHAIN.
void Clear()
Function Clear() Removes all points from the line chain.
VECTOR2I m_p_start
current routing start point (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::SegmentCount(), SHAPE_LINE_CHAIN::Simplify(), SHAPE_LINE_CHAIN::Slice(), and Trace().

Referenced by routeStep().

◆ reduceTail()

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

Function reduceTail()

Attempts to reduce the numer 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
aEndcurrent routing destination point.
Returns
true if the line has been changed.

Definition at line 233 of file pns_line_placer.cpp.

234 {
235  SHAPE_LINE_CHAIN& head = m_head.Line();
236  SHAPE_LINE_CHAIN& tail = m_tail.Line();
237 
238  int n = tail.SegmentCount();
239 
240  if( head.SegmentCount() < 1 )
241  return false;
242 
243  // Don't attempt this for too short tails
244  if( n < 2 )
245  return false;
246 
247  // Start from the segment farthest from the end of the tail
248  // int start_index = std::max(n - 1 - ReductionDepth, 0);
249 
250  DIRECTION_45 new_direction;
251  VECTOR2I new_start;
252  int reduce_index = -1;
253 
254  for( int i = tail.SegmentCount() - 1; i >= 0; i-- )
255  {
256  const SEG s = tail.CSegment( i );
257  DIRECTION_45 dir( s );
258 
259  // calculate a replacement route and check if it matches
260  // the direction of the segment to be replaced
261  SHAPE_LINE_CHAIN replacement = dir.BuildInitialTrace( s.A, aEnd );
262 
263  if( replacement.SegmentCount() < 1 )
264  continue;
265 
266  LINE tmp( m_tail, replacement );
267 
269  break;
270 
271  if( DIRECTION_45( replacement.CSegment( 0 ) ) == dir )
272  {
273  new_start = s.A;
274  new_direction = dir;
275  reduce_index = i;
276  }
277  }
278 
279  if( reduce_index >= 0 )
280  {
281  wxLogTrace( "PNS", "Placer: reducing tail: %d", reduce_index );
282  SHAPE_LINE_CHAIN reducedLine = new_direction.BuildInitialTrace( new_start, aEnd );
283 
284  m_p_start = new_start;
285  m_direction = new_direction;
286  tail.Remove( reduce_index + 1, -1 );
287  head.Clear();
288  return true;
289  }
290 
291  if( !tail.SegmentCount() )
293 
294  return false;
295 }
LINE m_head
routing "head": volatile part of the track from the previously analyzed point to the current routing ...
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.
Definition: direction45.h:37
DIRECTION_45 m_direction
current routing direction
void Remove(int aStartIndex, int aEndIndex)
Function Remove()
int SegmentCount() const
Function SegmentCount()
SHAPE_LINE_CHAIN & Line()
Modifiable accessor to the underlying shape
Definition: pns_line.h:143
const SHAPE_LINE_CHAIN BuildInitialTrace(const VECTOR2I &aP0, const VECTOR2I &aP1, bool aStartDiagonal=false, int aMaxRadius=0) const
Function BuildInitialTrace()
Definition: seg.h:39
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)
Function CheckColliding()
Definition: pns_node.cpp:427
VECTOR2I A
Definition: seg.h:47
void Clear()
Function Clear() Removes all points from the line chain.
VECTOR2I m_p_start
current routing start point (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().

◆ reduceToNearestObstacle()

const LINE PNS::LINE_PLACER::reduceToNearestObstacle ( const LINE aOriginalLine)
private

Definition at line 528 of file pns_line_placer.cpp.

529 {
530  const auto& l0 = aOriginalLine.CLine();
531 
532  if ( !l0.PointCount() )
533  return aOriginalLine;
534 
535  int l = l0.Length();
536  int step = l / 2;
537  VECTOR2I target;
538 
539  LINE l_test( aOriginalLine );
540 
541  while( step > 0 )
542  {
543  target = l0.PointAlong( l );
544  SHAPE_LINE_CHAIN l_cur( l0 );
545 
546  int index = l_cur.Split( target );
547 
548  l_test.SetShape( l_cur.Slice( 0, index ) );
549 
550  if ( m_currentNode->CheckColliding( &l_test ) )
551  l -= step;
552  else
553  l += step;
554 
555  step /= 2;
556  }
557 
558  l = l_test.CLine().Length();
559 
560  while( m_currentNode->CheckColliding( &l_test ) && l > 0 )
561  {
562  l--;
563  target = l0.PointAlong( l );
564  SHAPE_LINE_CHAIN l_cur( l0 );
565 
566  int index = l_cur.Split( target );
567 
568  l_test.SetShape( l_cur.Slice( 0, index ) );
569  }
570 
571  return l_test;
572 }
NODE * m_currentNode
Current world state
SHAPE_LINE_CHAIN.
OPT_OBSTACLE CheckColliding(const ITEM *aItem, int aKindMask=ITEM::ANY_T)
Function CheckColliding()
Definition: pns_node.cpp:427

References PNS::NODE::CheckColliding(), PNS::LINE::CLine(), SHAPE_LINE_CHAIN::Length(), m_currentNode, PNS::LINE::SetShape(), SHAPE_LINE_CHAIN::Slice(), and SHAPE_LINE_CHAIN::Split().

Referenced by rhStopAtNearestObstacle().

◆ removeLoops()

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

Function removeLoops()

Searches aNode for traces concurrent to aLatest and removes them. Updated topology is stored in aNode.

Definition at line 1281 of file pns_line_placer.cpp.

1282 {
1283  if( !aLatest.SegmentCount() )
1284  return;
1285 
1286  if( aLatest.CLine().CPoint( 0 ) == aLatest.CLine().CPoint( -1 ) )
1287  return;
1288 
1289  std::set<LINKED_ITEM *> toErase;
1290  aNode->Add( aLatest, true );
1291 
1292  for( int s = 0; s < aLatest.LinkCount(); s++ )
1293  {
1294  auto seg = aLatest.GetLink(s);
1295  LINE ourLine = aNode->AssembleLine( seg );
1296  JOINT a, b;
1297  std::vector<LINE> lines;
1298 
1299  aNode->FindLineEnds( ourLine, a, b );
1300 
1301  if( a == b )
1302  {
1303  aNode->FindLineEnds( aLatest, a, b );
1304  }
1305 
1306  aNode->FindLinesBetweenJoints( a, b, lines );
1307 
1308  int removedCount = 0;
1309  int total = 0;
1310 
1311  for( LINE& line : lines )
1312  {
1313  total++;
1314 
1315  if( !( line.ContainsLink( seg ) ) && line.SegmentCount() )
1316  {
1317  for( auto ss : line.Links() )
1318  toErase.insert( ss );
1319 
1320  removedCount++;
1321  }
1322  }
1323 
1324  wxLogTrace( "PNS", "total segs removed: %d/%d", removedCount, total );
1325  }
1326 
1327  for( auto s : toErase )
1328  aNode->Remove( s );
1329 
1330  aNode->Remove( aLatest );
1331 }

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

route step, mark obstacles mode

Definition at line 480 of file pns_line_placer.cpp.

481 {
482  LINE newHead( m_head ), bestHead( m_head );
483  bool hasBest = false;
484 
485  buildInitialLine( aP, newHead );
486 
487  NODE::OBSTACLES obstacles;
488 
489  m_currentNode->QueryColliding( &newHead, obstacles );
490 
491  // If we are allowing DRC violations, we don't push back to the hull
492  if( !Settings().CanViolateDRC() )
493  {
494  for( auto& obs : obstacles )
495  {
496  int cl = m_currentNode->GetClearance( obs.m_item, &newHead );
497  auto hull = obs.m_item->Hull( cl, newHead.Width() );
498 
499  auto nearest = hull.NearestPoint( aP );
500  Dbg()->AddLine( hull, 2, 10000 );
501 
502  if( ( nearest - aP ).EuclideanNorm() < newHead.Width() + cl )
503  {
504  buildInitialLine( nearest, newHead );
505 
506  // We want the shortest line here to ensure we don't break a clearance
507  // rule on larger, overlapping items (e.g. vias)
508  if( newHead.CLine().Length() < bestHead.CLine().Length() )
509  {
510  bestHead = newHead;
511  hasBest = true;
512  }
513  }
514  }
515  }
516 
517  if( hasBest )
518  m_head = bestHead;
519  else
520  m_head = newHead;
521 
522  aNewHead = m_head;
523 
524  return static_cast<bool>( m_currentNode->CheckColliding( &m_head ) );
525 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:128
virtual void AddLine(const SHAPE_LINE_CHAIN &aLine, int aType=0, int aWidth=0, const std::string aName="")
LINE m_head
routing "head": volatile part of the track from the previously analyzed point to the current routing ...
bool buildInitialLine(const VECTOR2I &aP, LINE &aHead)
ROUTING_SETTINGS & Settings() const
Returns current router settings
int GetClearance(const ITEM *aA, const ITEM *aB) const
Returns the expected clearance between items a and b.
Definition: pns_node.cpp:97
DEBUG_DECORATOR * Dbg() const
Definition: pns_algo_base.h:77
NODE * m_currentNode
Current world state
OPT_OBSTACLE CheckColliding(const ITEM *aItem, int aKindMask=ITEM::ANY_T)
Function CheckColliding()
Definition: pns_node.cpp:427
std::vector< OBSTACLE > OBSTACLES
Definition: pns_node.h:150
int QueryColliding(const ITEM *aItem, OBSTACLES &aObstacles, int aKindMask=ITEM::ANY_T, int aLimitCount=-1, bool aDifferentNetsOnly=true, int aForceClearance=-1)
Function QueryColliding()
Definition: pns_node.cpp:278

References PNS::DEBUG_DECORATOR::AddLine(), buildInitialLine(), PNS::NODE::CheckColliding(), PNS::LINE::CLine(), PNS::ALGO_BASE::Dbg(), EuclideanNorm(), PNS::NODE::GetClearance(), SHAPE_LINE_CHAIN::Length(), m_currentNode, m_head, PNS::NODE::QueryColliding(), and PNS::ALGO_BASE::Settings().

Referenced by routeHead().

◆ rhShoveOnly()

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

route step, shove mode

Definition at line 627 of file pns_line_placer.cpp.

628 {
629  LINE initTrack( m_head );
630  LINE walkSolids, l2;
631 
632  bool viaOk = buildInitialLine( aP, initTrack );
633 
634  m_currentNode = m_shove->CurrentNode();
635 
636  m_shove->SetLogger( Logger() );
637  m_shove->SetDebugDecorator( Dbg() );
638 
639  OPTIMIZER optimizer( m_currentNode );
640 
641  WALKAROUND walkaround( m_currentNode, Router() );
642 
643  walkaround.SetSolidsOnly( true );
644  walkaround.SetIterationLimit( 10 );
645  walkaround.SetDebugDecorator( Dbg() );
646  walkaround.SetLogger( Logger() );
647  WALKAROUND::WALKAROUND_STATUS stat_solids = walkaround.Route( initTrack, walkSolids );
648 
649  optimizer.SetEffortLevel( OPTIMIZER::MERGE_SEGMENTS );
650  optimizer.SetCollisionMask( ITEM::SOLID_T );
651  optimizer.Optimize( &walkSolids );
652 
653  if( stat_solids == WALKAROUND::DONE )
654  l2 = walkSolids;
655  else
656  l2 = initTrack.ClipToNearestObstacle( m_shove->CurrentNode() );
657 
658  LINE l( m_tail );
659  l.Line().Append( l2.CLine() );
660  l.Line().Simplify();
661 
662  if( l.PointCount() == 0 || l2.PointCount() == 0 )
663  {
664  aNewHead = m_head;
665  return false;
666  }
667 
668  if( m_placingVia && viaOk )
669  {
670  VIA v1( makeVia( l.CPoint( -1 ) ) );
671  VIA v2( makeVia( l2.CPoint( -1 ) ) );
672 
673  l.AppendVia( v1 );
674  l2.AppendVia( v2 );
675  }
676 
677  l.Line().Simplify();
678 
679  // in certain, uncommon cases there may be loops in the head+tail, In such case, we don't shove to avoid
680  // screwing up the database.
681  if( l.HasLoops() )
682  {
683  aNewHead = m_head;
684  return false;
685  }
686 
687  SHOVE::SHOVE_STATUS status = m_shove->ShoveLines( l );
688 
689  m_currentNode = m_shove->CurrentNode();
690 
691  if( status == SHOVE::SH_OK || status == SHOVE::SH_HEAD_MODIFIED )
692  {
693  if( status == SHOVE::SH_HEAD_MODIFIED )
694  {
695  l2 = m_shove->NewHead();
696  }
697 
698  optimizer.SetWorld( m_currentNode );
699 
700  int effortLevel = OPTIMIZER::MERGE_OBTUSE;
701  if( Settings().SmartPads() )
702  {
703  effortLevel = OPTIMIZER::SMART_PADS;
704  }
705  optimizer.SetEffortLevel( effortLevel );
706 
707  optimizer.SetCollisionMask( ITEM::ANY_T );
708  optimizer.Optimize( &l2 );
709 
710  aNewHead = l2;
711 
712  return true;
713  }
714  else
715  {
716  walkaround.SetWorld( m_currentNode );
717  walkaround.SetSolidsOnly( false );
718  walkaround.SetIterationLimit( 10 );
719  walkaround.SetApproachCursor( true, aP );
720  walkaround.Route( initTrack, l2 );
721  aNewHead = l2.ClipToNearestObstacle( m_shove->CurrentNode() );
722 
723  return false;
724  }
725 
726  return false;
727 }
ROUTER * Router() const
Returns the instance of our router
Definition: pns_algo_base.h:51
virtual LOGGER * Logger()
Returns the logger object, allowing to dump geometry to a file.
LINE m_head
routing "head": volatile part of the track from the previously analyzed point to the current routing ...
bool buildInitialLine(const VECTOR2I &aP, LINE &aHead)
ROUTING_SETTINGS & Settings() const
Returns current router settings
LINE m_tail
routing "tail": part of the track that has been already fixed due to collisions with obstacles
DEBUG_DECORATOR * Dbg() const
Definition: pns_algo_base.h:77
std::unique_ptr< SHOVE > m_shove
The shove engine
NODE * m_currentNode
Current world state
bool m_placingVia
Are we placing a via?
const VIA makeVia(const VECTOR2I &aP)

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::LINE::Line(), PNS::ALGO_BASE::Logger(), m_currentNode, m_head, 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, and PNS::ITEM::SOLID_T.

Referenced by routeHead().

◆ rhStopAtNearestObstacle()

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

Definition at line 575 of file pns_line_placer.cpp.

576 {
577  LINE l0;
578  l0 = m_head;
579 
580  buildInitialLine( aP, l0 );
581 
582  LINE l_cur = reduceToNearestObstacle( l0 );
583 
584  const auto l_shape = l_cur.CLine();
585 
586  if( l_shape.SegmentCount() == 0 )
587  {
588  return false;
589  }
590 
591  if( l_shape.SegmentCount() == 1 )
592  {
593  auto s = l_shape.CSegment( 0 );
594 
595  VECTOR2I dL( DIRECTION_45( s ).Left().ToVector() );
596  VECTOR2I dR( DIRECTION_45( s ).Right().ToVector() );
597 
598  SEG leadL( s.B, s.B + dL );
599  SEG leadR( s.B, s.B + dR );
600 
601  SEG segL( s.B, leadL.LineProject( aP ) );
602  SEG segR( s.B, leadR.LineProject( aP ) );
603 
604  LINE finishL( l0, SHAPE_LINE_CHAIN( { segL.A, segL.B } ) );
605  LINE finishR( l0, SHAPE_LINE_CHAIN( { segR.A, segR.B } ) );
606 
607  LINE reducedL = reduceToNearestObstacle( finishL );
608  LINE reducedR = reduceToNearestObstacle( finishR );
609 
610  int lL = reducedL.CLine().Length();
611  int lR = reducedR.CLine().Length();
612 
613  if( lL > lR )
614  l_cur.Line().Append( reducedL.CLine() );
615  else
616  l_cur.Line().Append( reducedR.CLine() );
617 
618  l_cur.Line().Simplify();
619  }
620 
621  m_head = l_cur;
622  aNewHead = m_head;
623  return true;
624 }
const LINE reduceToNearestObstacle(const LINE &aOriginalLine)
LINE m_head
routing "head": volatile part of the track from the previously analyzed point to the current routing ...
bool buildInitialLine(const VECTOR2I &aP, LINE &aHead)
DIRECTION_45.
Definition: direction45.h:37
Definition: seg.h:39
SHAPE_LINE_CHAIN.

References SHAPE_LINE_CHAIN::Append(), buildInitialLine(), PNS::LINE::CLine(), SHAPE_LINE_CHAIN::CSegment(), PCAD2KICAD::Left, SHAPE_LINE_CHAIN::Length(), PNS::LINE::Line(), SEG::LineProject(), m_head, reduceToNearestObstacle(), PCAD2KICAD::Right, and SHAPE_LINE_CHAIN::Simplify().

◆ rhWalkOnly()

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

route step, walkaround mode

Definition at line 392 of file pns_line_placer.cpp.

393 {
394  LINE initTrack( m_head );
395  LINE walkFull( m_head );
396  int effort = 0;
397  bool rv = true, viaOk;
398 
399  viaOk = buildInitialLine( aP, initTrack );
400 
401  WALKAROUND walkaround( m_currentNode, Router() );
402 
403  walkaround.SetSolidsOnly( false );
404  walkaround.SetDebugDecorator( Dbg() );
405  walkaround.SetLogger( Logger() );
406  walkaround.SetIterationLimit( Settings().WalkaroundIterationLimit() );
407 
408  WALKAROUND::RESULT wr = walkaround.Route( initTrack );
409  //WALKAROUND::WALKAROUND_STATUS wf = walkaround.Route( initTrack, walkFull, false );
410 
411  auto l_cw = wr.lineCw.CLine();
412  auto l_ccw = wr.lineCcw.CLine();
413 
414  if( wr.statusCcw == WALKAROUND::ALMOST_DONE || wr.statusCw == WALKAROUND::ALMOST_DONE )
415  {
416 
417  auto p_cw = closestProjectedPoint( l_cw, aP );
418  auto p_ccw = closestProjectedPoint( l_ccw, aP );
419 
420  int idx_cw = l_cw.Split( p_cw );
421  int idx_ccw = l_ccw.Split( p_ccw );
422 
423  l_cw = l_cw.Slice( 0, idx_cw );
424  l_ccw = l_ccw.Slice( 0, idx_ccw );
425 
426  //Dbg()->AddLine( wr.lineCw.CLine(), 3, 40000 );
427 
428  //Dbg()->AddPoint( p_cw, 4 );
429  //Dbg()->AddPoint( p_ccw, 5 );
430 
431  Dbg()->AddLine( wr.lineCw.CLine(), 4, 1000 );
432  Dbg()->AddLine( wr.lineCcw.CLine(), 5, 1000 );
433 
434  }
435 
436  walkFull.SetShape( l_ccw.Length() < l_cw.Length() ? l_ccw : l_cw );
437 
438  Dbg()->AddLine( walkFull.CLine(), 2, 100000, "walk-full" );
439 
440  switch( Settings().OptimizerEffort() )
441  {
442  case OE_LOW:
443  effort = 0;
444  break;
445 
446  case OE_MEDIUM:
447  case OE_FULL:
448  effort = OPTIMIZER::MERGE_SEGMENTS;
449  break;
450  }
451 
452  if( Settings().SmartPads() )
453  effort |= OPTIMIZER::SMART_PADS;
454 
455  if( wr.statusCw == WALKAROUND::STUCK || wr.statusCcw == WALKAROUND::STUCK )
456  {
457  walkFull = walkFull.ClipToNearestObstacle( m_currentNode );
458  rv = true;
459  }
460  else if( m_placingVia && viaOk )
461  {
462  walkFull.AppendVia( makeVia( walkFull.CPoint( -1 ) ) );
463  }
464 
465  OPTIMIZER::Optimize( &walkFull, effort, m_currentNode );
466 
467  if( m_currentNode->CheckColliding( &walkFull ) )
468  {
469  aNewHead = m_head;
470  return false;
471  }
472 
473  m_head = walkFull;
474  aNewHead = walkFull;
475 
476  return rv;
477 }
bool SmartPads() const
Returns true if Smart Pads (optimized connections) is enabled.
ROUTER * Router() const
Returns the instance of our router
Definition: pns_algo_base.h:51
virtual void AddLine(const SHAPE_LINE_CHAIN &aLine, int aType=0, int aWidth=0, const std::string aName="")
virtual LOGGER * Logger()
Returns the logger object, allowing to dump geometry to a file.
LINE m_head
routing "head": volatile part of the track from the previously analyzed point to the current routing ...
bool buildInitialLine(const VECTOR2I &aP, LINE &aHead)
ROUTING_SETTINGS & Settings() const
Returns current router settings
PNS_OPTIMIZATION_EFFORT OptimizerEffort() const
Returns 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))
a quick shortcut to optmize a line without creating and setting up an optimizer
DEBUG_DECORATOR * Dbg() const
Definition: pns_algo_base.h:77
VECTOR2I closestProjectedPoint(const SHAPE_LINE_CHAIN &line, const VECTOR2I &p)
NODE * m_currentNode
Current world state
bool m_placingVia
Are we placing a via?
OPT_OBSTACLE CheckColliding(const ITEM *aItem, int aKindMask=ITEM::ANY_T)
Function CheckColliding()
Definition: pns_node.cpp:427
const VIA makeVia(const VECTOR2I &aP)

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::WALKAROUND::RESULT::lineCcw, PNS::WALKAROUND::RESULT::lineCw, PNS::ALGO_BASE::Logger(), m_currentNode, m_head, 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(), PNS::OPTIMIZER::SMART_PADS, PNS::ROUTING_SETTINGS::SmartPads(), 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

Function route()

Re-routes 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 865 of file pns_line_placer.cpp.

866 {
867  routeStep( aP );
868 
869  if (!m_head.PointCount() )
870  return false;
871 
872  return m_head.CPoint(-1) == aP;
873 }
void routeStep(const VECTOR2I &aP)
Function routeStep()
LINE m_head
routing "head": volatile part of the track from the previously analyzed point to the current routing ...
int PointCount() const
Returns the number of points in the line
Definition: pns_line.h:161
const VECTOR2I & CPoint(int aIdx) const
Returns the aIdx-th point of the line
Definition: pns_line.h:173

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

Function routeHead()

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

731 {
732  switch( m_currentMode )
733  {
734  case RM_MarkObstacles:
735  return rhMarkObstacles( aP, aNewHead );
736  case RM_Walkaround:
737  return rhWalkOnly( aP, aNewHead );
738  case RM_Shove:
739  return rhShoveOnly( aP, aNewHead );
740  default:
741  break;
742  }
743 
744  return false;
745 }
Ignore collisions, mark obstacles
bool rhWalkOnly(const VECTOR2I &aP, LINE &aNewHead)
route step, walkaround mode
bool rhMarkObstacles(const VECTOR2I &aP, LINE &aNewHead)
route step, mark obstacles mode
bool rhShoveOnly(const VECTOR2I &aP, LINE &aNewHead)
route step, shove mode

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

Function routeStep()

Performs a single routing alorithm step, for the end point aP.

Parameters
aPending point of current route
Returns
true, if the line has been changed.

Definition at line 811 of file pns_line_placer.cpp.

812 {
813  bool fail = false;
814  bool go_back = false;
815 
816  int i, n_iter = 1;
817 
818  LINE new_head;
819 
820  wxLogTrace( "PNS", "INIT-DIR: %s head: %d, tail: %d segs",
822 
823  for( i = 0; i < n_iter; i++ )
824  {
825  if( !go_back && Settings().FollowMouse() )
826  reduceTail( aP );
827 
828  go_back = false;
829 
830  if( !routeHead( aP, new_head ) )
831  fail = true;
832 
833  if( !new_head.Is45Degree() )
834  fail = true;
835 
836  if( !Settings().FollowMouse() )
837  return;
838 
839  m_head = new_head;
840 
842  {
843  n_iter++;
844  go_back = true;
845  }
846 
847  if( !go_back && handlePullback() )
848  {
849  n_iter++;
850  go_back = true;
851  }
852 
853  }
854 
855  if( !fail )
856  {
858  return;
859 
860  mergeHead();
861  }
862 }
int SegmentCount() const
Returns the number of segments in the line
Definition: pns_line.h:155
const std::string Format() const
Function Format() Formats the direction in a human readable word.
Definition: direction45.h:101
LINE m_head
routing "head": volatile part of the track from the previously analyzed point to the current routing ...
bool reduceTail(const VECTOR2I &aEnd)
Function reduceTail()
bool handlePullback()
Function handlePullback()
bool FollowMouse() const
Returns true if follow mouse mode is active (permanently on for the moment).
ROUTING_SETTINGS & Settings() const
Returns current router settings
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
bool routeHead(const VECTOR2I &aP, LINE &aNewHead)
Function routeHead()
bool handleSelfIntersections()
Function handleSelfIntersections()
bool optimizeTailHeadTransition()
Function optimizeTailHeadTransition()
bool mergeHead()
Function mergeHead()

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

Referenced by route().

◆ SetDebugDecorator()

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

Function SetDebugDecorator.

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

Definition at line 72 of file pns_algo_base.h.

73  {
74  m_debugDecorator = aDecorator;
75  }
DEBUG_DECORATOR * m_debugDecorator
Definition: pns_algo_base.h:83

References PNS::ALGO_BASE::m_debugDecorator.

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

◆ setInitialDirection()

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

Function setInitialDirection()

Sets preferred direction of the very first track segment to be laid. Used by posture switching mechanism.

Definition at line 92 of file pns_line_placer.cpp.

93 {
94  m_initial_direction = aDirection;
95 
96  if( m_tail.SegmentCount() == 0 )
97  m_direction = aDirection;
98 }
int SegmentCount() const
Returns the number of segments in the line
Definition: pns_line.h:155
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

Function SetLayer()

Sets the current routing layer.

Reimplemented from PNS::PLACEMENT_ALGO.

Definition at line 940 of file pns_line_placer.cpp.

941 {
942  if( m_idle )
943  {
944  m_currentLayer = aLayer;
945  return true;
946  }
947  else if( m_chainedPlacement )
948  {
949  return false;
950  }
951  else if( !m_startItem || ( m_startItem->OfKind( ITEM::VIA_T ) && m_startItem->Layers().Overlaps( aLayer ) ) )
952  {
953  m_currentLayer = aLayer;
954  m_head.Line().Clear();
955  m_tail.Line().Clear();
958  Move( m_currentEnd, NULL );
959  return true;
960  }
961 
962  return false;
963 }
bool Move(const VECTOR2I &aP, ITEM *aEndItem) override
Function Move()
void SetLayer(int aLayer)
Definition: pns_item.h:154
LINE m_head
routing "head": volatile part of the track from the previously analyzed point to the current routing ...
bool Overlaps(const LAYER_RANGE &aOther) const
Definition: pns_layerset.h:68
#define NULL
LINE m_tail
routing "tail": part of the track that has been already fixed due to collisions with obstacles
SHAPE_LINE_CHAIN & Line()
Modifiable accessor to the underlying shape
Definition: pns_line.h:143
bool OfKind(int aKindMask) const
Function OfKind()
Definition: pns_item.h:133
void Clear()
Function Clear() Removes all points from the line chain.
const LAYER_RANGE & Layers() const
Definition: pns_item.h:151

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(), NULL, PNS::ITEM::OfKind(), LAYER_RANGE::Overlaps(), PNS::ITEM::SetLayer(), and PNS::ITEM::VIA_T.

◆ SetLogger()

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

Definition at line 62 of file pns_algo_base.h.

63  {
64  m_logger = aLogger;
65  }
LOGGER * m_logger
Definition: pns_algo_base.h:85

References PNS::ALGO_BASE::m_logger.

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

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

1375 {
1376  m_orthoMode = aOrthoMode;
1377 }

References m_orthoMode.

◆ Settings()

◆ setWorld()

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

Function setWorld()

Sets the board to route.

Definition at line 67 of file pns_line_placer.cpp.

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

References m_world.

Referenced by initPlacement().

◆ simplifyNewLine()

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

Function simplifyNewLine()

Assembles a line starting from segment aLatest, removes collinear segments and redundant vertexes. If a simplification bhas been found, replaces the old line with the simplified one in aNode.

Definition at line 1334 of file pns_line_placer.cpp.

1335 {
1336  LINE l = aNode->AssembleLine( aLatest );
1337  SHAPE_LINE_CHAIN simplified( l.CLine() );
1338 
1339  simplified.Simplify();
1340 
1341  if( simplified.PointCount() != l.PointCount() )
1342  {
1343  aNode->Remove( l );
1344  l.SetShape( simplified );
1345  aNode->Add( l );
1346  }
1347 }
SHAPE_LINE_CHAIN & Simplify()
Function Simplify()
void Remove(int aStartIndex, int aEndIndex)
Function Remove()
SHAPE_LINE_CHAIN.

References PNS::NODE::Add(), PNS::NODE::AssembleLine(), PNS::LINE::CLine(), PNS::LINE::PointCount(), PNS::NODE::Remove(), PNS::LINE::SetShape(), and SHAPE_LINE_CHAIN::Simplify().

Referenced by FixRoute().

◆ SplitAdjacentSegments()

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

Function SplitAdjacentSegments()

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

910 {
911  if( !aSeg )
912  return false;
913 
914  if( !aSeg->OfKind( ITEM::SEGMENT_T ) )
915  return false;
916 
917  JOINT* jt = aNode->FindJoint( aP, aSeg );
918 
919  if( jt && jt->LinkCount() >= 1 )
920  return false;
921 
922  SEGMENT* s_old = static_cast<SEGMENT*>( aSeg );
923 
924  std::unique_ptr< SEGMENT > s_new[2] = {
925  Clone( *s_old ),
926  Clone( *s_old )
927  };
928 
929  s_new[0]->SetEnds( s_old->Seg().A, aP );
930  s_new[1]->SetEnds( aP, s_old->Seg().B );
931 
932  aNode->Remove( s_old );
933  aNode->Add( std::move( s_new[0] ), true );
934  aNode->Add( std::move( s_new[1] ), true );
935 
936  return true;
937 }
std::unique_ptr< typename std::remove_const< T >::type > Clone(const T &aItem)
Definition: pns_item.h:271

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

Function Start()

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

Implements PNS::PLACEMENT_ALGO.

Definition at line 966 of file pns_line_placer.cpp.

967 {
968  m_placementCorrect = false;
969  m_currentStart = VECTOR2I( aP );
970  m_currentEnd = VECTOR2I( aP );
971  m_currentNet = std::max( 0, aStartItem ? aStartItem->Net() : 0 );
972  m_startItem = aStartItem;
973  m_placingVia = false;
974  m_chainedPlacement = false;
975  m_fixedTail.Clear();
976 
977  setInitialDirection( Settings().InitialDirection() );
978 
979  initPlacement();
980 
985 
986  NODE *n;
987 
988  if ( m_shove )
989  n = m_shove->CurrentNode();
990  else
991  n = m_currentNode;
992 
994 
995  return true;
996 }
LINE m_head
routing "head": volatile part of the track from the previously analyzed point to the current routing ...
POSTURE_SOLVER m_postureSolver
VECTOR2< int > VECTOR2I
Definition: vector2d.h:594
ROUTING_SETTINGS & Settings() const
Returns current router settings
void SetTollerance(int toll)
DIRECTION_45 m_initial_direction
routing direction for new traces
void setInitialDirection(const DIRECTION_45 &aDirection)
Function setInitialDirection()
void AddTrailPoint(const VECTOR2I &aP)
DIRECTION_45 m_direction
current routing direction
void initPlacement()
Function startPlacement()
void SetDefaultDirections(DIRECTION_45 aInitDirection, DIRECTION_45 aLastSegDir)
std::unique_ptr< SHOVE > m_shove
The shove engine
FIXED_TAIL m_fixedTail
NODE * m_currentNode
Current world state
void AddStage(VECTOR2I aStart, int aLayer, bool placingVias, DIRECTION_45 direction, NODE *aNode)
bool m_placingVia
Are we placing a via?
int Width() const
Returns line width
Definition: pns_line.h:192

References PNS::FIXED_TAIL::AddStage(), PNS::POSTURE_SOLVER::AddTrailPoint(), PNS::FIXED_TAIL::Clear(), PNS::POSTURE_SOLVER::Clear(), initPlacement(), m_chainedPlacement, m_currentEnd, m_currentLayer, m_currentNet, m_currentNode, m_currentStart, m_direction, m_fixedTail, m_head, m_initial_direction, m_placementCorrect, m_placingVia, m_postureSolver, m_shove, m_startItem, PNS::ITEM::Net(), PNS::POSTURE_SOLVER::SetDefaultDirections(), setInitialDirection(), PNS::ALGO_BASE::Settings(), PNS::POSTURE_SOLVER::SetTollerance(), DIRECTION_45::UNDEFINED, and PNS::LINE::Width().

◆ Tail()

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

Function Tail()

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

Definition at line 180 of file pns_line_placer.h.

180 { 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

Function ToggleVia()

Enables/disables a via at the end of currently routed trace.

Reimplemented from PNS::PLACEMENT_ALGO.

Definition at line 81 of file pns_line_placer.cpp.

82 {
83  m_placingVia = aEnabled;
84 
85  if( !aEnabled )
86  m_head.RemoveVia();
87 
88  return true;
89 }
LINE m_head
routing "head": volatile part of the track from the previously analyzed point to the current routing ...
void RemoveVia()
Definition: pns_line.h:237
bool m_placingVia
Are we placing a via?

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

◆ Trace()

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

Function Trace()

Returns the complete routed line.

Definition at line 876 of file pns_line_placer.cpp.

877 {
878  LINE tmp( m_head );
879 
880  tmp.SetShape( m_tail.CLine() );
881  tmp.Line().Append( m_head.CLine() );
882  tmp.Line().Simplify();
883  return tmp;
884 }
const SHAPE_LINE_CHAIN & CLine() const
Const accessor to the underlying shape
Definition: pns_line.h:149
LINE m_head
routing "head": volatile part of the track from the previously analyzed point to the current routing ...
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

Function Traces()

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

Implements PNS::PLACEMENT_ALGO.

Definition at line 887 of file pns_line_placer.cpp.

888 {
889  m_currentTrace = Trace();
890  return ITEM_SET( &m_currentTrace );
891 }
const LINE Trace() const
Function Trace()
std::unordered_set< SCH_ITEM * > ITEM_SET
Definition: sch_item.h:147

References m_currentTrace, and Trace().

◆ UnfixRoute()

bool PNS::LINE_PLACER::UnfixRoute ( )
overridevirtual

Reimplemented from PNS::PLACEMENT_ALGO.

Definition at line 1230 of file pns_line_placer.cpp.

1231 {
1232  FIXED_TAIL::STAGE st;
1233 
1234  if ( !m_fixedTail.PopStage( st ) )
1235  return false;
1236 
1237  m_head.Line().Clear();
1238  m_tail.Line().Clear();
1239  m_startItem = NULL;
1240  m_p_start = st.pts[0].p;
1241  m_direction = st.pts[0].direction;
1242  m_placingVia = st.pts[0].placingVias;
1243  m_currentNode = st.commit;
1244  m_currentLayer = st.pts[0].layer;
1247  m_head.RemoveVia( );
1248  m_tail.RemoveVia( );
1249 
1250  if (m_shove)
1251  {
1252  m_shove->RewindSpringbackTo( m_currentNode );
1253  m_shove->UnlockSpringbackNode( m_currentNode );
1254  m_currentNode = m_shove->CurrentNode();
1256  }
1257 
1259 
1260  return true;
1261 }
NODE * m_lastNode
Postprocessed world state (including marked collisions & removed loops)
void SetLayer(int aLayer)
Definition: pns_item.h:154
LINE m_head
routing "head": volatile part of the track from the previously analyzed point to the current routing ...
void RemoveVia()
Definition: pns_line.h:237
bool PopStage(STAGE &aStage)
NODE * Branch()
Function Branch()
Definition: pns_node.cpp:106
void KillChildren()
Destroys all child nodes. Applicable only to the root node.
Definition: pns_node.cpp:1288
#define NULL
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
std::unique_ptr< SHOVE > m_shove
The shove engine
FIXED_TAIL m_fixedTail
SHAPE_LINE_CHAIN & Line()
Modifiable accessor to the underlying shape
Definition: pns_line.h:143
NODE * m_currentNode
Current world state
bool m_placingVia
Are we placing a via?
void Clear()
Function Clear() Removes all points from the line chain.
VECTOR2I m_p_start
current routing start point (end of tail, beginning of head)

References PNS::NODE::Branch(), 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_lastNode, m_p_start, m_placingVia, m_shove, m_startItem, m_tail, NULL, PNS::FIXED_TAIL::PopStage(), PNS::FIXED_TAIL::STAGE::pts, PNS::LINE::RemoveVia(), and PNS::ITEM::SetLayer().

◆ updateLeadingRatLine()

void PNS::LINE_PLACER::updateLeadingRatLine ( )
private

Function updateLeadingRatLine()

Draws the "leading" ratsnest 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 1363 of file pns_line_placer.cpp.

1364 {
1365  LINE current = Trace();
1366  SHAPE_LINE_CHAIN ratLine;
1367  TOPOLOGY topo( m_lastNode );
1368 
1369  if( topo.LeadingRatLine( &current, ratLine ) )
1370  Dbg()->AddLine( ratLine, 5, 10000 );
1371 }
NODE * m_lastNode
Postprocessed world state (including marked collisions & removed loops)
virtual void AddLine(const SHAPE_LINE_CHAIN &aLine, int aType=0, int aWidth=0, const std::string aName="")
const LINE Trace() const
Function Trace()
DEBUG_DECORATOR * Dbg() const
Definition: pns_algo_base.h:77
SHAPE_LINE_CHAIN.

References PNS::DEBUG_DECORATOR::AddLine(), PNS::ALGO_BASE::Dbg(), PNS::TOPOLOGY::LeadingRatLine(), m_lastNode, and Trace().

Referenced by Move().

◆ UpdateSizes()

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

Function UpdateSizes()

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

1351 {
1352  // initPlacement will kill the tail, don't do that unless the track size has changed
1353  if( !m_idle && aSizes.TrackWidth() != m_sizes.TrackWidth() )
1354  {
1355  m_sizes = aSizes;
1356  initPlacement();
1357  }
1358 
1359  m_sizes = aSizes;
1360 }
SIZES_SETTINGS m_sizes
void initPlacement()
Function startPlacement()

References initPlacement(), m_idle, m_sizes, and PNS::SIZES_SETTINGS::TrackWidth().

Member Data Documentation

◆ m_chainedPlacement

bool PNS::LINE_PLACER::m_chainedPlacement
private

Definition at line 463 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 456 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 459 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 456 of file pns_line_placer.h.

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

◆ m_currentTrace

LINE PNS::LINE_PLACER::m_currentTrace
private

Definition at line 457 of file pns_line_placer.h.

Referenced by Traces().

◆ m_debugDecorator

DEBUG_DECORATOR* PNS::ALGO_BASE::m_debugDecorator
protectedinherited

Definition at line 83 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 467 of file pns_line_placer.h.

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

◆ m_head

LINE PNS::LINE_PLACER::m_head
private

routing "head": volatile part of the track from the previously

analyzed point to the current routing destination

Definition at line 428 of file pns_line_placer.h.

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

◆ m_idle

bool PNS::LINE_PLACER::m_idle
private

Definition at line 462 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

routing direction for new traces

Definition at line 424 of file pns_line_placer.h.

Referenced by FixRoute(), handlePullback(), handleSelfIntersections(), initPlacement(), LINE_PLACER(), reduceTail(), routeStep(), setInitialDirection(), and Start().

◆ m_lastNode

NODE* PNS::LINE_PLACER::m_lastNode
private

Postprocessed world state (including marked collisions & removed loops)

Definition at line 446 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 85 of file pns_algo_base.h.

Referenced by PNS::ALGO_BASE::SetLogger(), and PNS::WALKAROUND::singleStep().

◆ m_orthoMode

bool PNS::LINE_PLACER::m_orthoMode
private

Definition at line 464 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 point (end of tail, beginning of head)

Definition at line 437 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 465 of file pns_line_placer.h.

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

◆ m_placingVia

bool PNS::LINE_PLACER::m_placingVia
private

Are we placing a via?

Definition at line 451 of file pns_line_placer.h.

Referenced by buildInitialLine(), FixRoute(), IsPlacingVia(), LINE_PLACER(), rhShoveOnly(), rhWalkOnly(), Start(), ToggleVia(), and UnfixRoute().

◆ m_postureSolver

POSTURE_SOLVER PNS::LINE_PLACER::m_postureSolver
private

Definition at line 468 of file pns_line_placer.h.

Referenced by buildInitialLine(), FixRoute(), FlipPosture(), Move(), and Start().

◆ m_router

ROUTER* PNS::ALGO_BASE::m_router
protectedinherited

Definition at line 84 of file pns_algo_base.h.

Referenced by PNS::ALGO_BASE::Router(), and PNS::ALGO_BASE::Settings().

◆ m_shove

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

The shove engine

Definition at line 440 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 448 of file pns_line_placer.h.

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

◆ m_startItem

ITEM* PNS::LINE_PLACER::m_startItem
private

Definition at line 460 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 431 of file pns_line_placer.h.

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

◆ m_world

NODE* PNS::LINE_PLACER::m_world
private

pointer to world to search colliding items

Definition at line 434 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: