KiCad PCB EDA Suite
PNS::LINE_PLACER Class Reference

Class 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) override
 Function FixRoute() More...
 
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...
 
LOGGERLogger () override
 

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

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...
 
void SetDebugDecorator (DEBUG_DECORATOR *aDecorator)
 Function SetDebugDecorator. More...
 
DEBUG_DECORATORDbg () const
 

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, bool aInvertPosture=false)
 

Private Attributes

DIRECTION_45 m_direction
 

current routing direction

More...
 
DIRECTION_45 m_initial_direction
 

routing direction for new traces

More...
 
LINE m_head
 

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
 

Detailed Description

Class LINE_PLACER.

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

Definition at line 52 of file pns_line_placer.h.

Constructor & Destructor Documentation

PNS::LINE_PLACER::LINE_PLACER ( ROUTER aRouter)

Definition at line 37 of file pns_line_placer.cpp.

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

37  :
38  PLACEMENT_ALGO( aRouter )
39 {
41  m_world = NULL;
42  m_shove = NULL;
43  m_currentNode = NULL;
44  m_idle = true;
45 
46  // Init temporary variables (do not leave uninitialized members)
47  m_lastNode = NULL;
48  m_placingVia = false;
49  m_currentNet = 0;
50  m_currentLayer = 0;
52  m_startItem = NULL;
53  m_chainedPlacement = false;
54  m_orthoMode = false;
55 }
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
bool m_placingVia
Are we placing a via?
PLACEMENT_ALGO(ROUTER *aRouter)
PNS::LINE_PLACER::~LINE_PLACER ( )

Definition at line 58 of file pns_line_placer.cpp.

59 {
60 }

Member Function Documentation

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

Definition at line 1147 of file pns_line_placer.cpp.

References PNS::LINE::AppendVia(), DIRECTION_45::BuildInitialTrace(), SHAPE_LINE_CHAIN::Clear(), SHAPE_LINE_CHAIN::CPoint(), SHAPE_LINE_CHAIN::CSegment(), SEG::LineProject(), m_currentMode, m_currentNode, m_direction, m_orthoMode, m_p_start, m_placingVia, makeVia(), PNS::ITEM::Net(), SHAPE_LINE_CHAIN::Point(), PNS::VIA::Pos(), PNS::VIA::PushoutForce(), SHAPE_LINE_CHAIN::Remove(), DIRECTION_45::Right(), PNS::RM_MarkObstacles, PNS::RM_Walkaround, SHAPE_LINE_CHAIN::SegmentCount(), PNS::ITEM::SetNet(), PNS::VIA::SetPos(), PNS::LINE::SetShape(), and PNS::ALGO_BASE::Settings().

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

1148 {
1149  SHAPE_LINE_CHAIN l;
1150 
1151  if( m_p_start == aP )
1152  {
1153  l.Clear();
1154  }
1155  else
1156  {
1157  if( Settings().GetFreeAngleMode() && Settings().Mode() == RM_MarkObstacles )
1158  {
1159  l = SHAPE_LINE_CHAIN( m_p_start, aP );
1160  }
1161  else
1162  {
1163  if ( aInvertPosture )
1165  else
1167  }
1168 
1169  if( l.SegmentCount() > 1 && m_orthoMode )
1170  {
1171  VECTOR2I newLast = l.CSegment( 0 ).LineProject( l.CPoint( -1 ) );
1172 
1173  l.Remove( -1, -1 );
1174  l.Point( 1 ) = newLast;
1175  }
1176  }
1177 
1178  aHead.SetShape( l );
1179 
1180  if( !m_placingVia )
1181  return true;
1182 
1183  VIA v( makeVia( aP ) );
1184  v.SetNet( aHead.Net() );
1185 
1187  {
1188  aHead.AppendVia( v );
1189  return true;
1190  }
1191 
1192  VECTOR2I force;
1193  VECTOR2I lead = aP - m_p_start;
1194 
1195  bool solidsOnly = ( m_currentMode != RM_Walkaround );
1196 
1197  if( v.PushoutForce( m_currentNode, lead, force, solidsOnly, 40 ) )
1198  {
1199  SHAPE_LINE_CHAIN line = m_direction.BuildInitialTrace( m_p_start, aP + force );
1200  aHead = LINE( aHead, line );
1201 
1202  v.SetPos( v.Pos() + force );
1203  return true;
1204  }
1205 
1206  return false; // via placement unsuccessful
1207 }
VECTOR2I LineProject(const VECTOR2I &aP) const
Function LineProject()
Definition: seg.h:321
ROUTING_SETTINGS & Settings() const
Returns current router settings
const SEG CSegment(int aIndex) const
Function CSegment()
DIRECTION_45 m_direction
current routing direction
void Remove(int aStartIndex, int aEndIndex)
Function Remove()
NODE * m_currentNode
Current world state
bool m_placingVia
Are we placing a via?
Class SHAPE_LINE_CHAIN.
const DIRECTION_45 Right() const
Function Right()
Definition: direction45.h:259
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)
VECTOR2I & Point(int aIndex)
Function Point()
const SHAPE_LINE_CHAIN BuildInitialTrace(const VECTOR2I &aP0, const VECTOR2I &aP1, bool aStartDiagonal=false) const
Function BuildInitialTrace()
Definition: direction45.h:199
const VIA makeVia(const VECTOR2I &aP)
const VECTOR2I & CPoint(int aIndex) const
Function CPoint()
int SegmentCount() const
Function SegmentCount()
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 278 of file pns_line_placer.cpp.

References DIRECTION_45::IsObtuse().

279 {
280  const DIRECTION_45 dir_a( aA );
281  const DIRECTION_45 dir_b( aB );
282 
283  return dir_a.IsObtuse( dir_b ) || dir_a == dir_b;
284 }
Class DIRECTION_45.
Definition: direction45.h:33
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 136 of file pns_line_placer.h.

References m_currentEnd.

Referenced by route().

137  {
138  return m_currentEnd;
139  }
int PNS::LINE_PLACER::CurrentLayer ( ) const
inlineoverridevirtual

Function CurrentLayer()

Returns the layer of currently routed track.

Implements PNS::PLACEMENT_ALGO.

Definition at line 156 of file pns_line_placer.h.

References m_currentLayer.

157  {
158  return m_currentLayer;
159  }
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 146 of file pns_line_placer.h.

References m_currentNet.

147  {
148  return std::vector<int>( 1, m_currentNet );
149  }
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 792 of file pns_line_placer.cpp.

References m_currentNode, and m_lastNode.

793 {
794  if( aLoopsRemoved && m_lastNode )
795  return m_lastNode;
796 
797  return m_currentNode;
798 }
NODE * m_lastNode
Postprocessed world state (including marked collisions & removed loops)
NODE * m_currentNode
Current world state
bool PNS::LINE_PLACER::FixRoute ( const VECTOR2I aP,
ITEM aEndItem 
)
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 964 of file pns_line_placer.cpp.

References PNS::NODE::Add(), PNS::NODE::CheckColliding(), PNS::LINE::CLine(), PNS::Clone(), PNS::ROUTER::CommitRouting(), SHAPE_LINE_CHAIN::CPoint(), PNS::LINE::CSegment(), SHAPE_LINE_CHAIN::CSegment(), PNS::LINE::EndsWithVia(), initPlacement(), m_chainedPlacement, m_currentLayer, m_currentMode, m_currentNet, m_currentNode, m_currentStart, m_idle, m_lastNode, m_placingVia, m_startItem, m_world, max, PNS::ITEM::Net(), SHAPE_LINE_CHAIN::PointCount(), PNS::RM_MarkObstacles, PNS::ALGO_BASE::Router(), SHAPE_LINE_CHAIN::SegmentCount(), setInitialDirection(), PNS::ALGO_BASE::Settings(), simplifyNewLine(), Trace(), PNS::LINE::Via(), and PNS::LINE::Width().

965 {
966  bool realEnd = false;
967  int lastV;
968 
969  LINE pl = Trace();
970 
972  !Settings().CanViolateDRC() &&
973  m_world->CheckColliding( &pl ) )
974  return false;
975 
976  const SHAPE_LINE_CHAIN& l = pl.CLine();
977 
978  if( !l.SegmentCount() )
979  {
980  if( pl.EndsWithVia() )
981  {
982  m_lastNode->Add( Clone( pl.Via() ) );
984 
985  m_lastNode = NULL;
986  m_currentNode = NULL;
987 
988  m_idle = true;
989  }
990 
991  return true;
992  }
993 
994  VECTOR2I p_pre_last = l.CPoint( -1 );
995  const VECTOR2I p_last = l.CPoint( -1 );
996  DIRECTION_45 d_last( l.CSegment( -1 ) );
997 
998  if( l.PointCount() > 2 )
999  p_pre_last = l.CPoint( -2 );
1000 
1001  if( aEndItem && m_currentNet >= 0 && m_currentNet == aEndItem->Net() )
1002  realEnd = true;
1003 
1004  if( realEnd || m_placingVia )
1005  lastV = l.SegmentCount();
1006  else
1007  lastV = std::max( 1, l.SegmentCount() - 1 );
1008 
1009  SEGMENT* lastSeg = NULL;
1010 
1011  for( int i = 0; i < lastV; i++ )
1012  {
1013  const SEG& s = pl.CSegment( i );
1014  std::unique_ptr< SEGMENT > seg( new SEGMENT( s, m_currentNet ) );
1015  seg->SetWidth( pl.Width() );
1016  seg->SetLayer( m_currentLayer );
1017  lastSeg = seg.get();
1018  m_lastNode->Add( std::move( seg ) );
1019  }
1020 
1021  if( pl.EndsWithVia() )
1022  m_lastNode->Add( Clone( pl.Via() ) );
1023 
1024  if( realEnd )
1025  simplifyNewLine( m_lastNode, lastSeg );
1026 
1028 
1029  m_lastNode = NULL;
1030  m_currentNode = NULL;
1031 
1032  if( !realEnd )
1033  {
1034  setInitialDirection( d_last );
1035  m_currentStart = m_placingVia ? p_last : p_pre_last;
1036  m_startItem = NULL;
1037  m_placingVia = false;
1038  m_chainedPlacement = !pl.EndsWithVia();
1039  initPlacement();
1040  }
1041  else
1042  {
1043  m_idle = true;
1044  }
1045 
1046  return realEnd;
1047 }
NODE * m_lastNode
Postprocessed world state (including marked collisions & removed loops)
NODE * m_world
pointer to world to search colliding items
int PointCount() const
Function PointCount()
ROUTING_SETTINGS & Settings() const
Returns current router settings
void simplifyNewLine(NODE *aNode, SEGMENT *aLatest)
Function simplifyNewLine()
const SEG CSegment(int aIndex) const
Function CSegment()
void setInitialDirection(const DIRECTION_45 &aDirection)
Function setInitialDirection()
Class DIRECTION_45.
Definition: direction45.h:33
void initPlacement()
Function startPlacement()
ROUTER * Router() const
Returns the instance of our router
Definition: pns_algo_base.h:49
std::unique_ptr< typename std::remove_const< T >::type > Clone(const T &aItem)
Definition: pns_item.h:367
Definition: seg.h:36
NODE * m_currentNode
Current world state
void CommitRouting(NODE *aNode)
Definition: pns_router.cpp:326
#define max(a, b)
Definition: auxiliary.h:86
bool m_placingVia
Are we placing a via?
Class SHAPE_LINE_CHAIN.
OPT_OBSTACLE CheckColliding(const ITEM *aItem, int aKindMask=ITEM::ANY_T)
Function CheckColliding()
Definition: pns_node.cpp:425
Struct SEGMENT is a simple container used when filling areas with segments.
Definition: class_zone.h:57
const VECTOR2I & CPoint(int aIndex) const
Function CPoint()
void Add(std::unique_ptr< SEGMENT > aSegment, bool aAllowRedundant=false)
Function Add()
Definition: pns_node.cpp:594
int SegmentCount() const
Function SegmentCount()
const LINE Trace() const
Function Trace()
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 785 of file pns_line_placer.cpp.

References m_direction, m_initial_direction, and DIRECTION_45::Right().

786 {
789 }
DIRECTION_45 m_initial_direction
routing direction for new traces
DIRECTION_45 m_direction
current routing direction
const DIRECTION_45 Right() const
Function Right()
Definition: direction45.h:259
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 1210 of file pns_line_placer.cpp.

References m_currentNet.

1211 {
1212  aNets.push_back( m_currentNet );
1213 }
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 157 of file pns_line_placer.cpp.

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

158 {
159  SHAPE_LINE_CHAIN& head = m_head.Line();
160  SHAPE_LINE_CHAIN& tail = m_tail.Line();
161 
162  if( head.PointCount() < 2 )
163  return false;
164 
165  int n = tail.PointCount();
166 
167  if( n == 0 )
168  return false;
169  else if( n == 1 )
170  {
171  m_p_start = tail.CPoint( 0 );
172  tail.Clear();
173  return true;
174  }
175 
176  DIRECTION_45 first_head( head.CSegment( 0 ) );
177  DIRECTION_45 last_tail( tail.CSegment( -1 ) );
178  DIRECTION_45::AngleType angle = first_head.Angle( last_tail );
179 
180  // case 1: we have a defined routing direction, and the currently computed
181  // head goes in different one.
182  bool pullback_1 = false; // (m_direction != DIRECTION_45::UNDEFINED && m_direction != first_head);
183 
184  // case 2: regardless of the current routing direction, if the tail/head
185  // extremities form an acute or right angle, reduce the tail by one segment
186  // (and hope that further iterations) will result with a cleaner trace
187  bool pullback_2 = ( angle == DIRECTION_45::ANG_RIGHT || angle == DIRECTION_45::ANG_ACUTE );
188 
189  if( pullback_1 || pullback_2 )
190  {
191  const SEG last = tail.CSegment( -1 );
192  m_direction = DIRECTION_45( last );
193  m_p_start = last.A;
194 
195  wxLogTrace( "PNS", "Placer: pullback triggered [%d] [%s %s]",
196  n, last_tail.Format().c_str(), first_head.Format().c_str() );
197 
198  // erase the last point in the tail, hoping that the next iteration will
199  // result with a head trace that starts with a segment following our
200  // current direction.
201  if( n < 2 )
202  tail.Clear(); // don't leave a single-point tail
203  else
204  tail.Remove( -1, -1 );
205 
206  if( !tail.SegmentCount() )
208 
209  return true;
210  }
211 
212  return false;
213 }
int PointCount() const
Function PointCount()
LINE m_head
routing "head": volatile part of the track from the previously analyzed point to the current routing ...
const SEG CSegment(int aIndex) const
Function CSegment()
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 ...
Class DIRECTION_45.
Definition: direction45.h:33
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:117
Definition: seg.h:36
AngleType
Enum AngleType Represents kind of angle formed by vectors heading in two DIRECTION_45s.
Definition: direction45.h:59
Class SHAPE_LINE_CHAIN.
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
VECTOR2I A
Definition: seg.h:46
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 VECTOR2I & CPoint(int aIndex) const
Function CPoint()
int SegmentCount() const
Function SegmentCount()
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 97 of file pns_line_placer.cpp.

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::Point(), SHAPE_LINE_CHAIN::PointCount(), and SHAPE_LINE_CHAIN::Remove().

Referenced by routeStep().

98 {
100  SHAPE_LINE_CHAIN& head = m_head.Line();
101  SHAPE_LINE_CHAIN& tail = m_tail.Line();
102 
103  // if there is no tail, there is nothing to intersect with
104  if( tail.PointCount() < 2 )
105  return false;
106 
107  tail.Intersect( head, ips );
108 
109  // no intesection points - nothing to reduce
110  if( ips.empty() )
111  return false;
112 
113  int n = INT_MAX;
114  VECTOR2I ipoint;
115 
116  // if there is more than one intersection, find the one that is
117  // closest to the beginning of the tail.
118  for( SHAPE_LINE_CHAIN::INTERSECTION i : ips )
119  {
120  if( i.our.Index() < n )
121  {
122  n = i.our.Index();
123  ipoint = i.p;
124  }
125  }
126 
127  // ignore the point where head and tail meet
128  if( ipoint == head.CPoint( 0 ) || ipoint == tail.CPoint( -1 ) )
129  return false;
130 
131  // Intersection point is on the first or the second segment: just start routing
132  // from the beginning
133  if( n < 2 )
134  {
135  m_p_start = tail.Point( 0 );
137  tail.Clear();
138  head.Clear();
139 
140  return true;
141  }
142  else
143  {
144  // Clip till the last tail segment before intersection.
145  // Set the direction to the one of this segment.
146  const SEG last = tail.CSegment( n - 1 );
147  m_p_start = last.A;
148  m_direction = DIRECTION_45( last );
149  tail.Remove( n, -1 );
150  return true;
151  }
152 
153  return false;
154 }
std::vector< INTERSECTION > INTERSECTIONS
int PointCount() const
Function PointCount()
LINE m_head
routing "head": volatile part of the track from the previously analyzed point to the current routing ...
int Intersect(const SEG &aSeg, INTERSECTIONS &aIp) const
Function Intersect()
const SEG CSegment(int aIndex) const
Function CSegment()
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 ...
Class DIRECTION_45.
Definition: direction45.h:33
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:117
Definition: seg.h:36
Class SHAPE_LINE_CHAIN.
VECTOR2I A
Definition: seg.h:46
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)
VECTOR2I & Point(int aIndex)
Function Point()
const VECTOR2I & CPoint(int aIndex) const
Function CPoint()
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 106 of file pns_line_placer.h.

References m_head.

106 { return m_head; }
LINE m_head
routing "head": volatile part of the track from the previously analyzed point to the current routing ...
void PNS::LINE_PLACER::initPlacement ( )
private

Function startPlacement()

Initializes placement of a new line with given parameters.

Definition at line 881 of file pns_line_placer.cpp.

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 FixRoute(), SetLayer(), Start(), and UpdateSizes().

882 {
883  m_idle = false;
884 
885  m_head.Line().Clear();
886  m_tail.Line().Clear();
893  m_head.RemoveVia();
894  m_tail.RemoveVia();
895 
898 
899  NODE* world = Router()->GetWorld();
900 
901  world->KillChildren();
902  NODE* rootNode = world->Branch();
903 
905 
906  setWorld( rootNode );
907 
908  wxLogTrace( "PNS", "world %p, intitial-direction %s layer %d",
910 
911  m_lastNode = NULL;
914 
915  m_shove.reset();
916 
918  {
919  m_shove.reset( new SHOVE( m_world->Branch(), Router() ) );
920  }
921 }
PNS_MODE Mode() const
Returns the routing mode.
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)
Function SetLayer()
Definition: pns_item.h:197
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:251
SIZES_SETTINGS m_sizes
ROUTING_SETTINGS & Settings() const
Returns current router settings
NODE * Branch()
Function Branch()
Definition: pns_node.cpp:107
NODE * GetWorld() const
Definition: pns_router.h:143
void SetWidth(int aWidth)
Sets line width
Definition: pns_line.h:153
void SetNet(int aNet)
Function SetNet()
Definition: pns_item.h:167
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:1225
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
ROUTER * Router() const
Returns the instance of our router
Definition: pns_algo_base.h:49
std::unique_ptr< SHOVE > m_shove
The shove engine
SHAPE_LINE_CHAIN & Line()
Modifiable accessor to the underlying shape
Definition: pns_line.h:117
Only walkaround
NODE * m_currentNode
Current world state
void setWorld(NODE *aWorld)
Function setWorld()
const std::string Format() const
Function Format() Formats the direction in a human readable word.
Definition: direction45.h:94
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 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 186 of file pns_line_placer.h.

References m_placingVia.

186 { return m_placingVia; }
bool m_placingVia
Are we placing a via?
LOGGER * PNS::LINE_PLACER::Logger ( )
overridevirtual

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

Reimplemented from PNS::ALGO_BASE.

Definition at line 1215 of file pns_line_placer.cpp.

References m_shove.

1216 {
1217  if( m_shove )
1218  return m_shove->Logger();
1219 
1220  return NULL;
1221 }
std::unique_ptr< SHOVE > m_shove
The shove engine
const VIA PNS::LINE_PLACER::makeVia ( const VECTOR2I aP)
private
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 287 of file pns_line_placer.cpp.

References SEG::A, 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().

288 {
289  SHAPE_LINE_CHAIN& head = m_head.Line();
290  SHAPE_LINE_CHAIN& tail = m_tail.Line();
291 
292  const int ForbiddenAngles = DIRECTION_45::ANG_ACUTE |
295 
296  head.Simplify();
297  tail.Simplify();
298 
299  int n_head = head.SegmentCount();
300  int n_tail = tail.SegmentCount();
301 
302  if( n_head < 3 )
303  {
304  wxLogTrace( "PNS", "Merge failed: not enough head segs." );
305  return false;
306  }
307 
308  if( n_tail && head.CPoint( 0 ) != tail.CPoint( -1 ) )
309  {
310  wxLogTrace( "PNS", "Merge failed: head and tail discontinuous." );
311  return false;
312  }
313 
314  if( m_head.CountCorners( ForbiddenAngles ) != 0 )
315  return false;
316 
317  DIRECTION_45 dir_tail, dir_head;
318 
319  dir_head = DIRECTION_45( head.CSegment( 0 ) );
320 
321  if( n_tail )
322  {
323  dir_tail = DIRECTION_45( tail.CSegment( -1 ) );
324 
325  if( dir_head.Angle( dir_tail ) & ForbiddenAngles )
326  return false;
327  }
328 
329  if( !n_tail )
330  tail.Append( head.CSegment( 0 ).A );
331 
332  for( int i = 0; i < n_head - 2; i++ )
333  {
334  tail.Append( head.CSegment( i ).B );
335  }
336 
337  tail.Simplify();
338 
339  SEG last = tail.CSegment( -1 );
340 
341  m_p_start = last.B;
342  m_direction = DIRECTION_45( last ).Right();
343 
344  head.Remove( 0, n_head - 2 );
345 
346  wxLogTrace( "PNS", "Placer: merge %d, new direction: %s", n_head, m_direction.Format().c_str() );
347 
348  head.Simplify();
349  tail.Simplify();
350 
351  return true;
352 }
LINE m_head
routing "head": volatile part of the track from the previously analyzed point to the current routing ...
void Append(int aX, int aY, bool aAllowDuplication=false)
Function Append()
SHAPE_LINE_CHAIN & Simplify()
Function Simplify()
int CountCorners(int aAngles) const
Returns the number of corners of angles specified by mask aAngles.
Definition: pns_line.cpp:136
const SEG CSegment(int aIndex) const
Function CSegment()
LINE m_tail
routing "tail": part of the track that has been already fixed due to collisions with obstacles ...
Class DIRECTION_45.
Definition: direction45.h:33
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:117
Definition: seg.h:36
const std::string Format() const
Function Format() Formats the direction in a human readable word.
Definition: direction45.h:94
Class SHAPE_LINE_CHAIN.
VECTOR2I A
Definition: seg.h:46
AngleType Angle(const DIRECTION_45 &aOther) const
Function Angle() Returns the type of angle between directions (this) and aOther.
Definition: direction45.h:146
const DIRECTION_45 Right() const
Function Right()
Definition: direction45.h:259
VECTOR2I m_p_start
current routing start point (end of tail, beginning of head)
const VECTOR2I & CPoint(int aIndex) const
Function CPoint()
int SegmentCount() const
Function SegmentCount()
VECTOR2I B
Definition: seg.h:47
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 924 of file pns_line_placer.cpp.

References 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, 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().

925 {
926  LINE current;
927  VECTOR2I p = aP;
928  int eiDepth = -1;
929 
930  if( aEndItem && aEndItem->Owner() )
931  eiDepth = static_cast<NODE*>( aEndItem->Owner() )->Depth();
932 
933  if( m_lastNode )
934  {
935  delete m_lastNode;
936  m_lastNode = NULL;
937  }
938 
939  route( p );
940 
941  current = Trace();
942 
943  if( !current.PointCount() )
945  else
946  m_currentEnd = current.CLine().CPoint( -1 );
947 
948  NODE* latestNode = m_currentNode;
949  m_lastNode = latestNode->Branch();
950 
951  if( eiDepth >= 0 && aEndItem && latestNode->Depth() > eiDepth && current.SegmentCount() )
952  {
953  SplitAdjacentSegments( m_lastNode, aEndItem, current.CPoint( -1 ) );
954 
955  if( Settings().RemoveLoops() )
956  removeLoops( m_lastNode, current );
957  }
958 
960  return true;
961 }
NODE * m_lastNode
Postprocessed world state (including marked collisions & removed loops)
void removeLoops(NODE *aNode, LINE &aLatest)
Function removeLoops()
ROUTING_SETTINGS & Settings() const
Returns current router settings
NODE * Branch()
Function Branch()
Definition: pns_node.cpp:107
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
bool RemoveLoops() const
Returns true if loop (redundant track) removal is on.
VECTOR2I m_p_start
current routing start point (end of tail, beginning of head)
const LINE Trace() const
Function Trace()
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 644 of file pns_line_placer.cpp.

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, min, 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().

645 {
646  LINE linetmp = Trace();
647 
649  {
650  if( linetmp.SegmentCount() < 1 )
651  return false;
652 
653  m_head = linetmp;
654  m_p_start = linetmp.CLine().CPoint( 0 );
655  m_direction = DIRECTION_45( linetmp.CSegment( 0 ) );
656  m_tail.Line().Clear();
657 
658  return true;
659  }
660 
661  SHAPE_LINE_CHAIN& head = m_head.Line();
662  SHAPE_LINE_CHAIN& tail = m_tail.Line();
663 
664  int tailLookbackSegments = 3;
665 
666  //if(m_currentMode() == RM_Walkaround)
667  // tailLookbackSegments = 10000;
668 
669  int threshold = std::min( tail.PointCount(), tailLookbackSegments + 1 );
670 
671  if( tail.SegmentCount() < 3 )
672  return false;
673 
674  // assemble TailLookbackSegments tail segments with the current head
675  SHAPE_LINE_CHAIN opt_line = tail.Slice( -threshold, -1 );
676 
677  int end = std::min(2, head.PointCount() - 1 );
678 
679  opt_line.Append( head.Slice( 0, end ) );
680 
681  LINE new_head( m_tail, opt_line );
682 
683  // and see if it could be made simpler by merging obtuse/collnear segments.
684  // If so, replace the (threshold) last tail points and the head with
685  // the optimized line
686 
688  {
689  LINE tmp( m_tail, opt_line );
690 
691  wxLogTrace( "PNS", "Placer: optimize tail-head [%d]", threshold );
692 
693  head.Clear();
694  tail.Replace( -threshold, -1, new_head.CLine() );
695  tail.Simplify();
696 
697  m_p_start = new_head.CLine().CPoint( -1 );
698  m_direction = DIRECTION_45( new_head.CSegment( -1 ) );
699 
700  return true;
701  }
702 
703  return false;
704 }
int PointCount() const
Function PointCount()
LINE m_head
routing "head": volatile part of the track from the previously analyzed point to the current routing ...
const SHAPE_LINE_CHAIN Slice(int aStartIndex, int aEndIndex=-1) const
Function Slice()
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 ...
Class DIRECTION_45.
Definition: direction45.h:33
DIRECTION_45 m_direction
current routing direction
SHAPE_LINE_CHAIN & Line()
Modifiable accessor to the underlying shape
Definition: pns_line.h:117
NODE * m_currentNode
Current world state
Class 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()
static bool Optimize(LINE *aLine, int aEffortLevel, NODE *aWorld)
a quick shortcut to optmize a line without creating and setting up an optimizer
int SegmentCount() const
Function SegmentCount()
const LINE Trace() const
Function Trace()
#define min(a, b)
Definition: auxiliary.h:85
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 216 of file pns_line_placer.cpp.

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

217 {
218  SHAPE_LINE_CHAIN& head = m_head.Line();
219  SHAPE_LINE_CHAIN& tail = m_tail.Line();
220 
221  int n = tail.SegmentCount();
222 
223  if( head.SegmentCount() < 1 )
224  return false;
225 
226  // Don't attempt this for too short tails
227  if( n < 2 )
228  return false;
229 
230  // Start from the segment farthest from the end of the tail
231  // int start_index = std::max(n - 1 - ReductionDepth, 0);
232 
233  DIRECTION_45 new_direction;
234  VECTOR2I new_start;
235  int reduce_index = -1;
236 
237  for( int i = tail.SegmentCount() - 1; i >= 0; i-- )
238  {
239  const SEG s = tail.CSegment( i );
240  DIRECTION_45 dir( s );
241 
242  // calculate a replacement route and check if it matches
243  // the direction of the segment to be replaced
244  SHAPE_LINE_CHAIN replacement = dir.BuildInitialTrace( s.A, aEnd );
245 
246  LINE tmp( m_tail, replacement );
247 
249  break;
250 
251  if( DIRECTION_45( replacement.CSegment( 0 ) ) == dir )
252  {
253  new_start = s.A;
254  new_direction = dir;
255  reduce_index = i;
256  }
257  }
258 
259  if( reduce_index >= 0 )
260  {
261  wxLogTrace( "PNS", "Placer: reducing tail: %d", reduce_index );
262  SHAPE_LINE_CHAIN reducedLine = new_direction.BuildInitialTrace( new_start, aEnd );
263 
264  m_p_start = new_start;
265  m_direction = new_direction;
266  tail.Remove( reduce_index + 1, -1 );
267  head.Clear();
268  return true;
269  }
270 
271  if( !tail.SegmentCount() )
273 
274  return false;
275 }
LINE m_head
routing "head": volatile part of the track from the previously analyzed point to the current routing ...
const SEG CSegment(int aIndex) const
Function CSegment()
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 ...
Class DIRECTION_45.
Definition: direction45.h:33
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:117
Definition: seg.h:36
NODE * m_currentNode
Current world state
Class SHAPE_LINE_CHAIN.
OPT_OBSTACLE CheckColliding(const ITEM *aItem, int aKindMask=ITEM::ANY_T)
Function CheckColliding()
Definition: pns_node.cpp:425
VECTOR2I A
Definition: seg.h:46
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 SHAPE_LINE_CHAIN BuildInitialTrace(const VECTOR2I &aP0, const VECTOR2I &aP1, bool aStartDiagonal=false) const
Function BuildInitialTrace()
Definition: direction45.h:199
int SegmentCount() const
Function SegmentCount()
const LINE PNS::LINE_PLACER::reduceToNearestObstacle ( const LINE aOriginalLine)
private

Definition at line 437 of file pns_line_placer.cpp.

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

438 {
439  auto l0 = aOriginalLine.CLine();
440 
441  if ( !l0.PointCount() )
442  return aOriginalLine;
443 
444  int l = l0.Length();
445  int step = l / 2;
446  VECTOR2I target;
447 
448  LINE l_test( aOriginalLine );
449 
450  while( step > 0 )
451  {
452  target = l0.PointAlong( l );
453  SHAPE_LINE_CHAIN l_cur( l0 );
454 
455  int index = l_cur.Split( target );
456 
457  l_test.SetShape( l_cur.Slice( 0, index ) );
458 
459  if ( m_currentNode->CheckColliding( &l_test ) )
460  l -= step;
461  else
462  l += step;
463 
464  step /= 2;
465  }
466 
467  l = l_test.CLine().Length();
468 
469  while( m_currentNode->CheckColliding( &l_test ) && l > 0 )
470  {
471  l--;
472  target = l0.PointAlong( l );
473  SHAPE_LINE_CHAIN l_cur( l0 );
474 
475  int index = l_cur.Split( target );
476 
477  l_test.SetShape( l_cur.Slice( 0, index ) );
478  }
479 
480  return l_test;
481 }
NODE * m_currentNode
Current world state
Class SHAPE_LINE_CHAIN.
OPT_OBSTACLE CheckColliding(const ITEM *aItem, int aKindMask=ITEM::ANY_T)
Function CheckColliding()
Definition: pns_node.cpp:425
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 1050 of file pns_line_placer.cpp.

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

Referenced by Move().

1051 {
1052  if( !aLatest.SegmentCount() )
1053  return;
1054 
1055  if( aLatest.CLine().CPoint( 0 ) == aLatest.CLine().CPoint( -1 ) )
1056  return;
1057 
1058  std::set<SEGMENT *> toErase;
1059  aNode->Add( aLatest, true );
1060 
1061  for( int s = 0; s < aLatest.LinkCount(); s++ )
1062  {
1063  SEGMENT* seg = aLatest.GetLink(s);
1064  LINE ourLine = aNode->AssembleLine( seg );
1065  JOINT a, b;
1066  std::vector<LINE> lines;
1067 
1068  aNode->FindLineEnds( ourLine, a, b );
1069 
1070  if( a == b )
1071  {
1072  aNode->FindLineEnds( aLatest, a, b );
1073  }
1074 
1075  aNode->FindLinesBetweenJoints( a, b, lines );
1076 
1077  int removedCount = 0;
1078  int total = 0;
1079 
1080  for( LINE& line : lines )
1081  {
1082  total++;
1083 
1084  if( !( line.ContainsSegment( seg ) ) && line.SegmentCount() )
1085  {
1086  for( SEGMENT *ss : line.LinkedSegments() )
1087  toErase.insert( ss );
1088 
1089  removedCount++;
1090  }
1091  }
1092 
1093  wxLogTrace( "PNS", "total segs removed: %d/%d", removedCount, total );
1094  }
1095 
1096  for( SEGMENT *s : toErase )
1097  aNode->Remove( s );
1098 
1099  aNode->Remove( aLatest );
1100 }
Struct SEGMENT is a simple container used when filling areas with segments.
Definition: class_zone.h:57
bool PNS::LINE_PLACER::rhMarkObstacles ( const VECTOR2I aP,
LINE aNewHead 
)
private

route step, mark obstacles mode

Definition at line 411 of file pns_line_placer.cpp.

References PNS::DEBUG_DECORATOR::AddLine(), buildInitialLine(), PNS::NODE::CheckColliding(), PNS::ALGO_BASE::Dbg(), EuclideanNorm(), PNS::NODE::GetClearance(), m_currentNode, m_head, PNS::NODE::NearestObstacle(), and PNS::LINE::Width().

Referenced by routeHead().

412 {
413  buildInitialLine( aP, m_head );
414 
415  auto obs = m_currentNode->NearestObstacle( &m_head );
416 
417  if( obs )
418  {
419  int cl = m_currentNode->GetClearance( obs->m_item, &m_head );
420  auto hull = obs->m_item->Hull( cl, m_head.Width() );
421 
422  auto nearest = hull.NearestPoint( aP );
423  Dbg()->AddLine( hull, 2, 10000 );
424 
425  if( ( nearest - aP ).EuclideanNorm() < m_head.Width() )
426  {
427  buildInitialLine( nearest, m_head );
428  }
429  }
430 
431  aNewHead = m_head;
432 
433  return static_cast<bool>( m_currentNode->CheckColliding( &m_head ) );
434 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:112
OPT_OBSTACLE NearestObstacle(const LINE *aItem, int aKindMask=ITEM::ANY_T, const std::set< ITEM * > *aRestrictedSet=NULL)
Function NearestObstacle()
Definition: pns_node.cpp:302
DEBUG_DECORATOR * Dbg() const
Definition: pns_algo_base.h:70
LINE m_head
routing "head": volatile part of the track from the previously analyzed point to the current routing ...
int Width() const
Returns line width
Definition: pns_line.h:159
virtual void AddLine(const SHAPE_LINE_CHAIN &aLine, int aType=0, int aWidth=0)
bool buildInitialLine(const VECTOR2I &aP, LINE &aHead, bool aInvertPosture=false)
NODE * m_currentNode
Current world state
int GetClearance(const ITEM *aA, const ITEM *aB) const
Returns the expected clearance between items a and b.
Definition: pns_node.cpp:98
OPT_OBSTACLE CheckColliding(const ITEM *aItem, int aKindMask=ITEM::ANY_T)
Function CheckColliding()
Definition: pns_node.cpp:425
bool PNS::LINE_PLACER::rhShoveOnly ( const VECTOR2I aP,
LINE aNewHead 
)
private

route step, shove mode

Definition at line 536 of file pns_line_placer.cpp.

References PNS::ITEM::ANY_T, SHAPE_LINE_CHAIN::Append(), PNS::LINE::AppendVia(), buildInitialLine(), PNS::LINE::CLine(), PNS::LINE::ClipToNearestObstacle(), PNS::LINE::CPoint(), PNS::WALKAROUND::DONE, PNS::LINE::HasLoops(), PNS::LINE::Line(), 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::OPTIMIZER::SetEffortLevel(), PNS::WALKAROUND::SetIterationLimit(), PNS::WALKAROUND::SetSolidsOnly(), 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().

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

Definition at line 484 of file pns_line_placer.cpp.

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

485 {
486  LINE l0;
487  l0 = m_head;
488 
489  buildInitialLine( aP, l0 );
490 
491  LINE l_cur = reduceToNearestObstacle( l0 );
492 
493  const auto l_shape = l_cur.CLine();
494 
495  if( l_shape.SegmentCount() == 0 )
496  {
497  return false;
498  }
499 
500  if( l_shape.SegmentCount() == 1 )
501  {
502  auto s = l_shape.CSegment( 0 );
503 
504  VECTOR2I dL( DIRECTION_45( s ).Left().ToVector() );
505  VECTOR2I dR( DIRECTION_45( s ).Right().ToVector() );
506 
507  SEG leadL( s.B, s.B + dL );
508  SEG leadR( s.B, s.B + dR );
509 
510  SEG segL( s.B, leadL.LineProject( aP ) );
511  SEG segR( s.B, leadR.LineProject( aP ) );
512 
513  LINE finishL( l0, SHAPE_LINE_CHAIN( segL.A, segL.B ) );
514  LINE finishR( l0, SHAPE_LINE_CHAIN( segR.A, segR.B ) );
515 
516  LINE reducedL = reduceToNearestObstacle( finishL );
517  LINE reducedR = reduceToNearestObstacle( finishR );
518 
519  int lL = reducedL.CLine().Length();
520  int lR = reducedR.CLine().Length();
521 
522  if( lL > lR )
523  l_cur.Line().Append( reducedL.CLine() );
524  else
525  l_cur.Line().Append( reducedR.CLine() );
526 
527  l_cur.Line().Simplify();
528  }
529 
530  m_head = l_cur;
531  aNewHead = m_head;
532  return true;
533 }
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 ...
Class DIRECTION_45.
Definition: direction45.h:33
bool buildInitialLine(const VECTOR2I &aP, LINE &aHead, bool aInvertPosture=false)
Definition: seg.h:36
Class SHAPE_LINE_CHAIN.
bool PNS::LINE_PLACER::rhWalkOnly ( const VECTOR2I aP,
LINE aNewHead 
)
private

route step, walkaround mode

Definition at line 355 of file pns_line_placer.cpp.

References PNS::LINE::AppendVia(), buildInitialLine(), PNS::NODE::CheckColliding(), PNS::LINE::ClipToNearestObstacle(), PNS::LINE::CPoint(), m_currentNode, m_head, m_placingVia, makeVia(), PNS::OPTIMIZER::MERGE_SEGMENTS, PNS::OE_FULL, PNS::OE_LOW, PNS::OE_MEDIUM, PNS::OPTIMIZER::Optimize(), PNS::WALKAROUND::Route(), PNS::ALGO_BASE::Router(), PNS::WALKAROUND::SetIterationLimit(), PNS::WALKAROUND::SetSolidsOnly(), PNS::ALGO_BASE::Settings(), PNS::OPTIMIZER::SMART_PADS, and PNS::WALKAROUND::STUCK.

Referenced by routeHead().

356 {
357  LINE initTrack( m_head );
358  LINE walkFull;
359  int effort = 0;
360  bool rv = true, viaOk;
361 
362  viaOk = buildInitialLine( aP, initTrack );
363 
364  WALKAROUND walkaround( m_currentNode, Router() );
365 
366  walkaround.SetSolidsOnly( false );
367  walkaround.SetIterationLimit( Settings().WalkaroundIterationLimit() );
368 
369  WALKAROUND::WALKAROUND_STATUS wf = walkaround.Route( initTrack, walkFull, false );
370 
371  switch( Settings().OptimizerEffort() )
372  {
373  case OE_LOW:
374  effort = 0;
375  break;
376 
377  case OE_MEDIUM:
378  case OE_FULL:
379  effort = OPTIMIZER::MERGE_SEGMENTS;
380  break;
381  }
382 
383  if( Settings().SmartPads() )
384  effort |= OPTIMIZER::SMART_PADS;
385 
386  if( wf == WALKAROUND::STUCK )
387  {
388  walkFull = walkFull.ClipToNearestObstacle( m_currentNode );
389  rv = true;
390  }
391  else if( m_placingVia && viaOk )
392  {
393  walkFull.AppendVia( makeVia( walkFull.CPoint( -1 ) ) );
394  }
395 
396  OPTIMIZER::Optimize( &walkFull, effort, m_currentNode );
397 
398  if( m_currentNode->CheckColliding( &walkFull ) )
399  {
400  aNewHead = m_head;
401  return false;
402  }
403 
404  m_head = walkFull;
405  aNewHead = walkFull;
406 
407  return rv;
408 }
LINE m_head
routing "head": volatile part of the track from the previously analyzed point to the current routing ...
ROUTING_SETTINGS & Settings() const
Returns current router settings
bool buildInitialLine(const VECTOR2I &aP, LINE &aHead, bool aInvertPosture=false)
ROUTER * Router() const
Returns the instance of our router
Definition: pns_algo_base.h:49
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:425
static bool Optimize(LINE *aLine, int aEffortLevel, NODE *aWorld)
a quick shortcut to optmize a line without creating and setting up an optimizer
const VIA makeVia(const VECTOR2I &aP)
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 760 of file pns_line_placer.cpp.

References CurrentEnd(), and routeStep().

Referenced by Move().

761 {
762  routeStep( aP );
763  return CurrentEnd() == aP;
764 }
void routeStep(const VECTOR2I &aP)
Function routeStep()
const VECTOR2I & CurrentEnd() const override
Function CurrentEnd()
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 626 of file pns_line_placer.cpp.

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

Referenced by routeStep().

627 {
628  switch( m_currentMode )
629  {
630  case RM_MarkObstacles:
631  return rhMarkObstacles( aP, aNewHead );
632  case RM_Walkaround:
633  return rhWalkOnly( aP, aNewHead );
634  case RM_Shove:
635  return rhShoveOnly( aP, aNewHead );
636  default:
637  break;
638  }
639 
640  return false;
641 }
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
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 707 of file pns_line_placer.cpp.

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

708 {
709  bool fail = false;
710  bool go_back = false;
711 
712  int i, n_iter = 1;
713 
714  LINE new_head;
715 
716  wxLogTrace( "PNS", "INIT-DIR: %s head: %d, tail: %d segs",
718 
719  for( i = 0; i < n_iter; i++ )
720  {
721  if( !go_back && Settings().FollowMouse() )
722  reduceTail( aP );
723 
724  go_back = false;
725 
726  if( !routeHead( aP, new_head ) )
727  fail = true;
728 
729  if( !new_head.Is45Degree() )
730  fail = true;
731 
732  if( !Settings().FollowMouse() )
733  return;
734 
735  m_head = new_head;
736 
738  {
739  n_iter++;
740  go_back = true;
741  }
742 
743  if( !go_back && handlePullback() )
744  {
745  n_iter++;
746  go_back = true;
747  }
748  }
749 
750  if( !fail )
751  {
753  return;
754 
755  mergeHead();
756  }
757 }
bool FollowMouse() const
Returns true if follow mouse mode is active (permanently on for the moment).
LINE m_head
routing "head": volatile part of the track from the previously analyzed point to the current routing ...
ROUTING_SETTINGS & Settings() const
Returns current router settings
bool reduceTail(const VECTOR2I &aEnd)
Function reduceTail()
bool handlePullback()
Function handlePullback()
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 ...
int SegmentCount() const
Returns the number of segments in the line
Definition: pns_line.h:129
bool routeHead(const VECTOR2I &aP, LINE &aNewHead)
Function routeHead()
bool handleSelfIntersections()
Function handleSelfIntersections()
bool optimizeTailHeadTransition()
Function optimizeTailHeadTransition()
const std::string Format() const
Function Format() Formats the direction in a human readable word.
Definition: direction45.h:94
bool mergeHead()
Function mergeHead()
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 65 of file pns_algo_base.h.

References PNS::ALGO_BASE::m_debugDecorator.

66  {
67  m_debugDecorator = aDecorator;
68  }
DEBUG_DECORATOR * m_debugDecorator
Definition: pns_algo_base.h:76
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 88 of file pns_line_placer.cpp.

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

Referenced by FixRoute(), and Start().

89 {
90  m_initial_direction = aDirection;
91 
92  if( m_tail.SegmentCount() == 0 )
93  m_direction = aDirection;
94 }
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 ...
int SegmentCount() const
Returns the number of segments in the line
Definition: pns_line.h:129
DIRECTION_45 m_direction
current routing direction
bool PNS::LINE_PLACER::SetLayer ( int  aLayer)
overridevirtual

Function SetLayer()

Sets the current routing layer.

Reimplemented from PNS::PLACEMENT_ALGO.

Definition at line 832 of file pns_line_placer.cpp.

References initPlacement(), PNS::ITEM::Layers(), m_chainedPlacement, m_currentEnd, m_currentLayer, m_idle, m_startItem, Move(), PNS::ITEM::OfKind(), LAYER_RANGE::Overlaps(), and PNS::ITEM::VIA_T.

833 {
834  if( m_idle )
835  {
836  m_currentLayer = aLayer;
837  return true;
838  }
839  else if( m_chainedPlacement )
840  {
841  return false;
842  }
843  else if( !m_startItem || ( m_startItem->OfKind( ITEM::VIA_T ) && m_startItem->Layers().Overlaps( aLayer ) ) )
844  {
845  m_currentLayer = aLayer;
846  initPlacement();
847  Move( m_currentEnd, NULL );
848  return true;
849  }
850 
851  return false;
852 }
bool Move(const VECTOR2I &aP, ITEM *aEndItem) override
Function Move()
const LAYER_RANGE & Layers() const
Function Layers()
Definition: pns_item.h:207
bool OfKind(int aKindMask) const
Function OfKind()
Definition: pns_item.h:130
void initPlacement()
Function startPlacement()
bool Overlaps(const LAYER_RANGE &aOther) const
Definition: pns_layerset.h:68
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 1141 of file pns_line_placer.cpp.

References m_orthoMode.

1142 {
1143  m_orthoMode = aOrthoMode;
1144 }
void PNS::LINE_PLACER::setWorld ( NODE aWorld)
private

Function setWorld()

Sets the board to route.

Definition at line 63 of file pns_line_placer.cpp.

References m_world.

Referenced by initPlacement().

64 {
65  m_world = aWorld;
66 }
NODE * m_world
pointer to world to search colliding items
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 1103 of file pns_line_placer.cpp.

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

1104 {
1105  LINE l = aNode->AssembleLine( aLatest );
1106  SHAPE_LINE_CHAIN simplified( l.CLine() );
1107 
1108  simplified.Simplify();
1109 
1110  if( simplified.PointCount() != l.PointCount() )
1111  {
1112  aNode->Remove( l );
1113  l.SetShape( simplified );
1114  aNode->Add( l );
1115  }
1116 }
SHAPE_LINE_CHAIN & Simplify()
Function Simplify()
void Remove(int aStartIndex, int aEndIndex)
Function Remove()
Class SHAPE_LINE_CHAIN.
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 801 of file pns_line_placer.cpp.

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

802 {
803  if( !aSeg )
804  return false;
805 
806  if( !aSeg->OfKind( ITEM::SEGMENT_T ) )
807  return false;
808 
809  JOINT* jt = aNode->FindJoint( aP, aSeg );
810 
811  if( jt && jt->LinkCount() >= 1 )
812  return false;
813 
814  SEGMENT* s_old = static_cast<SEGMENT*>( aSeg );
815 
816  std::unique_ptr< SEGMENT > s_new[2] = {
817  Clone( *s_old ),
818  Clone( *s_old )
819  };
820 
821  s_new[0]->SetEnds( s_old->Seg().A, aP );
822  s_new[1]->SetEnds( aP, s_old->Seg().B );
823 
824  aNode->Remove( s_old );
825  aNode->Add( std::move( s_new[0] ), true );
826  aNode->Add( std::move( s_new[1] ), true );
827 
828  return true;
829 }
std::unique_ptr< typename std::remove_const< T >::type > Clone(const T &aItem)
Definition: pns_item.h:367
Struct SEGMENT is a simple container used when filling areas with segments.
Definition: class_zone.h:57
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 855 of file pns_line_placer.cpp.

References initPlacement(), m_chainedPlacement, m_currentEnd, m_currentNet, m_currentStart, m_placingVia, m_startItem, PNS::ITEM::Net(), setInitialDirection(), and PNS::ALGO_BASE::Settings().

856 {
857  VECTOR2I p( aP );
858 
859  static int unknowNetIdx = 0; // -10000;
860  int net = -1;
861 
862  if( !aStartItem || aStartItem->Net() < 0 )
863  net = unknowNetIdx--;
864  else
865  net = aStartItem->Net();
866 
867  m_currentStart = p;
868  m_currentEnd = p;
869  m_currentNet = net;
870  m_startItem = aStartItem;
871  m_placingVia = false;
872  m_chainedPlacement = false;
873 
874  setInitialDirection( Settings().InitialDirection() );
875 
876  initPlacement();
877  return true;
878 }
ROUTING_SETTINGS & Settings() const
Returns current router settings
void setInitialDirection(const DIRECTION_45 &aDirection)
Function setInitialDirection()
void initPlacement()
Function startPlacement()
bool m_placingVia
Are we placing a via?
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 114 of file pns_line_placer.h.

References m_tail.

114 { return m_tail; }
LINE m_tail
routing "tail": part of the track that has been already fixed due to collisions with obstacles ...
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 77 of file pns_line_placer.cpp.

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

78 {
79  m_placingVia = aEnabled;
80 
81  if( !aEnabled )
82  m_head.RemoveVia();
83 
84  return true;
85 }
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:251
bool m_placingVia
Are we placing a via?
const LINE PNS::LINE_PLACER::Trace ( ) const

Function Trace()

Returns the complete routed line.

Definition at line 767 of file pns_line_placer.cpp.

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

768 {
769  LINE tmp( m_head );
770 
771  tmp.SetShape( m_tail.CLine() );
772  tmp.Line().Append( m_head.CLine() );
773  tmp.Line().Simplify();
774  return tmp;
775 }
const SHAPE_LINE_CHAIN & CLine() const
Const accessor to the underlying shape
Definition: pns_line.h:123
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 ...
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 778 of file pns_line_placer.cpp.

References m_currentTrace, and Trace().

779 {
780  m_currentTrace = Trace();
781  return ITEM_SET( &m_currentTrace );
782 }
const LINE Trace() const
Function Trace()
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 1130 of file pns_line_placer.cpp.

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

Referenced by Move().

1131 {
1132  LINE current = Trace();
1133  SHAPE_LINE_CHAIN ratLine;
1134  TOPOLOGY topo( m_lastNode );
1135 
1136  if( topo.LeadingRatLine( &current, ratLine ) )
1137  Dbg()->AddLine( ratLine, 5, 10000 );
1138 }
NODE * m_lastNode
Postprocessed world state (including marked collisions & removed loops)
DEBUG_DECORATOR * Dbg() const
Definition: pns_algo_base.h:70
virtual void AddLine(const SHAPE_LINE_CHAIN &aLine, int aType=0, int aWidth=0)
Class SHAPE_LINE_CHAIN.
const LINE Trace() const
Function Trace()
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 1119 of file pns_line_placer.cpp.

References initPlacement(), m_idle, and m_sizes.

1120 {
1121  m_sizes = aSizes;
1122 
1123  if( !m_idle )
1124  {
1125  initPlacement();
1126  }
1127 }
SIZES_SETTINGS m_sizes
void initPlacement()
Function startPlacement()

Member Data Documentation

bool PNS::LINE_PLACER::m_chainedPlacement
private

Definition at line 399 of file pns_line_placer.h.

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

VECTOR2I PNS::LINE_PLACER::m_currentEnd
private

Definition at line 392 of file pns_line_placer.h.

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

int PNS::LINE_PLACER::m_currentLayer
private

Definition at line 390 of file pns_line_placer.h.

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

PNS_MODE PNS::LINE_PLACER::m_currentMode
private

Definition at line 395 of file pns_line_placer.h.

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

int PNS::LINE_PLACER::m_currentNet
private
VECTOR2I PNS::LINE_PLACER::m_currentStart
private

Definition at line 392 of file pns_line_placer.h.

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

LINE PNS::LINE_PLACER::m_currentTrace
private

Definition at line 393 of file pns_line_placer.h.

Referenced by Traces().

DIRECTION_45 PNS::LINE_PLACER::m_direction
private
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 364 of file pns_line_placer.h.

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

bool PNS::LINE_PLACER::m_idle
private

Definition at line 398 of file pns_line_placer.h.

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

DIRECTION_45 PNS::LINE_PLACER::m_initial_direction
private

routing direction for new traces

Definition at line 360 of file pns_line_placer.h.

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

NODE* PNS::LINE_PLACER::m_lastNode
private

Postprocessed world state (including marked collisions & removed loops)

Definition at line 382 of file pns_line_placer.h.

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

bool PNS::LINE_PLACER::m_orthoMode
private

Definition at line 400 of file pns_line_placer.h.

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

VECTOR2I PNS::LINE_PLACER::m_p_start
private

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

Definition at line 373 of file pns_line_placer.h.

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

bool PNS::LINE_PLACER::m_placingVia
private

Are we placing a via?

Definition at line 387 of file pns_line_placer.h.

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

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

The shove engine

Definition at line 376 of file pns_line_placer.h.

Referenced by initPlacement(), LINE_PLACER(), Logger(), and rhShoveOnly().

SIZES_SETTINGS PNS::LINE_PLACER::m_sizes
private

Definition at line 384 of file pns_line_placer.h.

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

ITEM* PNS::LINE_PLACER::m_startItem
private

Definition at line 396 of file pns_line_placer.h.

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

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

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

NODE* PNS::LINE_PLACER::m_world
private

pointer to world to search colliding items

Definition at line 370 of file pns_line_placer.h.

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


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