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...
 
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 splitAdjacentSegments (NODE *aNode, ITEM *aSeg, const VECTOR2I &aP)
 Function splitAdjacentSegments() 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 39 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.

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

Definition at line 60 of file pns_line_placer.cpp.

61 {
62 }

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

References DIRECTION_45::IsObtuse().

281 {
282  const DIRECTION_45 dir_a( aA );
283  const DIRECTION_45 dir_b( aB );
284 
285  return dir_a.IsObtuse( dir_b ) || dir_a == dir_b;
286 }
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 794 of file pns_line_placer.cpp.

References m_currentNode, and m_lastNode.

795 {
796  if( aLoopsRemoved && m_lastNode )
797  return m_lastNode;
798 
799  return m_currentNode;
800 }
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:37
NODE * m_currentNode
Current world state
void CommitRouting(NODE *aNode)
Definition: pns_router.cpp:324
#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:427
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:596
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 787 of file pns_line_placer.cpp.

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

788 {
791 }
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 159 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().

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

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

290 {
291  SHAPE_LINE_CHAIN& head = m_head.Line();
292  SHAPE_LINE_CHAIN& tail = m_tail.Line();
293 
294  const int ForbiddenAngles = DIRECTION_45::ANG_ACUTE |
297 
298  head.Simplify();
299  tail.Simplify();
300 
301  int n_head = head.SegmentCount();
302  int n_tail = tail.SegmentCount();
303 
304  if( n_head < 3 )
305  {
306  wxLogTrace( "PNS", "Merge failed: not enough head segs." );
307  return false;
308  }
309 
310  if( n_tail && head.CPoint( 0 ) != tail.CPoint( -1 ) )
311  {
312  wxLogTrace( "PNS", "Merge failed: head and tail discontinuous." );
313  return false;
314  }
315 
316  if( m_head.CountCorners( ForbiddenAngles ) != 0 )
317  return false;
318 
319  DIRECTION_45 dir_tail, dir_head;
320 
321  dir_head = DIRECTION_45( head.CSegment( 0 ) );
322 
323  if( n_tail )
324  {
325  dir_tail = DIRECTION_45( tail.CSegment( -1 ) );
326 
327  if( dir_head.Angle( dir_tail ) & ForbiddenAngles )
328  return false;
329  }
330 
331  if( !n_tail )
332  tail.Append( head.CSegment( 0 ).A );
333 
334  for( int i = 0; i < n_head - 2; i++ )
335  {
336  tail.Append( head.CSegment( i ).B );
337  }
338 
339  tail.Simplify();
340 
341  SEG last = tail.CSegment( -1 );
342 
343  m_p_start = last.B;
344  m_direction = DIRECTION_45( last ).Right();
345 
346  head.Remove( 0, n_head - 2 );
347 
348  wxLogTrace( "PNS", "Placer: merge %d, new direction: %s", n_head, m_direction.Format().c_str() );
349 
350  head.Simplify();
351  tail.Simplify();
352 
353  return true;
354 }
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:138
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:37
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:47
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:48
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:109
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.
void splitAdjacentSegments(NODE *aNode, ITEM *aSeg, const VECTOR2I &aP)
Function splitAdjacentSegments()
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 646 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().

647 {
648  LINE linetmp = Trace();
649 
651  {
652  if( linetmp.SegmentCount() < 1 )
653  return false;
654 
655  m_head = linetmp;
656  m_p_start = linetmp.CLine().CPoint( 0 );
657  m_direction = DIRECTION_45( linetmp.CSegment( 0 ) );
658  m_tail.Line().Clear();
659 
660  return true;
661  }
662 
663  SHAPE_LINE_CHAIN& head = m_head.Line();
664  SHAPE_LINE_CHAIN& tail = m_tail.Line();
665 
666  int tailLookbackSegments = 3;
667 
668  //if(m_currentMode() == RM_Walkaround)
669  // tailLookbackSegments = 10000;
670 
671  int threshold = std::min( tail.PointCount(), tailLookbackSegments + 1 );
672 
673  if( tail.SegmentCount() < 3 )
674  return false;
675 
676  // assemble TailLookbackSegments tail segments with the current head
677  SHAPE_LINE_CHAIN opt_line = tail.Slice( -threshold, -1 );
678 
679  int end = std::min(2, head.PointCount() - 1 );
680 
681  opt_line.Append( head.Slice( 0, end ) );
682 
683  LINE new_head( m_tail, opt_line );
684 
685  // and see if it could be made simpler by merging obtuse/collnear segments.
686  // If so, replace the (threshold) last tail points and the head with
687  // the optimized line
688 
690  {
691  LINE tmp( m_tail, opt_line );
692 
693  wxLogTrace( "PNS", "Placer: optimize tail-head [%d]", threshold );
694 
695  head.Clear();
696  tail.Replace( -threshold, -1, new_head.CLine() );
697  tail.Simplify();
698 
699  m_p_start = new_head.CLine().CPoint( -1 );
700  m_direction = DIRECTION_45( new_head.CSegment( -1 ) );
701 
702  return true;
703  }
704 
705  return false;
706 }
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 218 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().

219 {
220  SHAPE_LINE_CHAIN& head = m_head.Line();
221  SHAPE_LINE_CHAIN& tail = m_tail.Line();
222 
223  int n = tail.SegmentCount();
224 
225  if( head.SegmentCount() < 1 )
226  return false;
227 
228  // Don't attempt this for too short tails
229  if( n < 2 )
230  return false;
231 
232  // Start from the segment farthest from the end of the tail
233  // int start_index = std::max(n - 1 - ReductionDepth, 0);
234 
235  DIRECTION_45 new_direction;
236  VECTOR2I new_start;
237  int reduce_index = -1;
238 
239  for( int i = tail.SegmentCount() - 1; i >= 0; i-- )
240  {
241  const SEG s = tail.CSegment( i );
242  DIRECTION_45 dir( s );
243 
244  // calculate a replacement route and check if it matches
245  // the direction of the segment to be replaced
246  SHAPE_LINE_CHAIN replacement = dir.BuildInitialTrace( s.A, aEnd );
247 
248  LINE tmp( m_tail, replacement );
249 
251  break;
252 
253  if( DIRECTION_45( replacement.CSegment( 0 ) ) == dir )
254  {
255  new_start = s.A;
256  new_direction = dir;
257  reduce_index = i;
258  }
259  }
260 
261  if( reduce_index >= 0 )
262  {
263  wxLogTrace( "PNS", "Placer: reducing tail: %d", reduce_index );
264  SHAPE_LINE_CHAIN reducedLine = new_direction.BuildInitialTrace( new_start, aEnd );
265 
266  m_p_start = new_start;
267  m_direction = new_direction;
268  tail.Remove( reduce_index + 1, -1 );
269  head.Clear();
270  return true;
271  }
272 
273  if( !tail.SegmentCount() )
275 
276  return false;
277 }
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:37
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: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)
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 439 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().

440 {
441  auto l0 = aOriginalLine.CLine();
442 
443  if ( !l0.PointCount() )
444  return aOriginalLine;
445 
446  int l = l0.Length();
447  int step = l / 2;
448  VECTOR2I target;
449 
450  LINE l_test( aOriginalLine );
451 
452  while( step > 0 )
453  {
454  target = l0.PointAlong( l );
455  SHAPE_LINE_CHAIN l_cur( l0 );
456 
457  int index = l_cur.Split( target );
458 
459  l_test.SetShape( l_cur.Slice( 0, index ) );
460 
461  if ( m_currentNode->CheckColliding( &l_test ) )
462  l -= step;
463  else
464  l += step;
465 
466  step /= 2;
467  }
468 
469  l = l_test.CLine().Length();
470 
471  while( m_currentNode->CheckColliding( &l_test ) && l > 0 )
472  {
473  l--;
474  target = l0.PointAlong( l );
475  SHAPE_LINE_CHAIN l_cur( l0 );
476 
477  int index = l_cur.Split( target );
478 
479  l_test.SetShape( l_cur.Slice( 0, index ) );
480  }
481 
482  return l_test;
483 }
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:427
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 413 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().

414 {
415  buildInitialLine( aP, m_head );
416 
417  auto obs = m_currentNode->NearestObstacle( &m_head );
418 
419  if( obs )
420  {
421  int cl = m_currentNode->GetClearance( obs->m_item, &m_head );
422  auto hull = obs->m_item->Hull( cl, m_head.Width() );
423 
424  auto nearest = hull.NearestPoint( aP );
425  Dbg()->AddLine( hull, 2, 10000 );
426 
427  if( ( nearest - aP ).EuclideanNorm() < m_head.Width() )
428  {
429  buildInitialLine( nearest, m_head );
430  }
431  }
432 
433  aNewHead = m_head;
434 
435  return static_cast<bool>( m_currentNode->CheckColliding( &m_head ) );
436 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:104
OPT_OBSTACLE NearestObstacle(const LINE *aItem, int aKindMask=ITEM::ANY_T, const std::set< ITEM * > *aRestrictedSet=NULL)
Function NearestObstacle()
Definition: pns_node.cpp:304
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:100
OPT_OBSTACLE CheckColliding(const ITEM *aItem, int aKindMask=ITEM::ANY_T)
Function CheckColliding()
Definition: pns_node.cpp:427
bool PNS::LINE_PLACER::rhShoveOnly ( const VECTOR2I aP,
LINE aNewHead 
)
private

route step, shove mode

Definition at line 538 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().

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

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

route step, walkaround mode

Definition at line 357 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().

358 {
359  LINE initTrack( m_head );
360  LINE walkFull;
361  int effort = 0;
362  bool rv = true, viaOk;
363 
364  viaOk = buildInitialLine( aP, initTrack );
365 
366  WALKAROUND walkaround( m_currentNode, Router() );
367 
368  walkaround.SetSolidsOnly( false );
369  walkaround.SetIterationLimit( Settings().WalkaroundIterationLimit() );
370 
371  WALKAROUND::WALKAROUND_STATUS wf = walkaround.Route( initTrack, walkFull, false );
372 
373  switch( Settings().OptimizerEffort() )
374  {
375  case OE_LOW:
376  effort = 0;
377  break;
378 
379  case OE_MEDIUM:
380  case OE_FULL:
381  effort = OPTIMIZER::MERGE_SEGMENTS;
382  break;
383  }
384 
385  if( Settings().SmartPads() )
386  effort |= OPTIMIZER::SMART_PADS;
387 
388  if( wf == WALKAROUND::STUCK )
389  {
390  walkFull = walkFull.ClipToNearestObstacle( m_currentNode );
391  rv = true;
392  }
393  else if( m_placingVia && viaOk )
394  {
395  walkFull.AppendVia( makeVia( walkFull.CPoint( -1 ) ) );
396  }
397 
398  OPTIMIZER::Optimize( &walkFull, effort, m_currentNode );
399 
400  if( m_currentNode->CheckColliding( &walkFull ) )
401  {
402  aNewHead = m_head;
403  return false;
404  }
405 
406  m_head = walkFull;
407  aNewHead = walkFull;
408 
409  return rv;
410 }
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:427
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 762 of file pns_line_placer.cpp.

References CurrentEnd(), and routeStep().

Referenced by Move().

763 {
764  routeStep( aP );
765  return CurrentEnd() == aP;
766 }
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 628 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().

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

710 {
711  bool fail = false;
712  bool go_back = false;
713 
714  int i, n_iter = 1;
715 
716  LINE new_head;
717 
718  wxLogTrace( "PNS", "INIT-DIR: %s head: %d, tail: %d segs",
720 
721  for( i = 0; i < n_iter; i++ )
722  {
723  if( !go_back && Settings().FollowMouse() )
724  reduceTail( aP );
725 
726  go_back = false;
727 
728  if( !routeHead( aP, new_head ) )
729  fail = true;
730 
731  if( !new_head.Is45Degree() )
732  fail = true;
733 
734  if( !Settings().FollowMouse() )
735  return;
736 
737  m_head = new_head;
738 
740  {
741  n_iter++;
742  go_back = true;
743  }
744 
745  if( !go_back && handlePullback() )
746  {
747  n_iter++;
748  go_back = true;
749  }
750  }
751 
752  if( !fail )
753  {
755  return;
756 
757  mergeHead();
758  }
759 }
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 90 of file pns_line_placer.cpp.

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

Referenced by FixRoute(), and Start().

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

References m_world.

Referenced by initPlacement().

66 {
67  m_world = aWorld;
68 }
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.
void PNS::LINE_PLACER::splitAdjacentSegments ( NODE aNode,
ITEM aSeg,
const VECTOR2I aP 
)
private

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 803 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 initPlacement(), and Move().

804 {
805  if( !aSeg )
806  return;
807 
808  if( !aSeg->OfKind( ITEM::SEGMENT_T ) )
809  return;
810 
811  JOINT* jt = aNode->FindJoint( aP, aSeg );
812 
813  if( jt && jt->LinkCount() >= 1 )
814  return;
815 
816  SEGMENT* s_old = static_cast<SEGMENT*>( aSeg );
817 
818  std::unique_ptr< SEGMENT > s_new[2] = {
819  Clone( *s_old ),
820  Clone( *s_old )
821  };
822 
823  s_new[0]->SetEnds( s_old->Seg().A, aP );
824  s_new[1]->SetEnds( aP, s_old->Seg().B );
825 
826  aNode->Remove( s_old );
827  aNode->Add( std::move( s_new[0] ), true );
828  aNode->Add( std::move( s_new[1] ), 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 79 of file pns_line_placer.cpp.

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

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

770 {
771  LINE tmp( m_head );
772 
773  tmp.SetShape( m_tail.CLine() );
774  tmp.Line().Append( m_head.CLine() );
775  tmp.Line().Simplify();
776  return tmp;
777 }
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 780 of file pns_line_placer.cpp.

References m_currentTrace, and Trace().

781 {
782  m_currentTrace = Trace();
783  return ITEM_SET( &m_currentTrace );
784 }
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: