KiCad PCB EDA Suite
PNS::LINE Class Reference

Represents a track on a PCB, connecting two non-trivial joints (that is, vias, pads, junctions between multiple traces or two traces different widths and combinations of these). More...

#include <pns_line.h>

Inheritance diagram for PNS::LINE:
PNS::LINK_HOLDER PNS::ITEM

Public Types

typedef std::vector< LINKED_ITEM * > LINKS
 
enum  PnsKind {
  SOLID_T = 1, LINE_T = 2, JOINT_T = 4, SEGMENT_T = 8,
  ARC_T = 16, VIA_T = 32, DIFF_PAIR_T = 64, ANY_T = 0xff
}
 

Public Member Functions

 LINE ()
 Makes an empty line. More...
 
 LINE (const LINE &aOther)
 
 LINE (const LINE &aBase, const SHAPE_LINE_CHAIN &aLine)
 Copy properties (net, layers, etc.) from a base line and replaces the shape by another. More...
 
 LINE (const VIA &aVia)
 Construct a LINE for a lone VIA (ie a stitching via). More...
 
 ~LINE ()
 
virtual LINEClone () const override
 Return a deep copy of the item. More...
 
LINEoperator= (const LINE &aOther)
 
bool IsLinkedChecked () const
 Assign a shape to the line (a polyline/line chain). More...
 
void SetShape (const SHAPE_LINE_CHAIN &aLine)
 Return the shape of the line. More...
 
const SHAPEShape () const override
 Modifiable accessor to the underlying shape. More...
 
SHAPE_LINE_CHAINLine ()
 
const SHAPE_LINE_CHAINCLine () const
 
int SegmentCount () const
 
int PointCount () const
 
int ArcCount () const
 
int ShapeCount () const
 Return the aIdx-th point of the line. More...
 
const VECTOR2ICPoint (int aIdx) const
 
const SEG CSegment (int aIdx) const
 Set line width. More...
 
void SetWidth (int aWidth)
 Return line width. More...
 
int Width () const
 Return true if the line is geometrically identical as line aOther. More...
 
bool CompareGeometry (const LINE &aOther)
 Reverse the point/vertex order. More...
 
void Reverse ()
 Clip the line to the nearest obstacle, traversing from the line's start vertex (0). More...
 
const LINE ClipToNearestObstacle (NODE *aNode) const
 Clip the line to a given range of vertices. More...
 
void ClipVertexRange (int aStart, int aEnd)
 Return the number of corners of angles specified by mask aAngles. More...
 
int CountCorners (int aAngles) const
 
bool Walkaround (SHAPE_LINE_CHAIN aObstacle, SHAPE_LINE_CHAIN &aPre, SHAPE_LINE_CHAIN &aWalk, SHAPE_LINE_CHAIN &aPost, bool aCw) const
 Calculate a line tightly wrapping a convex hull of an obstacle object (aObstacle). More...
 
bool Walkaround (const SHAPE_LINE_CHAIN &aObstacle, SHAPE_LINE_CHAIN &aPath, bool aCw) const
 
bool Is45Degree () const
 Print out all linked segments. More...
 
void ShowLinks () const
 
bool EndsWithVia () const
 
void AppendVia (const VIA &aVia)
 
void RemoveVia ()
 
const VIAVia () const
 
void SetViaDiameter (int aDiameter)
 
void SetViaDrill (int aDrill)
 
virtual void Mark (int aMarker) const override
 
virtual void Unmark (int aMarker=-1) const override
 
virtual int Marker () const override
 
void SetBlockingObstacle (ITEM *aObstacle)
 
ITEMGetBlockingObstacle () const
 
void DragSegment (const VECTOR2I &aP, int aIndex, bool aFreeAngle=false)
 
void DragCorner (const VECTOR2I &aP, int aIndex, bool aFreeAngle=false)
 
void SetRank (int aRank) override
 
int Rank () const override
 
bool HasLoops () const
 
bool HasLockedSegments () const
 
void Clear ()
 
OPT_BOX2I ChangedArea (const LINE *aOther) const
 
void SetSnapThreshhold (int aThreshhold)
 
int GetSnapThreshhold () const
 
void Link (LINKED_ITEM *aLink)
 Return the list of links from the owning node that constitute this line (or NULL if the line is not linked). More...
 
LINKSLinks ()
 
const LINKSLinks () const
 
bool IsLinked () const
 Check if the segment aLink is a part of the line. More...
 
bool ContainsLink (const LINKED_ITEM *aItem) const
 
LINKED_ITEMGetLink (int aIndex) const
 Erase the linking information. Used to detach the line from the owning node. More...
 
virtual void ClearLinks ()
 Return the number of segments that were assembled together to form this line. More...
 
int LinkCount () const
 
virtual const SHAPE_LINE_CHAIN Hull (int aClearance=0, int aWalkaroundThickness=0, int aLayer=-1) const
 
virtual const SHAPE_LINE_CHAIN HoleHull (int aClearance, int aWalkaroundThickness, int aLayer) const
 
PnsKind Kind () const
 Return the type (kind) of the item. More...
 
bool OfKind (int aKindMask) const
 Return true if the item's type matches the mask aKindMask. More...
 
std::string KindStr () const
 Returns the kind of the item, as string. More...
 
void SetParent (BOARD_ITEM *aParent)
 
BOARD_ITEMParent () const
 
void SetNet (int aNet)
 
int Net () const
 
const LAYER_RANGELayers () const
 
void SetLayers (const LAYER_RANGE &aLayers)
 
void SetLayer (int aLayer)
 
virtual int Layer () const
 
bool LayersOverlap (const ITEM *aOther) const
 Return true if the set of layers spanned by aOther overlaps our layers. More...
 
NODEOwner () const
 Return the owner of this item, or NULL if there's none. More...
 
void SetOwner (NODE *aOwner)
 Set the node that owns this item. More...
 
bool BelongsTo (NODE *aNode) const
 
bool Collide (const ITEM *aOther, const NODE *aNode, bool aDifferentNetsOnly=true) const
 Check for a collision (clearance violation) with between us and item aOther. More...
 
virtual const SHAPEHole () const
 
virtual VECTOR2I Anchor (int n) const
 
virtual int AnchorCount () const
 
bool IsLocked () const
 
void SetRoutable (bool aRoutable)
 
bool IsRoutable () const
 

Static Public Member Functions

static bool ClassOf (const ITEM *aItem)
 

Static Public Attributes

static const int UnusedNet = INT_MAX
 Supported item types. More...
 

Protected Member Functions

void copyLinks (const LINK_HOLDER *aParent)
 < Copy m_links from the line aParent. More...
 

Protected Attributes

LINKS m_links
 
PnsKind m_kind
 
BOARD_ITEMm_parent
 
NODEm_owner
 
LAYER_RANGE m_layers
 
bool m_movable
 
int m_net
 
int m_marker
 
int m_rank
 
bool m_routable
 

Private Member Functions

void dragSegment45 (const VECTOR2I &aP, int aIndex)
 
void dragCorner45 (const VECTOR2I &aP, int aIndex)
 
void dragSegmentFree (const VECTOR2I &aP, int aIndex)
 
void dragCornerFree (const VECTOR2I &aP, int aIndex)
 
VECTOR2I snapToNeighbourSegments (const SHAPE_LINE_CHAIN &aPath, const VECTOR2I &aP, int aIndex) const
 
VECTOR2I snapDraggedCorner (const SHAPE_LINE_CHAIN &aPath, const VECTOR2I &aP, int aIndex) const
 

Private Attributes

SHAPE_LINE_CHAIN m_line
 The actual shape of the line. More...
 
int m_width
 Our width. More...
 
int m_snapThreshhold
 Width to smooth out jagged segments. More...
 
bool m_hasVia
 Optional via at the end point. More...
 
VIA m_via
 
ITEMm_blockingObstacle
 For mark obstacle mode. More...
 

Detailed Description

Represents a track on a PCB, connecting two non-trivial joints (that is, vias, pads, junctions between multiple traces or two traces different widths and combinations of these).

PNS_LINEs are NOT stored in the model (NODE). Instead, they are assembled on-the-fly, based on a via/pad/segment that belongs to/starts/ends them.

PNS_LINEs can be either loose (consisting of segments that do not belong to any NODE) or owned (with segments taken from a NODE) - these are returned by #NODE::AssembleLine and friends.

A LINE may have a VIA attached at its end (i.e. the last point) - this is used by via dragging/force propagation stuff.

Definition at line 60 of file pns_line.h.

Member Typedef Documentation

◆ LINKS

typedef std::vector<LINKED_ITEM*> PNS::LINK_HOLDER::LINKS
inherited

Definition at line 36 of file pns_link_holder.h.

Member Enumeration Documentation

◆ PnsKind

enum PNS::ITEM::PnsKind
inherited
Enumerator
SOLID_T 
LINE_T 
JOINT_T 
SEGMENT_T 
ARC_T 
VIA_T 
DIFF_PAIR_T 
ANY_T 

Definition at line 61 of file pns_item.h.

62  {
63  SOLID_T = 1,
64  LINE_T = 2,
65  JOINT_T = 4,
66  SEGMENT_T = 8,
67  ARC_T = 16,
68  VIA_T = 32,
69  DIFF_PAIR_T = 64,
70  ANY_T = 0xff
71  };

Constructor & Destructor Documentation

◆ LINE() [1/4]

PNS::LINE::LINE ( )
inline

Makes an empty line.

Definition at line 66 of file pns_line.h.

66  :
68  m_blockingObstacle( nullptr )
69  {
70  m_hasVia = false;
71  m_width = 1; // Dummy value
72  m_snapThreshhold = 0;
73  }
ITEM * m_blockingObstacle
For mark obstacle mode.
Definition: pns_line.h:252
bool m_hasVia
Optional via at the end point.
Definition: pns_line.h:249
int m_snapThreshhold
Width to smooth out jagged segments.
Definition: pns_line.h:247
int m_width
Our width.
Definition: pns_line.h:244

References m_hasVia, m_snapThreshhold, and m_width.

Referenced by Clone().

◆ LINE() [2/4]

PNS::LINE::LINE ( const LINE aOther)

Definition at line 37 of file pns_line.cpp.

38  : LINK_HOLDER( aOther ),
39  m_line( aOther.m_line ),
40  m_width( aOther.m_width ),
41  m_snapThreshhold( aOther.m_snapThreshhold )
42 {
43  m_net = aOther.m_net;
44  m_movable = aOther.m_movable;
45  m_layers = aOther.m_layers;
46  m_via = aOther.m_via;
47  m_hasVia = aOther.m_hasVia;
48  m_marker = aOther.m_marker;
49  m_rank = aOther.m_rank;
50  m_blockingObstacle = aOther.m_blockingObstacle;
51 
52  copyLinks( &aOther );
53 }
VIA m_via
Definition: pns_line.h:250
LAYER_RANGE m_layers
Definition: pns_item.h:239
int m_rank
Definition: pns_item.h:244
bool m_movable
Definition: pns_item.h:241
int m_marker
Definition: pns_item.h:243
ITEM * m_blockingObstacle
For mark obstacle mode.
Definition: pns_line.h:252
SHAPE_LINE_CHAIN m_line
The actual shape of the line.
Definition: pns_line.h:243
bool m_hasVia
Optional via at the end point.
Definition: pns_line.h:249
int m_net
Definition: pns_item.h:242
int m_snapThreshhold
Width to smooth out jagged segments.
Definition: pns_line.h:247
int m_width
Our width.
Definition: pns_line.h:244

References PNS::LINK_HOLDER::copyLinks(), m_blockingObstacle, m_hasVia, PNS::ITEM::m_layers, PNS::ITEM::m_marker, PNS::ITEM::m_movable, PNS::ITEM::m_net, PNS::ITEM::m_rank, and m_via.

◆ LINE() [3/4]

PNS::LINE::LINE ( const LINE aBase,
const SHAPE_LINE_CHAIN aLine 
)
inline

Copy properties (net, layers, etc.) from a base line and replaces the shape by another.

Definition at line 80 of file pns_line.h.

80  :
81  LINK_HOLDER( aBase ),
82  m_line( aLine ),
83  m_width( aBase.m_width ),
84  m_snapThreshhold( aBase.m_snapThreshhold ),
85  m_blockingObstacle( nullptr )
86  {
87  m_net = aBase.m_net;
88  m_layers = aBase.m_layers;
89  m_hasVia = false;
90  }
LAYER_RANGE m_layers
Definition: pns_item.h:239
ITEM * m_blockingObstacle
For mark obstacle mode.
Definition: pns_line.h:252
SHAPE_LINE_CHAIN m_line
The actual shape of the line.
Definition: pns_line.h:243
bool m_hasVia
Optional via at the end point.
Definition: pns_line.h:249
int m_net
Definition: pns_item.h:242
int m_snapThreshhold
Width to smooth out jagged segments.
Definition: pns_line.h:247
int m_width
Our width.
Definition: pns_line.h:244

References m_hasVia, PNS::ITEM::m_layers, and PNS::ITEM::m_net.

◆ LINE() [4/4]

PNS::LINE::LINE ( const VIA aVia)
inline

Construct a LINE for a lone VIA (ie a stitching via).

Definition at line 95 of file pns_line.h.

95  :
97  m_blockingObstacle( nullptr )
98  {
99  m_hasVia = true;
100  m_via = aVia;
101  m_width = aVia.Diameter();
102  m_net = aVia.Net();
103  m_layers = aVia.Layers();
104  m_rank = aVia.Rank();
105  m_snapThreshhold = 0;
106  }
VIA m_via
Definition: pns_line.h:250
LAYER_RANGE m_layers
Definition: pns_item.h:239
int m_rank
Definition: pns_item.h:244
ITEM * m_blockingObstacle
For mark obstacle mode.
Definition: pns_line.h:252
bool m_hasVia
Optional via at the end point.
Definition: pns_line.h:249
int m_net
Definition: pns_item.h:242
int m_snapThreshhold
Width to smooth out jagged segments.
Definition: pns_line.h:247
int m_width
Our width.
Definition: pns_line.h:244

References PNS::VIA::Diameter(), PNS::ITEM::Layers(), m_hasVia, PNS::ITEM::m_layers, PNS::ITEM::m_net, PNS::ITEM::m_rank, m_snapThreshhold, m_via, m_width, PNS::ITEM::Net(), and PNS::ITEM::Rank().

◆ ~LINE()

PNS::LINE::~LINE ( )

Definition at line 56 of file pns_line.cpp.

57 {
58 }

Member Function Documentation

◆ Anchor()

◆ AnchorCount()

virtual int PNS::ITEM::AnchorCount ( ) const
inlinevirtualinherited

Reimplemented in PNS::VIA, PNS::SEGMENT, PNS::SOLID, and PNS::ARC.

Definition at line 218 of file pns_item.h.

219  {
220  return 0;
221  }

◆ AppendVia()

void PNS::LINE::AppendVia ( const VIA aVia)

Definition at line 870 of file pns_line.cpp.

871 {
872  if( m_line.PointCount() > 1 && aVia.Pos() == m_line.CPoint( 0 ) )
873  {
874  Reverse();
875  }
876 
877  m_hasVia = true;
878  m_via = aVia;
879  m_via.SetNet( m_net );
880 }
VIA m_via
Definition: pns_line.h:250
int PointCount() const
Function PointCount()
void SetNet(int aNet)
Definition: pns_item.h:147
SHAPE_LINE_CHAIN m_line
The actual shape of the line.
Definition: pns_line.h:243
const VECTOR2I & CPoint(int aIndex) const
Function Point()
void Reverse()
Clip the line to the nearest obstacle, traversing from the line's start vertex (0).
Definition: pns_line.cpp:862
bool m_hasVia
Optional via at the end point.
Definition: pns_line.h:249
int m_net
Definition: pns_item.h:242

References SHAPE_LINE_CHAIN::CPoint(), m_hasVia, m_line, PNS::ITEM::m_net, m_via, SHAPE_LINE_CHAIN::PointCount(), PNS::VIA::Pos(), Reverse(), and PNS::ITEM::SetNet().

Referenced by PNS::LINE_PLACER::buildInitialLine(), PNS::SHOVE::onReverseCollidingVia(), PNS::LINE_PLACER::rhShoveOnly(), PNS::LINE_PLACER::rhWalkOnly(), and PNS::DIFF_PAIR::updateLine().

◆ ArcCount()

int PNS::LINE::ArcCount ( ) const
inline

Definition at line 141 of file pns_line.h.

141 { return m_line.ArcCount(); }
size_t ArcCount() const
SHAPE_LINE_CHAIN m_line
The actual shape of the line.
Definition: pns_line.h:243

References SHAPE_LINE_CHAIN::ArcCount(), and m_line.

Referenced by PNS::OPTIMIZER::Optimize().

◆ BelongsTo()

bool PNS::ITEM::BelongsTo ( NODE aNode) const
inlineinherited
Returns
true if the item is owned by the node aNode.

Definition at line 177 of file pns_item.h.

178  {
179  return m_owner == aNode;
180  }
NODE * m_owner
Definition: pns_item.h:238

References PNS::ITEM::m_owner.

Referenced by PNS::NODE::doRemove().

◆ ChangedArea()

OPT_BOX2I PNS::LINE::ChangedArea ( const LINE aOther) const

Definition at line 1008 of file pns_line.cpp.

1009 {
1010  BOX2I area;
1011  bool areaDefined = false;
1012 
1013  int i_start = -1;
1014  int i_end_self = -1, i_end_other = -1;
1015 
1016  SHAPE_LINE_CHAIN self( m_line );
1017  self.Simplify();
1018  SHAPE_LINE_CHAIN other( aOther->m_line );
1019  other.Simplify();
1020 
1021  int np_self = self.PointCount();
1022  int np_other = other.PointCount();
1023 
1024  int n = std::min( np_self, np_other );
1025 
1026  for( int i = 0; i < n; i++ )
1027  {
1028  const VECTOR2I p1 = self.CPoint( i );
1029  const VECTOR2I p2 = other.CPoint( i );
1030 
1031  if( p1 != p2 )
1032  {
1033  if( i != n - 1 )
1034  {
1035  SEG s = self.CSegment( i );
1036 
1037  if( !s.Contains( p2 ) )
1038  {
1039  i_start = i;
1040  break;
1041  }
1042  }
1043  else
1044  {
1045  i_start = i;
1046  break;
1047  }
1048  }
1049  }
1050 
1051  for( int i = 0; i < n; i++ )
1052  {
1053  const VECTOR2I p1 = self.CPoint( np_self - 1 - i );
1054  const VECTOR2I p2 = other.CPoint( np_other - 1 - i );
1055 
1056  if( p1 != p2 )
1057  {
1058  i_end_self = np_self - 1 - i;
1059  i_end_other = np_other - 1 - i;
1060  break;
1061  }
1062  }
1063 
1064  if( i_start < 0 )
1065  i_start = n;
1066 
1067  if( i_end_self < 0 )
1068  i_end_self = np_self - 1;
1069 
1070  if( i_end_other < 0 )
1071  i_end_other = np_other - 1;
1072 
1073  for( int i = i_start; i <= i_end_self; i++ )
1074  extendBox( area, areaDefined, self.CPoint( i ) );
1075 
1076  for( int i = i_start; i <= i_end_other; i++ )
1077  extendBox( area, areaDefined, other.CPoint( i ) );
1078 
1079  if( areaDefined )
1080  {
1081  area.Inflate( std::max( Width(), aOther->Width() ) );
1082  return area;
1083  }
1084 
1085  return OPT_BOX2I();
1086 }
SHAPE_LINE_CHAIN & Simplify(bool aRemoveColinear=true)
Function Simplify()
const VECTOR2I & CPoint(int aIdx) const
Definition: pns_line.h:145
SHAPE_LINE_CHAIN m_line
The actual shape of the line.
Definition: pns_line.h:243
Definition: seg.h:41
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:302
SHAPE_LINE_CHAIN.
static void extendBox(BOX2I &aBox, bool &aDefined, const VECTOR2I &aP)
Definition: pns_line.cpp:994
int Width() const
Return true if the line is geometrically identical as line aOther.
Definition: pns_line.h:156
OPT< BOX2I > OPT_BOX2I
Definition: box2.h:525
bool Contains(const SEG &aSeg) const
Definition: seg.h:321

References SEG::Contains(), CPoint(), SHAPE_LINE_CHAIN::CPoint(), PNS::extendBox(), BOX2< Vec >::Inflate(), m_line, SHAPE_LINE_CHAIN::PointCount(), SHAPE_LINE_CHAIN::Simplify(), and Width().

Referenced by PNS::ChangedArea(), and PNS::DRAGGER::optimizeAndUpdateDraggedLine().

◆ ClassOf()

static bool PNS::LINE::ClassOf ( const ITEM aItem)
inlinestatic

Definition at line 110 of file pns_line.h.

111  {
112  return aItem && LINE_T == aItem->Kind();
113  }

References PNS::ITEM::Kind(), and PNS::ITEM::LINE_T.

◆ Clear()

void PNS::LINE::Clear ( )

Definition at line 1099 of file pns_line.cpp.

1100 {
1101  m_hasVia = false;
1102  m_line.Clear();
1103 }
SHAPE_LINE_CHAIN m_line
The actual shape of the line.
Definition: pns_line.h:243
bool m_hasVia
Optional via at the end point.
Definition: pns_line.h:249
void Clear()
Function Clear() Removes all points from the line chain.

References SHAPE_LINE_CHAIN::Clear(), m_hasVia, and m_line.

◆ ClearLinks()

◆ CLine()

const SHAPE_LINE_CHAIN& PNS::LINE::CLine ( ) const
inline

Definition at line 137 of file pns_line.h.

137 { return m_line; }
SHAPE_LINE_CHAIN m_line
The actual shape of the line.
Definition: pns_line.h:243

References m_line.

Referenced by PNS::COST_ESTIMATOR::Add(), PNS::DIFF_PAIR_PLACER::attemptWalk(), PNS::KEEP_TOPOLOGY_CONSTRAINT::Check(), PNS::NODE::CheckColliding(), PNS::SHOVE::checkShoveDirection(), PNS::COST_ESTIMATOR::CornerCost(), PNS::DIFF_PAIR::DIFF_PAIR(), PNS::MEANDER_PLACER::doMove(), PNS::DRAGGER::dragViaMarkObstacles(), PNS::DRAGGER::dragViaWalkaround(), PNS::OPTIMIZER::fanoutCleanup(), PNS::NODE::FindLinesBetweenJoints(), PNS::LINE_PLACER::FixRoute(), PNS::TOPOLOGY::followTrivialPath(), PNS::LINE_PLACER::Move(), PNS::NODE::NearestObstacle(), PNS::SHOVE::onCollidingArc(), PNS::SHOVE::onCollidingLine(), PNS::SHOVE::onCollidingSegment(), PNS::SHOVE::onCollidingSolid(), PNS::SHOVE::onReverseCollidingVia(), PNS::DRAGGER::optimizeAndUpdateDraggedLine(), PNS::LINE_PLACER::optimizeTailHeadTransition(), PNS::COST_ESTIMATOR::Remove(), PNS::LINE_PLACER::removeLoops(), PNS::COST_ESTIMATOR::Replace(), PNS_TEST_ENVIRONMENT::ReplayLog(), PNS::LINE_PLACER::rhShoveOnly(), PNS::LINE_PLACER::rhWalkOnly(), PNS::WALKAROUND::Route(), PNS::SHOVE::runOptimizer(), PNS::SHOVE::ShoveLines(), PNS::SHOVE::shoveLineToHullSet(), PNS::SHOVE::ShoveObstacleLine(), PNS::TOPOLOGY::SimplifyLine(), PNS::WALKAROUND::singleStep(), PNS::OPTIMIZER::smartPadsSingle(), PNS::Tighten(), PNS::LINE_PLACER::Trace(), PNS::DRAGGER::tryWalkaround(), and Walkaround().

◆ ClipToNearestObstacle()

const LINE PNS::LINE::ClipToNearestObstacle ( NODE aNode) const

Clip the line to a given range of vertices.

Definition at line 456 of file pns_line.cpp.

457 {
458  const int IterationLimit = 5;
459  int i;
460  LINE l( *this );
461 
462  for( i = 0; i < IterationLimit; i++ )
463  {
464  NODE::OPT_OBSTACLE obs = aNode->NearestObstacle( &l );
465 
466  if( obs )
467  {
468  l.RemoveVia();
469  int p = l.Line().Split( obs->m_ipFirst );
470  l.Line().Remove( p + 1, -1 );
471  } else
472  break;
473  }
474 
475  if( i == IterationLimit )
476  l.Line().Clear();
477 
478  return l;
479 }
LINE()
Makes an empty line.
Definition: pns_line.h:66
OPT< OBSTACLE > OPT_OBSTACLE
Definition: pns_node.h:152

References SHAPE_LINE_CHAIN::Clear(), Line(), PNS::NODE::NearestObstacle(), SHAPE_LINE_CHAIN::Remove(), RemoveVia(), and SHAPE_LINE_CHAIN::Split().

Referenced by PNS::LINE_PLACER::rhShoveOnly(), PNS::LINE_PLACER::rhWalkOnly(), and PNS::WALKAROUND::singleStep().

◆ ClipVertexRange()

void PNS::LINE::ClipVertexRange ( int  aStart,
int  aEnd 
)

Return the number of corners of angles specified by mask aAngles.

We need to figure out which joints to keep after the clip operation, because arcs will have multiple vertices. It is assumed that anything calling this method will have determined the vertex range to clip based on joints, meaning we will never clip in the middle of an arc. Clipping in the middle of an arc would break this and various other things...

Definition at line 912 of file pns_line.cpp.

913 {
920  int firstLink = 0;
921  int lastLink = std::max( 0, static_cast<int>( m_links.size() ) - 1 );
922  int arcIdx = -1;
923  int linkIdx = 0;
924 
925  auto shapes = m_line.CShapes();
926  int numPoints = static_cast<int>( shapes.size() );
927 
928  for( int i = 0; i < m_line.PointCount(); i++ )
929  {
930  if( i <= aStart )
931  firstLink = linkIdx;
932 
933  if( shapes[i] >= 0 )
934  {
935  // Account for "hidden segments" between two arcs
936  if( i > aStart && ( shapes[i - 1] >= 0 ) && ( shapes[i - 1] != shapes[i] ) )
937  linkIdx++;
938 
939  arcIdx = shapes[i];
940 
941  // Skip over the rest of the arc vertices
942  while( i < numPoints && shapes[i] == arcIdx )
943  i++;
944 
945  // Back up two vertices to restart at the segment coincident with the end of the arc
946  i -= 2;
947  }
948 
949  if( i >= aEnd - 1 || linkIdx >= lastLink )
950  {
951  lastLink = linkIdx;
952  break;
953  }
954 
955  linkIdx++;
956  }
957 
958  wxASSERT( lastLink >= firstLink );
959 
960  m_line = m_line.Slice( aStart, aEnd );
961 
962  if( IsLinked() )
963  {
964  wxASSERT( m_links.size() < INT_MAX );
965  wxASSERT( static_cast<int>( m_links.size() ) >= ( lastLink - firstLink ) );
966 
967  // Note: The range includes aEnd, but we have n-1 segments.
968  std::rotate(
969  m_links.begin(),
970  m_links.begin() + firstLink,
971  m_links.begin() + lastLink
972  );
973 
974  m_links.resize( lastLink - firstLink + 1 );
975  }
976 }
const SHAPE_LINE_CHAIN Slice(int aStartIndex, int aEndIndex=-1) const
Function Slice()
int PointCount() const
Function PointCount()
SHAPE_LINE_CHAIN m_line
The actual shape of the line.
Definition: pns_line.h:243
const std::vector< ssize_t > & CShapes() const

References SHAPE_LINE_CHAIN::CShapes(), PNS::LINK_HOLDER::IsLinked(), m_line, PNS::LINK_HOLDER::m_links, SHAPE_LINE_CHAIN::PointCount(), and SHAPE_LINE_CHAIN::Slice().

Referenced by PNS::NODE::FindLinesBetweenJoints().

◆ Clone()

LINE * PNS::LINE::Clone ( ) const
overridevirtual

Return a deep copy of the item.

Implements PNS::ITEM.

Definition at line 82 of file pns_line.cpp.

83 {
84  LINE* l = new LINE( *this );
85 
86  return l;
87 }
LINE()
Makes an empty line.
Definition: pns_line.h:66

References LINE().

Referenced by PNS::ITEM_SET::Add(), and PNS::ITEM_SET::Prepend().

◆ Collide()

bool PNS::ITEM::Collide ( const ITEM aOther,
const NODE aNode,
bool  aDifferentNetsOnly = true 
) const
inherited

Check for a collision (clearance violation) with between us and item aOther.

Collision checking takes all PCB stuff into account (layers, nets, DRC rules). Optionally returns a minimum translation vector for force propagation algorithm.

Parameters
aOtheris the item to check collision against.
Returns
true, if a collision was found.

Definition at line 97 of file pns_item.cpp.

98 {
99  if( collideSimple( aOther, aNode, aDifferentNetsOnly ) )
100  return true;
101 
102  // Special cases for "head" lines with vias attached at the end. Note that this does not
103  // support head-line-via to head-line-via collisions, but you can't route two independant
104  // tracks at once so it shouldn't come up.
105 
106  if( m_kind == LINE_T )
107  {
108  const LINE* line = static_cast<const LINE*>( this );
109 
110  if( line->EndsWithVia() && line->Via().collideSimple( aOther, aNode, aDifferentNetsOnly ) )
111  return true;
112  }
113 
114  if( aOther->m_kind == LINE_T )
115  {
116  const LINE* line = static_cast<const LINE*>( aOther );
117 
118  if( line->EndsWithVia() && line->Via().collideSimple( this, aNode, aDifferentNetsOnly ) )
119  return true;
120  }
121 
122  return false;
123 }
PnsKind m_kind
Definition: pns_item.h:235
bool collideSimple(const ITEM *aOther, const NODE *aNode, bool aDifferentNetsOnly) const
Definition: pns_item.cpp:31

References PNS::ITEM::collideSimple(), EndsWithVia(), PNS::ITEM::LINE_T, PNS::ITEM::m_kind, and Via().

Referenced by PNS::SHOVE::onCollidingSolid(), PNS::OPTIMIZER::CACHE_VISITOR::operator()(), PNS::NODE::DEFAULT_OBSTACLE_VISITOR::operator()(), PNS::SHOVE::shoveLineFromLoneVia(), PNS::SHOVE::shoveLineToHullSet(), and PNS::COMPONENT_DRAGGER::Start().

◆ CompareGeometry()

bool PNS::LINE::CompareGeometry ( const LINE aOther)

Reverse the point/vertex order.

Definition at line 856 of file pns_line.cpp.

857 {
858  return m_line.CompareGeometry( aOther.m_line );
859 }
SHAPE_LINE_CHAIN m_line
The actual shape of the line.
Definition: pns_line.h:243
bool CompareGeometry(const SHAPE_LINE_CHAIN &aOther) const

References SHAPE_LINE_CHAIN::CompareGeometry(), and m_line.

◆ ContainsLink()

bool PNS::LINK_HOLDER::ContainsLink ( const LINKED_ITEM aItem) const
inlineinherited

Definition at line 58 of file pns_link_holder.h.

59  {
60  return alg::contains( m_links, aItem );
61  }
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Definition: kicad_algo.h:81

References alg::contains(), and PNS::LINK_HOLDER::m_links.

◆ copyLinks()

void PNS::LINK_HOLDER::copyLinks ( const LINK_HOLDER aParent)
inlineprotectedinherited

< Copy m_links from the line aParent.

List of segments in the owning NODE (ITEM::m_owner) that constitute this line, or NULL if the line is not a part of any node.

Definition at line 98 of file pns_link_holder.h.

References PNS::LINK_HOLDER::m_links.

Referenced by LINE(), and operator=().

◆ CountCorners()

int PNS::LINE::CountCorners ( int  aAngles) const

Definition at line 136 of file pns_line.cpp.

137 {
138  int count = 0;
139 
140  for( int i = 0; i < m_line.SegmentCount() - 1; i++ )
141  {
142  const SEG seg1 = m_line.CSegment( i );
143  const SEG seg2 = m_line.CSegment( i + 1 );
144 
145  const DIRECTION_45 dir1( seg1 );
146  const DIRECTION_45 dir2( seg2 );
147 
148  DIRECTION_45::AngleType a = dir1.Angle( dir2 );
149 
150  if( a & aAngles )
151  count++;
152  }
153 
154  return count;
155 }
SHAPE_LINE_CHAIN m_line
The actual shape of the line.
Definition: pns_line.h:243
Represent route directions & corner angles in a 45-degree metric.
Definition: direction45.h:36
int SegmentCount() const
Function SegmentCount()
Definition: seg.h:41
AngleType
Represent kind of angle formed by vectors heading in two DIRECTION_45s.
Definition: direction45.h:65
const SEG CSegment(int aIndex) const
Function CSegment()

References DIRECTION_45::Angle(), SHAPE_LINE_CHAIN::CSegment(), m_line, and SHAPE_LINE_CHAIN::SegmentCount().

Referenced by PNS::LINE_PLACER::mergeHead(), and PNS::OPTIMIZER::smartPadsSingle().

◆ CPoint()

◆ CSegment()

const SEG PNS::LINE::CSegment ( int  aIdx) const
inline

◆ DragCorner()

void PNS::LINE::DragCorner ( const VECTOR2I aP,
int  aIndex,
bool  aFreeAngle = false 
)

Definition at line 594 of file pns_line.cpp.

595 {
596  if( aFreeAngle )
597  {
598  dragCornerFree( aP, aIndex );
599  }
600  else
601  {
602  dragCorner45( aP, aIndex );
603  }
604 }
void dragCorner45(const VECTOR2I &aP, int aIndex)
Definition: pns_line.cpp:565
void dragCornerFree(const VECTOR2I &aP, int aIndex)
Definition: pns_line.cpp:588

References dragCorner45(), and dragCornerFree().

Referenced by PNS::DRAGGER::dragMarkObstacles(), PNS::DRAGGER::dragShove(), PNS::DRAGGER::dragViaMarkObstacles(), PNS::DRAGGER::dragViaWalkaround(), and PNS::DRAGGER::dragWalkaround().

◆ dragCorner45()

void PNS::LINE::dragCorner45 ( const VECTOR2I aP,
int  aIndex 
)
private

Definition at line 565 of file pns_line.cpp.

566 {
567  SHAPE_LINE_CHAIN path;
568 
569  VECTOR2I snapped = snapDraggedCorner( m_line, aP, aIndex );
570 
571  if( aIndex == 0 )
572  path = dragCornerInternal( m_line.Reverse(), snapped ).Reverse();
573  else if( aIndex == m_line.SegmentCount() )
574  path = dragCornerInternal( m_line, snapped );
575  else
576  {
577  // fixme: awkward behaviour for "outwards" drags
578  path = dragCornerInternal( m_line.Slice( 0, aIndex ), snapped );
579  SHAPE_LINE_CHAIN path_rev =
580  dragCornerInternal( m_line.Slice( aIndex + 1, -1 ).Reverse(), snapped ).Reverse();
581  path.Append( path_rev );
582  }
583 
584  path.Simplify();
585  m_line = path;
586 }
SHAPE_LINE_CHAIN & Simplify(bool aRemoveColinear=true)
Function Simplify()
const SHAPE_LINE_CHAIN Slice(int aStartIndex, int aEndIndex=-1) const
Function Slice()
const SHAPE_LINE_CHAIN Reverse() const
Function Reverse()
void Append(int aX, int aY, bool aAllowDuplication=false)
Function Append()
SHAPE_LINE_CHAIN dragCornerInternal(const SHAPE_LINE_CHAIN &aOrigin, const VECTOR2I &aP)
Definition: pns_line.cpp:483
SHAPE_LINE_CHAIN m_line
The actual shape of the line.
Definition: pns_line.h:243
void Reverse()
Clip the line to the nearest obstacle, traversing from the line's start vertex (0).
Definition: pns_line.cpp:862
int SegmentCount() const
Function SegmentCount()
SHAPE_LINE_CHAIN.
VECTOR2I snapDraggedCorner(const SHAPE_LINE_CHAIN &aPath, const VECTOR2I &aP, int aIndex) const
Definition: pns_line.cpp:618

References SHAPE_LINE_CHAIN::Append(), PNS::dragCornerInternal(), m_line, Reverse(), SHAPE_LINE_CHAIN::Reverse(), SHAPE_LINE_CHAIN::SegmentCount(), SHAPE_LINE_CHAIN::Simplify(), SHAPE_LINE_CHAIN::Slice(), and snapDraggedCorner().

Referenced by DragCorner().

◆ dragCornerFree()

void PNS::LINE::dragCornerFree ( const VECTOR2I aP,
int  aIndex 
)
private

Definition at line 588 of file pns_line.cpp.

589 {
590  m_line.SetPoint( aIndex, aP );
591  m_line.Simplify();
592 }
SHAPE_LINE_CHAIN & Simplify(bool aRemoveColinear=true)
Function Simplify()
void SetPoint(int aIndex, const VECTOR2I &aPos)
Accessor Function to move a point to a specific location.
SHAPE_LINE_CHAIN m_line
The actual shape of the line.
Definition: pns_line.h:243

References m_line, SHAPE_LINE_CHAIN::SetPoint(), and SHAPE_LINE_CHAIN::Simplify().

Referenced by DragCorner().

◆ DragSegment()

void PNS::LINE::DragSegment ( const VECTOR2I aP,
int  aIndex,
bool  aFreeAngle = false 
)

Definition at line 606 of file pns_line.cpp.

607 {
608  if( aFreeAngle )
609  {
610  assert( false );
611  }
612  else
613  {
614  dragSegment45( aP, aIndex );
615  }
616 }
void dragSegment45(const VECTOR2I &aP, int aIndex)
Definition: pns_line.cpp:705

References dragSegment45().

Referenced by PNS::DRAGGER::dragMarkObstacles(), PNS::DRAGGER::dragShove(), and PNS::DRAGGER::dragWalkaround().

◆ dragSegment45()

void PNS::LINE::dragSegment45 ( const VECTOR2I aP,
int  aIndex 
)
private

Definition at line 705 of file pns_line.cpp.

706 {
707  SHAPE_LINE_CHAIN path( m_line );
708  VECTOR2I target( aP );
709 
710  SEG guideA[2], guideB[2];
711  int index = aIndex;
712 
713  target = snapToNeighbourSegments( path, aP, aIndex );
714 
715  if( index == 0 )
716  {
717  path.Insert( 0, path.CPoint( 0 ) );
718  index++;
719  }
720 
721  if( index == path.SegmentCount() - 1 )
722  {
723  path.Insert( path.PointCount() - 1, path.CPoint( -1 ) );
724  }
725 
726  SEG dragged = path.CSegment( index );
727  DIRECTION_45 drag_dir( dragged );
728 
729  SEG s_prev = path.CSegment( index - 1 );
730  SEG s_next = path.CSegment( index + 1 );
731 
732  DIRECTION_45 dir_prev( s_prev );
733  DIRECTION_45 dir_next( s_next );
734 
735  if( dir_prev == drag_dir )
736  {
737  dir_prev = dir_prev.Left();
738  path.Insert( index, path.CPoint( index ) );
739  index++;
740  }
741 
742  if( dir_next == drag_dir )
743  {
744  dir_next = dir_next.Right();
745  path.Insert( index + 1, path.CPoint( index + 1 ) );
746  }
747 
748  s_prev = path.CSegment( index - 1 );
749  s_next = path.CSegment( index + 1 );
750  dragged = path.CSegment( index );
751 
752  if( aIndex == 0 )
753  {
754  guideA[0] = SEG( dragged.A, dragged.A + drag_dir.Right().ToVector() );
755  guideA[1] = SEG( dragged.A, dragged.A + drag_dir.Left().ToVector() );
756  }
757  else
758  {
759  if( dir_prev.Angle( drag_dir )
761  {
762  guideA[0] = SEG( s_prev.A, s_prev.A + drag_dir.Left().ToVector() );
763  guideA[1] = SEG( s_prev.A, s_prev.A + drag_dir.Right().ToVector() );
764  }
765  else
766  guideA[0] = guideA[1] = SEG( dragged.A, dragged.A + dir_prev.ToVector() );
767  }
768 
769  if( aIndex == m_line.SegmentCount() - 1 )
770  {
771  guideB[0] = SEG( dragged.B, dragged.B + drag_dir.Right().ToVector() );
772  guideB[1] = SEG( dragged.B, dragged.B + drag_dir.Left().ToVector() );
773  }
774  else
775  {
776  if( dir_next.Angle( drag_dir )
778  {
779  guideB[0] = SEG( s_next.B, s_next.B + drag_dir.Left().ToVector() );
780  guideB[1] = SEG( s_next.B, s_next.B + drag_dir.Right().ToVector() );
781  }
782  else
783  guideB[0] = guideB[1] = SEG( dragged.B, dragged.B + dir_next.ToVector() );
784  }
785 
786  SEG s_current( target, target + drag_dir.ToVector() );
787 
788  int best_len = INT_MAX;
789  SHAPE_LINE_CHAIN best;
790 
791  for( int i = 0; i < 2; i++ )
792  {
793  for( int j = 0; j < 2; j++ )
794  {
795  OPT_VECTOR2I ip1 = s_current.IntersectLines( guideA[i] );
796  OPT_VECTOR2I ip2 = s_current.IntersectLines( guideB[j] );
797 
798  SHAPE_LINE_CHAIN np;
799 
800  if( !ip1 || !ip2 )
801  continue;
802 
803  SEG s1( s_prev.A, *ip1 );
804  SEG s2( *ip1, *ip2 );
805  SEG s3( *ip2, s_next.B );
806 
807  OPT_VECTOR2I ip;
808 
809  if( ( ip = s1.Intersect( s_next ) ) )
810  {
811  np.Append( s1.A );
812  np.Append( *ip );
813  np.Append( s_next.B );
814  }
815  else if( ( ip = s3.Intersect( s_prev ) ) )
816  {
817  np.Append( s_prev.A );
818  np.Append( *ip );
819  np.Append( s3.B );
820  }
821  else if( ( ip = s1.Intersect( s3 ) ) )
822  {
823  np.Append( s_prev.A );
824  np.Append( *ip );
825  np.Append( s_next.B );
826  }
827  else
828  {
829  np.Append( s_prev.A );
830  np.Append( *ip1 );
831  np.Append( *ip2 );
832  np.Append( s_next.B );
833  }
834 
835  if( np.Length() < best_len )
836  {
837  best_len = np.Length();
838  best = np;
839  }
840  }
841  }
842 
843  if( m_line.PointCount() == 1 )
844  m_line = best;
845  else if( aIndex == 0 )
846  m_line.Replace( 0, 1, best );
847  else if( aIndex == m_line.SegmentCount() - 1 )
848  m_line.Replace( -2, -1, best );
849  else
850  m_line.Replace( aIndex, aIndex + 1, best );
851 
852  m_line.Simplify();
853 }
long long int Length() const
Function Length()
SHAPE_LINE_CHAIN & Simplify(bool aRemoveColinear=true)
Function Simplify()
VECTOR2I snapToNeighbourSegments(const SHAPE_LINE_CHAIN &aPath, const VECTOR2I &aP, int aIndex) const
Definition: pns_line.cpp:660
int PointCount() const
Function PointCount()
void Append(int aX, int aY, bool aAllowDuplication=false)
Function Append()
SHAPE_LINE_CHAIN m_line
The actual shape of the line.
Definition: pns_line.h:243
OPT< VECTOR2I > OPT_VECTOR2I
Definition: seg.h:39
Represent route directions & corner angles in a 45-degree metric.
Definition: direction45.h:36
int SegmentCount() const
Function SegmentCount()
Definition: seg.h:41
SHAPE_LINE_CHAIN.
VECTOR2I A
Definition: seg.h:49
void Replace(int aStartIndex, int aEndIndex, const VECTOR2I &aP)
Function Replace()
VECTOR2I B
Definition: seg.h:50

References SEG::A, DIRECTION_45::ANG_HALF_FULL, DIRECTION_45::ANG_OBTUSE, DIRECTION_45::Angle(), SHAPE_LINE_CHAIN::Append(), SEG::B, SHAPE_LINE_CHAIN::CPoint(), SHAPE_LINE_CHAIN::CSegment(), SHAPE_LINE_CHAIN::Insert(), SEG::Intersect(), DIRECTION_45::Left(), SHAPE_LINE_CHAIN::Length(), m_line, SHAPE_LINE_CHAIN::PointCount(), SHAPE_LINE_CHAIN::Replace(), DIRECTION_45::Right(), SHAPE_LINE_CHAIN::SegmentCount(), SHAPE_LINE_CHAIN::Simplify(), snapToNeighbourSegments(), and DIRECTION_45::ToVector().

Referenced by DragSegment().

◆ dragSegmentFree()

void PNS::LINE::dragSegmentFree ( const VECTOR2I aP,
int  aIndex 
)
private

◆ EndsWithVia()

◆ GetBlockingObstacle()

ITEM* PNS::LINE::GetBlockingObstacle ( ) const
inline

Definition at line 206 of file pns_line.h.

206 { return m_blockingObstacle; }
ITEM * m_blockingObstacle
For mark obstacle mode.
Definition: pns_line.h:252

References m_blockingObstacle.

Referenced by PNS::ROUTER::markViolations().

◆ GetLink()

LINKED_ITEM* PNS::LINK_HOLDER::GetLink ( int  aIndex) const
inlineinherited

Erase the linking information. Used to detach the line from the owning node.

Definition at line 63 of file pns_link_holder.h.

References PNS::LINK_HOLDER::m_links.

Referenced by PNS::LINE_PLACER::removeLoops(), PNS::TOPOLOGY::SimplifyLine(), PNS::MEANDER_SKEW_PLACER::Start(), and PNS::DP_MEANDER_PLACER::Start().

◆ GetSnapThreshhold()

int PNS::LINE::GetSnapThreshhold ( ) const
inline

Definition at line 226 of file pns_line.h.

227  {
228  return m_snapThreshhold;
229  }
int m_snapThreshhold
Width to smooth out jagged segments.
Definition: pns_line.h:247

References m_snapThreshhold.

◆ HasLockedSegments()

bool PNS::LINE::HasLockedSegments ( ) const

Definition at line 1089 of file pns_line.cpp.

1090 {
1091  for( const auto seg : m_links )
1092  {
1093  if( seg->Marker() & MK_LOCKED )
1094  return true;
1095  }
1096  return false;
1097 }

References PNS::LINK_HOLDER::m_links, and PNS::MK_LOCKED.

Referenced by PNS::SHOVE::onCollidingArc(), and PNS::SHOVE::onCollidingSegment().

◆ HasLoops()

bool PNS::LINE::HasLoops ( ) const

Definition at line 979 of file pns_line.cpp.

980 {
981  for( int i = 0; i < PointCount(); i++ )
982  {
983  for( int j = i + 2; j < PointCount(); j++ )
984  {
985  if( CPoint( i ) == CPoint( j ) )
986  return true;
987  }
988  }
989 
990  return false;
991 }
int PointCount() const
Definition: pns_line.h:140
const VECTOR2I & CPoint(int aIdx) const
Definition: pns_line.h:145

References CPoint(), and PointCount().

Referenced by PNS::SHOVE::onCollidingSolid(), and PNS::LINE_PLACER::rhShoveOnly().

◆ Hole()

virtual const SHAPE* PNS::ITEM::Hole ( ) const
inlinevirtualinherited

Reimplemented in PNS::VIA, and PNS::SOLID.

Definition at line 201 of file pns_item.h.

202  {
203  return nullptr;
204  }

Referenced by PNS::ITEM::collideSimple().

◆ HoleHull()

virtual const SHAPE_LINE_CHAIN PNS::ITEM::HoleHull ( int  aClearance,
int  aWalkaroundThickness,
int  aLayer 
) const
inlinevirtualinherited

Reimplemented in PNS::SOLID.

Definition at line 117 of file pns_item.h.

119  {
120  return SHAPE_LINE_CHAIN();
121  }
SHAPE_LINE_CHAIN.

◆ Hull()

virtual const SHAPE_LINE_CHAIN PNS::ITEM::Hull ( int  aClearance = 0,
int  aWalkaroundThickness = 0,
int  aLayer = -1 
) const
inlinevirtualinherited

Reimplemented in PNS::VIA, PNS::SEGMENT, PNS::ARC, and PNS::SOLID.

Definition at line 111 of file pns_item.h.

113  {
114  return SHAPE_LINE_CHAIN();
115  }
SHAPE_LINE_CHAIN.

◆ Is45Degree()

bool PNS::LINE::Is45Degree ( ) const

Print out all linked segments.

Definition at line 427 of file pns_line.cpp.

428 {
429  for( int i = 0; i < m_line.SegmentCount(); i++ )
430  {
431  const SEG& s = m_line.CSegment( i );
432 
433  if( m_line.isArc( i ) )
434  continue;
435 
436  if( s.Length() < 10 )
437  continue;
438 
439  double angle = 180.0 / M_PI *
440  atan2( (double) s.B.y - (double) s.A.y,
441  (double) s.B.x - (double) s.A.x );
442 
443  if( angle < 0 )
444  angle += 360.0;
445 
446  double angle_a = fabs( fmod( angle, 45.0 ) );
447 
448  if( angle_a > 1.0 && angle_a < 44.0 )
449  return false;
450  }
451 
452  return true;
453 }
int Length() const
Return the length (this).
Definition: seg.h:340
bool isArc(size_t aSegment) const
SHAPE_LINE_CHAIN m_line
The actual shape of the line.
Definition: pns_line.h:243
int SegmentCount() const
Function SegmentCount()
Definition: seg.h:41
const SEG CSegment(int aIndex) const
Function CSegment()
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
VECTOR2I A
Definition: seg.h:49
VECTOR2I B
Definition: seg.h:50

References SEG::A, PNS::angle(), SEG::B, SHAPE_LINE_CHAIN::CSegment(), SHAPE_LINE_CHAIN::isArc(), SEG::Length(), m_line, SHAPE_LINE_CHAIN::SegmentCount(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by PNS::LINE_PLACER::routeStep().

◆ IsLinked()

bool PNS::LINK_HOLDER::IsLinked ( ) const
inlineinherited

◆ IsLinkedChecked()

bool PNS::LINE::IsLinkedChecked ( ) const
inline

Assign a shape to the line (a polyline/line chain).

Definition at line 120 of file pns_line.h.

References PNS::LINK_HOLDER::IsLinked(), PNS::LINK_HOLDER::LinkCount(), and SegmentCount().

Referenced by PNS::SHOVE::pushLineStack().

◆ IsLocked()

bool PNS::ITEM::IsLocked ( ) const
inlineinherited

Definition at line 223 of file pns_item.h.

224  {
225  return Marker() & MK_LOCKED;
226  }
virtual int Marker() const
Definition: pns_item.h:208

References PNS::ITEM::Marker(), and PNS::MK_LOCKED.

Referenced by ROUTER_TOOL::InlineBreakTrack(), ROUTER_TOOL::performDragging(), and PNS::SHOVE::pushOrShoveVia().

◆ IsRoutable()

bool PNS::ITEM::IsRoutable ( ) const
inlineinherited

Definition at line 229 of file pns_item.h.

229 { return m_routable; }
bool m_routable
Definition: pns_item.h:245

References PNS::ITEM::m_routable.

Referenced by PNS::NODE::addSolid(), and PNS::NODE::removeSolidIndex().

◆ Kind()

◆ KindStr()

std::string PNS::ITEM::KindStr ( ) const
inherited

Returns the kind of the item, as string.

Definition at line 126 of file pns_item.cpp.

127 {
128  switch( m_kind )
129  {
130  case ARC_T: return "arc";
131  case LINE_T: return "line";
132  case SEGMENT_T: return "segment";
133  case VIA_T: return "via";
134  case JOINT_T: return "joint";
135  case SOLID_T: return "solid";
136  case DIFF_PAIR_T: return "diff-pair";
137  default: return "unknown";
138  }
139 }
PnsKind m_kind
Definition: pns_item.h:235

References PNS::ITEM::ARC_T, PNS::ITEM::DIFF_PAIR_T, PNS::ITEM::JOINT_T, PNS::ITEM::LINE_T, PNS::ITEM::m_kind, PNS::ITEM::SEGMENT_T, PNS::ITEM::SOLID_T, and PNS::ITEM::VIA_T.

Referenced by PNS::TOOL_BASE::pickSingleItem(), and PNS::TOOL_BASE::updateEndItem().

◆ Layer()

◆ Layers()

const LAYER_RANGE& PNS::ITEM::Layers ( ) const
inlineinherited

Definition at line 150 of file pns_item.h.

150 { return m_layers; }
LAYER_RANGE m_layers
Definition: pns_item.h:239

References PNS::ITEM::m_layers.

Referenced by PNS::INDEX::Add(), PNS::NODE::Add(), PNS::NODE::addArc(), PNS_KICAD_IFACE::AddItem(), PNS::NODE::addSegment(), PNS::NODE::addSolid(), PNS::NODE::addVia(), PNS::ARC::ARC(), PNS::TOPOLOGY::AssembleDiffPair(), PNS::NODE::AssembleLine(), PNS::KEEP_TOPOLOGY_CONSTRAINT::Check(), PNS_PCBNEW_RULE_RESOLVER::Clearance(), PNS::VIA::Clone(), PNS::ITEM::collideSimple(), PNS::MEANDER_PLACER::CurrentLayer(), PNS::DP_MEANDER_PLACER::CurrentLayer(), PNS::DIFF_PAIR_PLACER::FindDpPrimitivePair(), PNS::NODE::FindJoint(), PNS::NODE::FindLinesBetweenJoints(), PNS::NODE::findRedundantArc(), PNS::NODE::findRedundantSegment(), ROUTER_TOOL::getStartLayer(), PNS_PCBNEW_RULE_RESOLVER::HoleClearance(), PNS_PCBNEW_RULE_RESOLVER::HoleToHoleClearance(), PNS_KICAD_IFACE::IsFlashedOnLayer(), PNS::ITEM::Layer(), PNS::ITEM::LayersOverlap(), LINE(), PNS::NODE::LockJoint(), PNS::VIA::MakeHandle(), PNS::ROUTER::markViolations(), PNS::SHOVE::onCollidingSolid(), LENGTH_TUNER_TOOL::performTuning(), PNS::TOOL_BASE::pickSingleItem(), PNS::INDEX::Query(), PNS::INDEX::Remove(), PNS::NODE::removeArcIndex(), PNS::NODE::removeSegmentIndex(), PNS::NODE::removeSolidIndex(), PNS::NODE::removeViaIndex(), PNS_TEST_ENVIRONMENT::ReplayLog(), PNS::SEGMENT::SEGMENT(), PNS::LINE_PLACER::SetLayer(), ROUTER_PREVIEW_ITEM::Update(), PNS::TOOL_BASE::updateEndItem(), PNS_KICAD_IFACE::UpdateItem(), PNS::DIFF_PAIR::updateLine(), PNS::TOOL_BASE::updateStartItem(), and PNS::VIA::VIA().

◆ LayersOverlap()

bool PNS::ITEM::LayersOverlap ( const ITEM aOther) const
inlineinherited

Return true if the set of layers spanned by aOther overlaps our layers.

Definition at line 159 of file pns_item.h.

160  {
161  return Layers().Overlaps( aOther->Layers() );
162  }
bool Overlaps(const LAYER_RANGE &aOther) const
Definition: pns_layerset.h:67
const LAYER_RANGE & Layers() const
Definition: pns_item.h:150

References PNS::ITEM::Layers(), and LAYER_RANGE::Overlaps().

Referenced by PNS::SHOVE::onCollidingArc(), PNS::SHOVE::onCollidingSegment(), PNS::NODE::rebuildJoint(), and PNS::SHOVE::ShoveObstacleLine().

◆ Line()

◆ Link()

void PNS::LINK_HOLDER::Link ( LINKED_ITEM aLink)
inlineinherited

Return the list of links from the owning node that constitute this line (or NULL if the line is not linked).

Definition at line 42 of file pns_link_holder.h.

References PNS::LINK_HOLDER::m_links.

Referenced by PNS::NODE::Add(), and PNS::NODE::AssembleLine().

◆ LinkCount()

int PNS::LINK_HOLDER::LinkCount ( ) const
inlineinherited

Definition at line 75 of file pns_link_holder.h.

76  {
77  return m_links.size();
78  }

References PNS::LINK_HOLDER::m_links.

Referenced by IsLinkedChecked(), and PNS::LINE_PLACER::removeLoops().

◆ Links() [1/2]

◆ Links() [2/2]

const LINKS& PNS::LINK_HOLDER::Links ( ) const
inlineinherited

Definition at line 50 of file pns_link_holder.h.

50 { return m_links; }

References PNS::LINK_HOLDER::m_links.

◆ Mark()

void PNS::LINE::Mark ( int  aMarker) const
overridevirtual

Reimplemented from PNS::ITEM.

Definition at line 90 of file pns_line.cpp.

91 {
92  m_marker = aMarker;
93 
94  for( const LINKED_ITEM* s : m_links )
95  s->Mark( aMarker );
96 
97 }
int m_marker
Definition: pns_item.h:243

References PNS::LINK_HOLDER::m_links, and PNS::ITEM::m_marker.

Referenced by PNS::SHOVE::onCollidingSolid(), PNS::SHOVE::ShoveLines(), PNS::SHOVE::ShoveMultiLines(), and PNS::SHOVE::ShoveObstacleLine().

◆ Marker()

int PNS::LINE::Marker ( ) const
overridevirtual

Reimplemented from PNS::ITEM.

Definition at line 109 of file pns_line.cpp.

110 {
111  int marker = m_marker;
112 
113  for( auto s : m_links )
114  {
115  marker |= s->Marker();
116  }
117 
118  return marker;
119 }
int m_marker
Definition: pns_item.h:243

References PNS::LINK_HOLDER::m_links, and PNS::ITEM::m_marker.

Referenced by PNS::ARC::ARC(), PNS::SHOVE::onCollidingArc(), PNS::SHOVE::onCollidingLine(), PNS::SHOVE::onCollidingSegment(), PNS::SHOVE::onCollidingSolid(), PNS::SEGMENT::SEGMENT(), PNS::SHOVE::shoveLineToHullSet(), and PNS::SHOVE::ShoveObstacleLine().

◆ Net()

int PNS::ITEM::Net ( ) const
inlineinherited

◆ OfKind()

◆ operator=()

LINE & PNS::LINE::operator= ( const LINE aOther)

Definition at line 61 of file pns_line.cpp.

62 {
63  m_line = aOther.m_line;
64  m_width = aOther.m_width;
65  m_net = aOther.m_net;
66  m_movable = aOther.m_movable;
67  m_layers = aOther.m_layers;
68  m_via = aOther.m_via;
69  m_hasVia = aOther.m_hasVia;
70  m_marker = aOther.m_marker;
71  m_rank = aOther.m_rank;
72  m_owner = aOther.m_owner;
73  m_snapThreshhold = aOther.m_snapThreshhold;
74  m_blockingObstacle = aOther.m_blockingObstacle;
75 
76  copyLinks( &aOther );
77 
78  return *this;
79 }
VIA m_via
Definition: pns_line.h:250
NODE * m_owner
Definition: pns_item.h:238
LAYER_RANGE m_layers
Definition: pns_item.h:239
int m_rank
Definition: pns_item.h:244
bool m_movable
Definition: pns_item.h:241
int m_marker
Definition: pns_item.h:243
ITEM * m_blockingObstacle
For mark obstacle mode.
Definition: pns_line.h:252
SHAPE_LINE_CHAIN m_line
The actual shape of the line.
Definition: pns_line.h:243
bool m_hasVia
Optional via at the end point.
Definition: pns_line.h:249
int m_net
Definition: pns_item.h:242
int m_snapThreshhold
Width to smooth out jagged segments.
Definition: pns_line.h:247
int m_width
Our width.
Definition: pns_line.h:244

References PNS::LINK_HOLDER::copyLinks(), m_blockingObstacle, m_hasVia, PNS::ITEM::m_layers, m_line, PNS::ITEM::m_marker, PNS::ITEM::m_movable, PNS::ITEM::m_net, PNS::ITEM::m_owner, PNS::ITEM::m_rank, m_snapThreshhold, m_via, and m_width.

◆ Owner()

NODE* PNS::ITEM::Owner ( ) const
inlineinherited

Return the owner of this item, or NULL if there's none.

Definition at line 167 of file pns_item.h.

167 { return m_owner; }
NODE * m_owner
Definition: pns_item.h:238

References PNS::ITEM::m_owner.

Referenced by PNS_KICAD_IFACE_BASE::inheritTrackWidth(), and PNS::LINE_PLACER::Move().

◆ Parent()

◆ PointCount()

◆ Rank()

int PNS::LINE::Rank ( ) const
overridevirtual

Reimplemented from PNS::ITEM.

Definition at line 893 of file pns_line.cpp.

894 {
895  int min_rank = INT_MAX;
896 
897  if( IsLinked() ) {
898  for( auto s : m_links )
899  {
900  min_rank = std::min( min_rank, s->Rank() );
901  }
902  } else {
903  min_rank = m_rank;
904  }
905 
906  int rank = ( min_rank == INT_MAX ) ? -1 : min_rank;
907 
908  return rank;
909 }
int m_rank
Definition: pns_item.h:244

References PNS::LINK_HOLDER::IsLinked(), PNS::LINK_HOLDER::m_links, and PNS::ITEM::m_rank.

Referenced by PNS::ARC::ARC(), PNS::SHOVE::onCollidingArc(), PNS::SHOVE::onCollidingLine(), PNS::SHOVE::onCollidingSegment(), PNS::SHOVE::onCollidingSolid(), PNS::SHOVE::onReverseCollidingVia(), PNS::SEGMENT::SEGMENT(), and PNS::SHOVE::shoveIteration().

◆ RemoveVia()

void PNS::LINE::RemoveVia ( )
inline

◆ Reverse()

void PNS::LINE::Reverse ( )

Clip the line to the nearest obstacle, traversing from the line's start vertex (0).

Returns the clipped line.

Definition at line 862 of file pns_line.cpp.

863 {
864  m_line = m_line.Reverse();
865 
866  std::reverse( m_links.begin(), m_links.end() );
867 }
const SHAPE_LINE_CHAIN Reverse() const
Function Reverse()
SHAPE_LINE_CHAIN m_line
The actual shape of the line.
Definition: pns_line.h:243

References m_line, PNS::LINK_HOLDER::m_links, and SHAPE_LINE_CHAIN::Reverse().

Referenced by AppendVia(), dragCorner45(), PNS::DRAGGER::findViaFanoutByHandle(), and PNS::TOPOLOGY::followTrivialPath().

◆ SegmentCount()

◆ SetBlockingObstacle()

void PNS::LINE::SetBlockingObstacle ( ITEM aObstacle)
inline

Definition at line 205 of file pns_line.h.

205 { m_blockingObstacle = aObstacle; }
ITEM * m_blockingObstacle
For mark obstacle mode.
Definition: pns_line.h:252

References m_blockingObstacle.

Referenced by PNS::LINE_PLACER::rhMarkObstacles().

◆ SetLayer()

◆ SetLayers()

void PNS::ITEM::SetLayers ( const LAYER_RANGE aLayers)
inlineinherited

Definition at line 151 of file pns_item.h.

151 { m_layers = aLayers; }
LAYER_RANGE m_layers
Definition: pns_item.h:239

References PNS::ITEM::m_layers.

Referenced by PNS::TOPOLOGY::AssembleDiffPair(), PNS::NODE::AssembleLine(), PNS::VIA::Clone(), and PNS::VIA::VIA().

◆ SetNet()

◆ SetOwner()

void PNS::ITEM::SetOwner ( NODE aOwner)
inlineinherited

Set the node that owns this item.

An item can belong to a single NODE or be unowned.

Definition at line 172 of file pns_item.h.

172 { m_owner = aOwner; }
NODE * m_owner
Definition: pns_item.h:238

References PNS::ITEM::m_owner.

Referenced by PNS::NODE::AssembleLine(), PNS::NODE::doRemove(), and PNS::NODE::Remove().

◆ SetParent()

void PNS::ITEM::SetParent ( BOARD_ITEM aParent)
inlineinherited

Definition at line 144 of file pns_item.h.

144 { m_parent = aParent; }
BOARD_ITEM * m_parent
Definition: pns_item.h:237

References PNS::ITEM::m_parent.

Referenced by PNS_KICAD_IFACE::AddItem().

◆ SetRank()

void PNS::LINE::SetRank ( int  aRank)
overridevirtual

Reimplemented from PNS::ITEM.

Definition at line 883 of file pns_line.cpp.

884 {
885  m_rank = aRank;
886 
887  for( auto s : m_links )
888  s->SetRank( aRank );
889 
890 }
int m_rank
Definition: pns_item.h:244

References PNS::LINK_HOLDER::m_links, and PNS::ITEM::m_rank.

Referenced by PNS::SHOVE::onCollidingArc(), PNS::SHOVE::onCollidingLine(), PNS::SHOVE::onCollidingSegment(), PNS::SHOVE::onCollidingSolid(), PNS::SHOVE::onReverseCollidingVia(), PNS::SHOVE::ShoveLines(), and PNS::SHOVE::ShoveMultiLines().

◆ SetRoutable()

void PNS::ITEM::SetRoutable ( bool  aRoutable)
inlineinherited

Definition at line 228 of file pns_item.h.

228 { m_routable = aRoutable; }
bool m_routable
Definition: pns_item.h:245

References PNS::ITEM::m_routable.

◆ SetShape()

◆ SetSnapThreshhold()

void PNS::LINE::SetSnapThreshhold ( int  aThreshhold)
inline

Definition at line 221 of file pns_line.h.

222  {
223  m_snapThreshhold = aThreshhold;
224  }
int m_snapThreshhold
Width to smooth out jagged segments.
Definition: pns_line.h:247

References m_snapThreshhold.

Referenced by PNS::DRAGGER::dragMarkObstacles(), PNS::DRAGGER::dragShove(), and PNS::DRAGGER::dragWalkaround().

◆ SetViaDiameter()

void PNS::LINE::SetViaDiameter ( int  aDiameter)
inline

Definition at line 198 of file pns_line.h.

198 { m_via.SetDiameter( aDiameter ); }
VIA m_via
Definition: pns_line.h:250
void SetDiameter(int aDiameter)
Definition: pns_via.h:109

References m_via, and PNS::VIA::SetDiameter().

Referenced by PNS::LINE_PLACER::UpdateSizes().

◆ SetViaDrill()

void PNS::LINE::SetViaDrill ( int  aDrill)
inline

Definition at line 199 of file pns_line.h.

199 { m_via.SetDrill( aDrill ); }
VIA m_via
Definition: pns_line.h:250
void SetDrill(int aDrill)
Definition: pns_via.h:116

References m_via, and PNS::VIA::SetDrill().

Referenced by PNS::LINE_PLACER::UpdateSizes().

◆ SetWidth()

void PNS::LINE::SetWidth ( int  aWidth)
inline

◆ Shape()

const SHAPE* PNS::LINE::Shape ( ) const
inlineoverridevirtual

Modifiable accessor to the underlying shape.

Reimplemented from PNS::ITEM.

Definition at line 133 of file pns_line.h.

References m_line.

Referenced by PNS::SHOVE::onCollidingVia().

◆ ShapeCount()

int PNS::LINE::ShapeCount ( ) const
inline

Return the aIdx-th point of the line.

Definition at line 142 of file pns_line.h.

References m_line, and SHAPE_LINE_CHAIN::ShapeCount().

Referenced by PNS::LINE_PLACER::routeStep().

◆ ShowLinks()

void PNS::LINE::ShowLinks ( ) const

◆ snapDraggedCorner()

VECTOR2I PNS::LINE::snapDraggedCorner ( const SHAPE_LINE_CHAIN aPath,
const VECTOR2I aP,
int  aIndex 
) const
private

Definition at line 618 of file pns_line.cpp.

620 {
621  int s_start = std::max( aIndex - 2, 0 );
622  int s_end = std::min( aIndex + 2, aPath.SegmentCount() - 1 );
623 
624  int i, j;
625  int best_dist = INT_MAX;
626  VECTOR2I best_snap = aP;
627 
628  if( m_snapThreshhold <= 0 )
629  return aP;
630 
631  for( i = s_start; i <= s_end; i++ )
632  {
633  const SEG& a = aPath.CSegment( i );
634 
635  for( j = s_start; j < i; j++ )
636  {
637  const SEG& b = aPath.CSegment( j );
638 
639  if( !( DIRECTION_45( a ).IsObtuse( DIRECTION_45( b ) ) ) )
640  continue;
641 
642  OPT_VECTOR2I ip = a.IntersectLines( b );
643 
644  if( ip )
645  {
646  int dist = ( *ip - aP ).EuclideanNorm();
647 
648  if( dist < m_snapThreshhold && dist < best_dist )
649  {
650  best_dist = dist;
651  best_snap = *ip;
652  }
653  }
654  }
655  }
656 
657  return best_snap;
658 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:148
OPT_VECTOR2I IntersectLines(const SEG &aSeg) const
Compute the intersection point of lines passing through ends of (this) and aSeg.
Definition: seg.h:193
OPT< VECTOR2I > OPT_VECTOR2I
Definition: seg.h:39
Represent route directions & corner angles in a 45-degree metric.
Definition: direction45.h:36
int SegmentCount() const
Function SegmentCount()
Definition: seg.h:41
const SEG CSegment(int aIndex) const
Function CSegment()
int m_snapThreshhold
Width to smooth out jagged segments.
Definition: pns_line.h:247

References SHAPE_LINE_CHAIN::CSegment(), EuclideanNorm(), SEG::IntersectLines(), m_snapThreshhold, and SHAPE_LINE_CHAIN::SegmentCount().

Referenced by dragCorner45().

◆ snapToNeighbourSegments()

VECTOR2I PNS::LINE::snapToNeighbourSegments ( const SHAPE_LINE_CHAIN aPath,
const VECTOR2I aP,
int  aIndex 
) const
private

Definition at line 660 of file pns_line.cpp.

662 {
663  VECTOR2I snap_p[2];
664  DIRECTION_45 dragDir( aPath.CSegment( aIndex ) );
665  int snap_d[2] = { -1, -1 };
666 
667  if( m_snapThreshhold == 0 )
668  return aP;
669 
670  if( aIndex >= 2 )
671  {
672  SEG s = aPath.CSegment( aIndex - 2 );
673 
674  if( DIRECTION_45( s ) == dragDir )
675  snap_d[0] = s.LineDistance( aP );
676 
677  snap_p[0] = s.A;
678  }
679 
680  if( aIndex < aPath.SegmentCount() - 2 )
681  {
682  SEG s = aPath.CSegment( aIndex + 2 );
683 
684  if( DIRECTION_45( s ) == dragDir )
685  snap_d[1] = s.LineDistance( aP );
686 
687  snap_p[1] = s.A;
688  }
689 
690  VECTOR2I best = aP;
691  int minDist = INT_MAX;
692 
693  for( int i = 0; i < 2; i++ )
694  {
695  if( snap_d[i] >= 0 && snap_d[i] < minDist && snap_d[i] <= m_snapThreshhold )
696  {
697  minDist = snap_d[i];
698  best = snap_p[i];
699  }
700  }
701 
702  return best;
703 }
int LineDistance(const VECTOR2I &aP, bool aDetermineSide=false) const
Return the closest Euclidean distance between point aP and the line defined by the ends of segment (t...
Definition: seg.h:405
Represent route directions & corner angles in a 45-degree metric.
Definition: direction45.h:36
int SegmentCount() const
Function SegmentCount()
Definition: seg.h:41
const SEG CSegment(int aIndex) const
Function CSegment()
int m_snapThreshhold
Width to smooth out jagged segments.
Definition: pns_line.h:247
VECTOR2I A
Definition: seg.h:49

References SEG::A, SHAPE_LINE_CHAIN::CSegment(), SEG::LineDistance(), m_snapThreshhold, and SHAPE_LINE_CHAIN::SegmentCount().

Referenced by dragSegment45().

◆ Unmark()

void PNS::LINE::Unmark ( int  aMarker = -1) const
overridevirtual

Reimplemented from PNS::ITEM.

Definition at line 100 of file pns_line.cpp.

101 {
102  for( const LINKED_ITEM* s : m_links )
103  s->Unmark( aMarker );
104 
105  m_marker = 0;
106 }
int m_marker
Definition: pns_item.h:243

References PNS::LINK_HOLDER::m_links, and PNS::ITEM::m_marker.

Referenced by PNS::DRAGGER::dragShove(), PNS::SHOVE::onCollidingSolid(), and PNS::DRAGGER::optimizeAndUpdateDraggedLine().

◆ Via()

◆ Walkaround() [1/2]

bool PNS::LINE::Walkaround ( SHAPE_LINE_CHAIN  aObstacle,
SHAPE_LINE_CHAIN aPre,
SHAPE_LINE_CHAIN aWalk,
SHAPE_LINE_CHAIN aPost,
bool  aCw 
) const

Calculate a line tightly wrapping a convex hull of an obstacle object (aObstacle).

Parameters
aPrePathis the path from origin to the obstacle.
aWalkaroundPathis the path around the obstacle.
aPostPathis the path from obstacle till the end.
aCWdetermines whether to walk around in clockwise or counter-clockwise direction.

Referenced by PNS::SHOVE::shoveLineFromLoneVia(), PNS::SHOVE::shoveLineToHullSet(), PNS::WALKAROUND::singleStep(), and test2_main_func().

◆ Walkaround() [2/2]

bool PNS::LINE::Walkaround ( const SHAPE_LINE_CHAIN aObstacle,
SHAPE_LINE_CHAIN aPath,
bool  aCw 
) const

Definition at line 157 of file pns_line.cpp.

158 {
159  const SHAPE_LINE_CHAIN& line( CLine() );
160 
161  if( line.SegmentCount() < 1 )
162  {
163  return false;
164  }
165 
166  const auto pFirst = line.CPoint(0);
167  const auto pLast = line.CPoint(-1);
168 
169  bool inFirst = aObstacle.PointInside( pFirst ) && !aObstacle.PointOnEdge( pFirst );
170  bool inLast = aObstacle.PointInside( pLast ) && !aObstacle.PointOnEdge( pLast );
171 
172  // We can't really walk around if the beginning or the end of the path lies inside the obstacle hull.
173  // Double check if it's not on the hull itself as this triggers many unroutable corner cases.
174  if( inFirst || inLast )
175  {
176  return false;
177  }
178 
179  enum VERTEX_TYPE { INSIDE = 0, OUTSIDE, ON_EDGE };
180 
181  // Represents an entry in directed graph of hull/path vertices. Scanning this graph
182  // starting from the path's first point results (if possible) with a correct walkaround path
183  struct VERTEX
184  {
185  // vertex classification (inside/outside/exactly on the hull)
186  VERTEX_TYPE type;
187  // true = vertex coming from the hull primitive
188  bool isHull;
189  // position
190  VECTOR2I pos;
191  // list of neighboring vertices
192  std::vector<VERTEX*> neighbours;
193  // index of this vertex in path (pnew)
194  int indexp = -1;
195  // index of this vertex in the hull (hnew)
196  int indexh = -1;
197  // visited indicator (for BFS search)
198  bool visited = false;
199  };
200 
202 
203  line.Intersect( aObstacle, ips );
204 
205  SHAPE_LINE_CHAIN pnew( CLine() ), hnew( aObstacle );
206 
207  std::vector<VERTEX> vts;
208 
209  auto findVertex = [&]( VECTOR2I pos) -> VERTEX*
210  {
211  for( VERTEX& v : vts )
212  {
213  if(v.pos == pos )
214  return &v;
215  }
216 
217  return nullptr;
218  };
219 
220  // make sure all points that lie on the edge of the hull also exist as vertices in the path
221  for( int i = 0; i < pnew.PointCount(); i++ )
222  {
223  const VECTOR2I &p = pnew.CPoint(i);
224 
225  if( hnew.PointOnEdge( p ) )
226  {
228  ip.p = p;
229  ips.push_back( ip );
230  }
231  }
232 
233  // insert all intersections found into the new hull/path SLCs
234  for( auto ip : ips )
235  {
236  bool isNewP, isNewH;
237 
238  if( pnew.Find( ip.p ) < 0 )
239  {
240  pnew.Split(ip.p);
241  }
242 
243  if( hnew.Find( ip.p ) < 0 )
244  {
245  hnew.Split(ip.p);
246  }
247  }
248 
249  // we assume the default orientation of the hulls is clockwise, so just reverse the vertex
250  // order if the caller wants a counter-clockwise walkaround
251  if ( !aCw )
252  hnew = hnew.Reverse();
253 
254  vts.reserve( 2 * ( hnew.PointCount() + pnew.PointCount() ) );
255 
256  // create a graph of hull/path vertices and classify them (inside/on edge/outside the hull)
257  for( int i = 0; i < pnew.PointCount(); i++ )
258  {
259  auto p = pnew.CPoint(i);
260  bool onEdge = hnew.PointOnEdge( p );
261  bool inside = hnew.PointInside( p );
262 
263  VERTEX v;
264 
265  v.indexp = i;
266  v.isHull = false;
267  v.pos = p;
268  v.type = inside && !onEdge ? INSIDE : onEdge ? ON_EDGE : OUTSIDE;
269  vts.push_back( v );
270  }
271 
272  // each path vertex neighbour list points for sure to the next vertex in the path
273  for( int i = 0; i < pnew.PointCount() - 1; i++ )
274  {
275  vts[i].neighbours.push_back( &vts[ i+1 ] );
276  }
277 
278  // insert hull vertices into the graph
279  for( int i = 0; i < hnew.PointCount(); i++ )
280  {
281  auto hp = hnew.CPoint( i );
282  auto vn = findVertex( hp );
283 
284  // if vertex already present (it's very likely that in recursive shoving hull and path vertices will overlap)
285  // just mark it as a path vertex that also belongs to the hull
286  if( vn )
287  {
288  vn->isHull = true;
289  vn->indexh = i;
290  }
291  else // new hull vertex
292  {
293  VERTEX v;
294  v.pos = hp;
295  v.type = ON_EDGE;
296  v.indexh = i;
297  v.isHull = true;
298  vts.push_back( v );
299  }
300  }
301 
302  // go around the hull and fix up the neighbour link lists
303  for( int i = 0; i < hnew.PointCount(); i++ )
304  {
305  auto vc = findVertex( hnew.CPoint(i ) );
306  auto vnext = findVertex( hnew.CPoint( i+1 ) );
307 
308  if(vc && vnext)
309  vc->neighbours.push_back(vnext);
310  }
311 
312  // vts[0] = start point
313  VERTEX* v = &vts[0];
314  SHAPE_LINE_CHAIN out;
315 
316  int iterLimit = 1000;
317 
318  // keep scanning the graph until we reach the end point of the path
319  while ( v->indexp != (pnew.PointCount() - 1) )
320  {
321  iterLimit--;
322 
323  // I'm not 100% sure this algorithm doesn't have bugs that may cause it to freeze,
324  // so here's a temporary iteration limit
325  if( iterLimit == 0 )
326  {
327  return false;
328  }
329 
330  if(v->visited)
331  {
332  // loop found? clip to beginning of the loop
333  out = out.Slice(0, out.Find( v->pos ) );
334  break;
335  }
336 
337  out.Append( v->pos );
338 
339  VERTEX* v_next = nullptr;
340 
341  if (v->type == OUTSIDE)
342  {
343  // current vertex is outside? first look for any vertex further down the path
344  // that is not inside the hull
345  out.Append(v->pos);
346  for( auto vn : v->neighbours )
347  {
348  if( (vn->indexp > v->indexp) && vn->type != INSIDE )
349  {
350  v_next = vn;
351  break;
352  }
353  }
354 
355  // such a vertex must always be present, if not, bummer.
356  if (!v_next)
357  return false;
358 
359  }
360  else if (v->type == ON_EDGE)
361  {
362  // current vertex lies on the hull? first look for the hull/path vertex with the index (N+1)
363  for( VERTEX* vn: v->neighbours)
364  {
365 
366  if( vn->type == ON_EDGE && (vn->indexp == (v->indexp + 1) ) && ( (vn->indexh == (v->indexh + 1) ) % hnew.PointCount() ) )
367  {
368  v_next = vn;
369  break;
370  }
371  }
372 
373  // nothing found? look for the first vertex outside the hull then
374  if( !v_next )
375  {
376  for( VERTEX* vn: v->neighbours)
377  {
378  if( vn->type == OUTSIDE )
379  {
380  v_next = vn;
381  break;
382  }
383  }
384  }
385 
386  // still nothing found? try to find the next (index-wise) point on the hull. I guess
387  // we should never reach this part of the code, but who really knows?
388  if( !v_next )
389  {
390  for( VERTEX* vn: v->neighbours)
391  {
392  if ( v->type == ON_EDGE )
393  {
394  if( vn->indexh == ( (v->indexh + 1) % hnew.PointCount() ) )
395  {
396  v_next = vn;
397 
398  break;
399  }
400  }
401  }
402  }
403  }
404 
405  v->visited = true;
406  v = v_next;
407 
408  if( !v )
409  return false;
410  }
411 
412  out.Append( v->pos );
413  out.Simplify();
414 
415  aPath = out;
416 
417  return true;
418 }
int Find(const VECTOR2I &aP) const
Function Find()
const SHAPE_LINE_CHAIN & CLine() const
Definition: pns_line.h:137
std::vector< INTERSECTION > INTERSECTIONS
SHAPE_LINE_CHAIN & Simplify(bool aRemoveColinear=true)
Function Simplify()
const SHAPE_LINE_CHAIN Slice(int aStartIndex, int aEndIndex=-1) const
Function Slice()
VECTOR2I p
point of intersection between our and their.
bool PointOnEdge(const VECTOR2I &aP, int aAccuracy=0) const
Check if point aP lies on an edge or vertex of the line chain.
static std::pair< bool, SHAPE_POLY_SET::VERTEX_INDEX > findVertex(SHAPE_POLY_SET &aPolySet, const EDIT_POINT &aPoint)
void Append(int aX, int aY, bool aAllowDuplication=false)
Function Append()
bool PointInside(const VECTOR2I &aPt, int aAccuracy=0, bool aUseBBoxCache=false) const
Check if point aP lies inside a polygon (any type) defined by the line chain.
Text appears outside the dimension line (default)
SHAPE_LINE_CHAIN.

References SHAPE_LINE_CHAIN::Append(), CLine(), SHAPE_LINE_CHAIN::CPoint(), SHAPE_LINE_CHAIN::Find(), findVertex(), SHAPE_LINE_CHAIN::Intersect(), OUTSIDE, SHAPE_LINE_CHAIN::INTERSECTION::p, SHAPE_LINE_CHAIN::PointCount(), SHAPE_LINE_CHAIN_BASE::PointInside(), SHAPE_LINE_CHAIN_BASE::PointOnEdge(), SHAPE_LINE_CHAIN::Reverse(), SHAPE_LINE_CHAIN::SegmentCount(), SHAPE_LINE_CHAIN::Simplify(), SHAPE_LINE_CHAIN::Slice(), and SHAPE_LINE_CHAIN::Split().

◆ Width()

Member Data Documentation

◆ m_blockingObstacle

ITEM* PNS::LINE::m_blockingObstacle
private

For mark obstacle mode.

Definition at line 252 of file pns_line.h.

Referenced by GetBlockingObstacle(), LINE(), operator=(), and SetBlockingObstacle().

◆ m_hasVia

bool PNS::LINE::m_hasVia
private

Optional via at the end point.

Definition at line 249 of file pns_line.h.

Referenced by AppendVia(), Clear(), EndsWithVia(), LINE(), operator=(), and RemoveVia().

◆ m_kind

PnsKind PNS::ITEM::m_kind
protectedinherited

◆ m_layers

◆ m_line

◆ m_links

◆ m_marker

◆ m_movable

bool PNS::ITEM::m_movable
protectedinherited

Definition at line 241 of file pns_item.h.

Referenced by PNS::ITEM::ITEM(), LINE(), operator=(), and PNS::SOLID::SOLID().

◆ m_net

◆ m_owner

NODE* PNS::ITEM::m_owner
protectedinherited

◆ m_parent

BOARD_ITEM* PNS::ITEM::m_parent
protectedinherited

◆ m_rank

◆ m_routable

bool PNS::ITEM::m_routable
protectedinherited

Definition at line 245 of file pns_item.h.

Referenced by PNS::ITEM::IsRoutable(), PNS::ITEM::ITEM(), and PNS::ITEM::SetRoutable().

◆ m_snapThreshhold

int PNS::LINE::m_snapThreshhold
private

Width to smooth out jagged segments.

Definition at line 247 of file pns_line.h.

Referenced by GetSnapThreshhold(), LINE(), operator=(), SetSnapThreshhold(), snapDraggedCorner(), and snapToNeighbourSegments().

◆ m_via

VIA PNS::LINE::m_via
private

Definition at line 250 of file pns_line.h.

Referenced by AppendVia(), LINE(), operator=(), SetViaDiameter(), SetViaDrill(), and Via().

◆ m_width

int PNS::LINE::m_width
private

Our width.

Definition at line 244 of file pns_line.h.

Referenced by LINE(), operator=(), SetShape(), SetWidth(), and Width().

◆ UnusedNet

const int PNS::ITEM::UnusedNet = INT_MAX
staticinherited

Supported item types.

Definition at line 58 of file pns_item.h.

Referenced by PNS::ITEM::ITEM().


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