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, bool aForceFinish) 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 1164 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 IsPlacingVia(), rhMarkObstacles(), rhShoveOnly(), rhStopAtNearestObstacle(), and rhWalkOnly().

1165 {
1166  SHAPE_LINE_CHAIN l;
1167 
1168  if( m_p_start == aP )
1169  {
1170  l.Clear();
1171  }
1172  else
1173  {
1174  if( Settings().GetFreeAngleMode() && Settings().Mode() == RM_MarkObstacles )
1175  {
1176  l = SHAPE_LINE_CHAIN( m_p_start, aP );
1177  }
1178  else
1179  {
1180  if ( aInvertPosture )
1182  else
1184  }
1185 
1186  if( l.SegmentCount() > 1 && m_orthoMode )
1187  {
1188  VECTOR2I newLast = l.CSegment( 0 ).LineProject( l.CPoint( -1 ) );
1189 
1190  l.Remove( -1, -1 );
1191  l.Point( 1 ) = newLast;
1192  }
1193  }
1194 
1195  aHead.SetShape( l );
1196 
1197  if( !m_placingVia )
1198  return true;
1199 
1200  VIA v( makeVia( aP ) );
1201  v.SetNet( aHead.Net() );
1202 
1204  {
1205  aHead.AppendVia( v );
1206  return true;
1207  }
1208 
1209  VECTOR2I force;
1210  VECTOR2I lead = aP - m_p_start;
1211 
1212  bool solidsOnly = ( m_currentMode != RM_Walkaround );
1213 
1214  if( v.PushoutForce( m_currentNode, lead, force, solidsOnly, 40 ) )
1215  {
1216  SHAPE_LINE_CHAIN line = m_direction.BuildInitialTrace( m_p_start, aP + force );
1217  aHead = LINE( aHead, line );
1218 
1219  v.SetPos( v.Pos() + force );
1220  return true;
1221  }
1222 
1223  return false; // via placement unsuccessful
1224 }
VECTOR2I LineProject(const VECTOR2I &aP) const
Function LineProject()
Definition: seg.h:341
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:262
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:202
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 281 of file pns_line_placer.cpp.

References DIRECTION_45::IsObtuse().

Referenced by IsPlacingVia().

282 {
283  const DIRECTION_45 dir_a( aA );
284  const DIRECTION_45 dir_b( aB );
285 
286  return dir_a.IsObtuse( dir_b ) || dir_a == dir_b;
287 }
Class DIRECTION_45.
Definition: direction45.h:36
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 CurrentNode(), FlipPosture(), m_currentLayer, SetOrthoMode(), and UpdateSizes().

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

References m_currentNode, and m_lastNode.

Referenced by CurrentLayer().

796 {
797  if( aLoopsRemoved && m_lastNode )
798  return m_lastNode;
799 
800  return m_currentNode;
801 }
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,
bool  aForceFinish 
)
overridevirtual

Function FixRoute()

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

Returns
true, if route has been commited. May return false if the routing result is violating design rules - in such case, the track is only committed if Settings.CanViolateDRC() is on.

Implements PNS::PLACEMENT_ALGO.

Definition at line 957 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(), i, 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::ITEM::SetNet(), PNS::ALGO_BASE::Settings(), simplifyNewLine(), Trace(), PNS::LINE::Via(), and PNS::LINE::Width().

958 {
959  bool realEnd = false;
960  int lastV;
961 
962  LINE pl = Trace();
963 
965  {
966  // Mark Obstacles is sort of a half-manual, half-automated mode in which the
967  // user has more responsibility and authority.
968 
969  if( aEndItem )
970  {
971  // The user has indicated a connection should be made. If either the
972  // trace or endItem is netless, then allow the connection by adopting the net of the other.
973  if( m_currentNet <= 0 )
974  {
975  m_currentNet = aEndItem->Net();
976  pl.SetNet( m_currentNet );
977  }
978  else if (aEndItem->Net() <= 0 )
979  aEndItem->SetNet( m_currentNet );
980  }
981 
982  // Collisions still prevent fixing unless "Allow DRC violations" is checked
983  if( !Settings().CanViolateDRC() && m_world->CheckColliding( &pl ) )
984  return false;
985  }
986 
987  const SHAPE_LINE_CHAIN& l = pl.CLine();
988 
989  if( !l.SegmentCount() )
990  {
991  if( pl.EndsWithVia() )
992  {
993  m_lastNode->Add( Clone( pl.Via() ) );
995 
996  m_lastNode = NULL;
997  m_currentNode = NULL;
998 
999  m_idle = true;
1000  }
1001 
1002  return true;
1003  }
1004 
1005  VECTOR2I p_pre_last = l.CPoint( -1 );
1006  const VECTOR2I p_last = l.CPoint( -1 );
1007  DIRECTION_45 d_last( l.CSegment( -1 ) );
1008 
1009  if( l.PointCount() > 2 )
1010  p_pre_last = l.CPoint( -2 );
1011 
1012  if( aEndItem && m_currentNet >= 0 && m_currentNet == aEndItem->Net() )
1013  realEnd = true;
1014 
1015  if( aForceFinish )
1016  realEnd = true;
1017 
1018  if( realEnd || m_placingVia )
1019  lastV = l.SegmentCount();
1020  else
1021  lastV = std::max( 1, l.SegmentCount() - 1 );
1022 
1023  SEGMENT* lastSeg = nullptr;
1024 
1025  for( int i = 0; i < lastV; i++ )
1026  {
1027  const SEG& s = pl.CSegment( i );
1028  lastSeg = new SEGMENT( s, m_currentNet );
1029  std::unique_ptr< SEGMENT > seg( lastSeg );
1030  seg->SetWidth( pl.Width() );
1031  seg->SetLayer( m_currentLayer );
1032  if( ! m_lastNode->Add( std::move( seg ) ) )
1033  {
1034  lastSeg = nullptr;
1035  }
1036  }
1037 
1038  if( pl.EndsWithVia() )
1039  m_lastNode->Add( Clone( pl.Via() ) );
1040 
1041  if( realEnd && lastSeg )
1042  simplifyNewLine( m_lastNode, lastSeg );
1043 
1045 
1046  m_lastNode = NULL;
1047  m_currentNode = NULL;
1048 
1049  if( !realEnd )
1050  {
1051  setInitialDirection( d_last );
1052  m_currentStart = m_placingVia ? p_last : p_pre_last;
1053  m_startItem = NULL;
1054  m_placingVia = false;
1055  m_chainedPlacement = !pl.EndsWithVia();
1056  initPlacement();
1057  }
1058  else
1059  {
1060  m_idle = true;
1061  }
1062 
1063  return realEnd;
1064 }
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:36
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:380
Definition: seg.h:36
NODE * m_currentNode
Current world state
void CommitRouting(NODE *aNode)
Definition: pns_router.cpp:350
#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
size_t i
Definition: json11.cpp:597
const VECTOR2I & CPoint(int aIndex) const
Function CPoint()
bool 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 788 of file pns_line_placer.cpp.

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

Referenced by CurrentLayer().

789 {
792 }
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:262
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 1227 of file pns_line_placer.cpp.

References m_currentNet.

Referenced by IsPlacingVia().

1228 {
1229  aNets.push_back( m_currentNet );
1230 }
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 IsPlacingVia(), and 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:36
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:62
Class SHAPE_LINE_CHAIN.
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
VECTOR2I A
Definition: seg.h:44
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(), i, 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 IsPlacingVia(), and 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:36
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.
size_t i
Definition: json11.cpp:597
VECTOR2I A
Definition: seg.h:44
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 874 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(), IsPlacingVia(), SetLayer(), Start(), and UpdateSizes().

875 {
876  m_idle = false;
877 
878  m_head.Line().Clear();
879  m_tail.Line().Clear();
886  m_head.RemoveVia();
887  m_tail.RemoveVia();
888 
891 
892  NODE* world = Router()->GetWorld();
893 
894  world->KillChildren();
895  NODE* rootNode = world->Branch();
896 
898 
899  setWorld( rootNode );
900 
901  wxLogTrace( "PNS", "world %p, intitial-direction %s layer %d",
903 
904  m_lastNode = NULL;
907 
908  m_shove.reset();
909 
911  {
912  m_shove.reset( new SHOVE( m_world->Branch(), Router() ) );
913  }
914 }
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:199
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:169
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:1226
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:97
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)
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 1232 of file pns_line_placer.cpp.

References m_shove.

Referenced by IsPlacingVia().

1233 {
1234  if( m_shove )
1235  return m_shove->Logger();
1236 
1237  return NULL;
1238 }
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 290 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(), i, 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 IsPlacingVia(), and routeStep().

291 {
292  SHAPE_LINE_CHAIN& head = m_head.Line();
293  SHAPE_LINE_CHAIN& tail = m_tail.Line();
294 
295  const int ForbiddenAngles = DIRECTION_45::ANG_ACUTE |
298 
299  head.Simplify();
300  tail.Simplify();
301 
302  int n_head = head.SegmentCount();
303  int n_tail = tail.SegmentCount();
304 
305  if( n_head < 3 )
306  {
307  wxLogTrace( "PNS", "Merge failed: not enough head segs." );
308  return false;
309  }
310 
311  if( n_tail && head.CPoint( 0 ) != tail.CPoint( -1 ) )
312  {
313  wxLogTrace( "PNS", "Merge failed: head and tail discontinuous." );
314  return false;
315  }
316 
317  if( m_head.CountCorners( ForbiddenAngles ) != 0 )
318  return false;
319 
320  DIRECTION_45 dir_tail, dir_head;
321 
322  dir_head = DIRECTION_45( head.CSegment( 0 ) );
323 
324  if( n_tail )
325  {
326  dir_tail = DIRECTION_45( tail.CSegment( -1 ) );
327 
328  if( dir_head.Angle( dir_tail ) & ForbiddenAngles )
329  return false;
330  }
331 
332  if( !n_tail )
333  tail.Append( head.CSegment( 0 ).A );
334 
335  for( int i = 0; i < n_head - 2; i++ )
336  {
337  tail.Append( head.CSegment( i ).B );
338  }
339 
340  tail.Simplify();
341 
342  SEG last = tail.CSegment( -1 );
343 
344  m_p_start = last.B;
345  m_direction = DIRECTION_45( last ).Right();
346 
347  head.Remove( 0, n_head - 2 );
348 
349  wxLogTrace( "PNS", "Placer: merge %d, new direction: %s", n_head, m_direction.Format().c_str() );
350 
351  head.Simplify();
352  tail.Simplify();
353 
354  return true;
355 }
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:36
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:97
Class SHAPE_LINE_CHAIN.
size_t i
Definition: json11.cpp:597
VECTOR2I A
Definition: seg.h:44
AngleType Angle(const DIRECTION_45 &aOther) const
Function Angle() Returns the type of angle between directions (this) and aOther.
Definition: direction45.h:149
const DIRECTION_45 Right() const
Function Right()
Definition: direction45.h:262
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:45
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 917 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().

918 {
919  LINE current;
920  VECTOR2I p = aP;
921  int eiDepth = -1;
922 
923  if( aEndItem && aEndItem->Owner() )
924  eiDepth = static_cast<NODE*>( aEndItem->Owner() )->Depth();
925 
926  if( m_lastNode )
927  {
928  delete m_lastNode;
929  m_lastNode = NULL;
930  }
931 
932  route( p );
933 
934  current = Trace();
935 
936  if( !current.PointCount() )
938  else
939  m_currentEnd = current.CLine().CPoint( -1 );
940 
941  NODE* latestNode = m_currentNode;
942  m_lastNode = latestNode->Branch();
943 
944  if( eiDepth >= 0 && aEndItem && latestNode->Depth() > eiDepth && current.SegmentCount() )
945  {
946  SplitAdjacentSegments( m_lastNode, aEndItem, current.CPoint( -1 ) );
947 
948  if( Settings().RemoveLoops() )
949  removeLoops( m_lastNode, current );
950  }
951 
953  return true;
954 }
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 647 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 IsPlacingVia(), and routeStep().

648 {
649  LINE linetmp = Trace();
650 
652  {
653  if( linetmp.SegmentCount() < 1 )
654  return false;
655 
656  m_head = linetmp;
657  m_p_start = linetmp.CLine().CPoint( 0 );
658  m_direction = DIRECTION_45( linetmp.CSegment( 0 ) );
659  m_tail.Line().Clear();
660 
661  return true;
662  }
663 
664  SHAPE_LINE_CHAIN& head = m_head.Line();
665  SHAPE_LINE_CHAIN& tail = m_tail.Line();
666 
667  int tailLookbackSegments = 3;
668 
669  //if(m_currentMode() == RM_Walkaround)
670  // tailLookbackSegments = 10000;
671 
672  int threshold = std::min( tail.PointCount(), tailLookbackSegments + 1 );
673 
674  if( tail.SegmentCount() < 3 )
675  return false;
676 
677  // assemble TailLookbackSegments tail segments with the current head
678  SHAPE_LINE_CHAIN opt_line = tail.Slice( -threshold, -1 );
679 
680  int end = std::min(2, head.PointCount() - 1 );
681 
682  opt_line.Append( head.Slice( 0, end ) );
683 
684  LINE new_head( m_tail, opt_line );
685 
686  // and see if it could be made simpler by merging obtuse/collnear segments.
687  // If so, replace the (threshold) last tail points and the head with
688  // the optimized line
689 
691  {
692  LINE tmp( m_tail, opt_line );
693 
694  wxLogTrace( "PNS", "Placer: optimize tail-head [%d]", threshold );
695 
696  head.Clear();
697  tail.Replace( -threshold, -1, new_head.CLine() );
698  tail.Simplify();
699 
700  m_p_start = new_head.CLine().CPoint( -1 );
701  m_direction = DIRECTION_45( new_head.CSegment( -1 ) );
702 
703  return true;
704  }
705 
706  return false;
707 }
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:36
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(), i, 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 IsPlacingVia(), and 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  if( replacement.SegmentCount() < 1 )
247  continue;
248 
249  LINE tmp( m_tail, replacement );
250 
252  break;
253 
254  if( DIRECTION_45( replacement.CSegment( 0 ) ) == dir )
255  {
256  new_start = s.A;
257  new_direction = dir;
258  reduce_index = i;
259  }
260  }
261 
262  if( reduce_index >= 0 )
263  {
264  wxLogTrace( "PNS", "Placer: reducing tail: %d", reduce_index );
265  SHAPE_LINE_CHAIN reducedLine = new_direction.BuildInitialTrace( new_start, aEnd );
266 
267  m_p_start = new_start;
268  m_direction = new_direction;
269  tail.Remove( reduce_index + 1, -1 );
270  head.Clear();
271  return true;
272  }
273 
274  if( !tail.SegmentCount() )
276 
277  return false;
278 }
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:36
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
size_t i
Definition: json11.cpp:597
VECTOR2I A
Definition: seg.h:44
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:202
int SegmentCount() const
Function SegmentCount()
const LINE PNS::LINE_PLACER::reduceToNearestObstacle ( const LINE aOriginalLine)
private

Definition at line 440 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 IsPlacingVia(), and rhStopAtNearestObstacle().

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

1068 {
1069  if( !aLatest.SegmentCount() )
1070  return;
1071 
1072  if( aLatest.CLine().CPoint( 0 ) == aLatest.CLine().CPoint( -1 ) )
1073  return;
1074 
1075  std::set<SEGMENT *> toErase;
1076  aNode->Add( aLatest, true );
1077 
1078  for( int s = 0; s < aLatest.LinkCount(); s++ )
1079  {
1080  SEGMENT* seg = aLatest.GetLink(s);
1081  LINE ourLine = aNode->AssembleLine( seg );
1082  JOINT a, b;
1083  std::vector<LINE> lines;
1084 
1085  aNode->FindLineEnds( ourLine, a, b );
1086 
1087  if( a == b )
1088  {
1089  aNode->FindLineEnds( aLatest, a, b );
1090  }
1091 
1092  aNode->FindLinesBetweenJoints( a, b, lines );
1093 
1094  int removedCount = 0;
1095  int total = 0;
1096 
1097  for( LINE& line : lines )
1098  {
1099  total++;
1100 
1101  if( !( line.ContainsSegment( seg ) ) && line.SegmentCount() )
1102  {
1103  for( SEGMENT *ss : line.LinkedSegments() )
1104  toErase.insert( ss );
1105 
1106  removedCount++;
1107  }
1108  }
1109 
1110  wxLogTrace( "PNS", "total segs removed: %d/%d", removedCount, total );
1111  }
1112 
1113  for( SEGMENT *s : toErase )
1114  aNode->Remove( s );
1115 
1116  aNode->Remove( aLatest );
1117 }
bool PNS::LINE_PLACER::rhMarkObstacles ( const VECTOR2I aP,
LINE aNewHead 
)
private

route step, mark obstacles mode

Definition at line 414 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 IsPlacingVia(), and routeHead().

415 {
416  buildInitialLine( aP, m_head );
417 
418  auto obs = m_currentNode->NearestObstacle( &m_head );
419 
420  if( obs )
421  {
422  int cl = m_currentNode->GetClearance( obs->m_item, &m_head );
423  auto hull = obs->m_item->Hull( cl, m_head.Width() );
424 
425  auto nearest = hull.NearestPoint( aP );
426  Dbg()->AddLine( hull, 2, 10000 );
427 
428  if( ( nearest - aP ).EuclideanNorm() < m_head.Width() )
429  {
430  buildInitialLine( nearest, m_head );
431  }
432  }
433 
434  aNewHead = m_head;
435 
436  return static_cast<bool>( m_currentNode->CheckColliding( &m_head ) );
437 }
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 539 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 IsPlacingVia(), and routeHead().

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

Referenced by IsPlacingVia().

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

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

References CurrentEnd(), and routeStep().

Referenced by IsPlacingVia(), and Move().

764 {
765  routeStep( aP );
766  return CurrentEnd() == aP;
767 }
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 629 of file pns_line_placer.cpp.

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

Referenced by IsPlacingVia(), and routeStep().

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

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

Referenced by IsPlacingVia(), and route().

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

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

References m_orthoMode.

Referenced by CurrentLayer().

1159 {
1160  m_orthoMode = aOrthoMode;
1161 }
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(), and IsPlacingVia().

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 1120 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(), and IsPlacingVia().

1121 {
1122  LINE l = aNode->AssembleLine( aLatest );
1123  SHAPE_LINE_CHAIN simplified( l.CLine() );
1124 
1125  simplified.Simplify();
1126 
1127  if( simplified.PointCount() != l.PointCount() )
1128  {
1129  aNode->Remove( l );
1130  l.SetShape( simplified );
1131  aNode->Add( l );
1132  }
1133 }
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 804 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(), IsPlacingVia(), and Move().

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

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

859 {
860  m_currentStart = VECTOR2I( aP );
861  m_currentEnd = VECTOR2I( aP );
862  m_currentNet = std::max( 0, aStartItem ? aStartItem->Net() : 0 );
863  m_startItem = aStartItem;
864  m_placingVia = false;
865  m_chainedPlacement = false;
866 
867  setInitialDirection( Settings().InitialDirection() );
868 
869  initPlacement();
870  return true;
871 }
ROUTING_SETTINGS & Settings() const
Returns current router settings
VECTOR2< int > VECTOR2I
Definition: vector2d.h:587
void setInitialDirection(const DIRECTION_45 &aDirection)
Function setInitialDirection()
void initPlacement()
Function startPlacement()
#define max(a, b)
Definition: auxiliary.h:86
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, Trace(), and Traces().

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 770 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(), Tail(), Traces(), and updateLeadingRatLine().

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

References m_currentTrace, and Trace().

Referenced by Tail().

782 {
783  m_currentTrace = Trace();
784  return ITEM_SET( &m_currentTrace );
785 }
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 1147 of file pns_line_placer.cpp.

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

Referenced by IsPlacingVia(), and Move().

1148 {
1149  LINE current = Trace();
1150  SHAPE_LINE_CHAIN ratLine;
1151  TOPOLOGY topo( m_lastNode );
1152 
1153  if( topo.LeadingRatLine( &current, ratLine ) )
1154  Dbg()->AddLine( ratLine, 5, 10000 );
1155 }
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 1136 of file pns_line_placer.cpp.

References initPlacement(), m_idle, and m_sizes.

Referenced by CurrentLayer().

1137 {
1138  m_sizes = aSizes;
1139 
1140  if( !m_idle )
1141  {
1142  initPlacement();
1143  }
1144 }
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: