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
 
bool IsVirtual () 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
 
bool m_isVirtual
 

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 36 of file pns_line.cpp.

37  : LINK_HOLDER( aOther ),
38  m_line( aOther.m_line ),
39  m_width( aOther.m_width ),
40  m_snapThreshhold( aOther.m_snapThreshhold )
41 {
42  m_net = aOther.m_net;
43  m_movable = aOther.m_movable;
44  m_layers = aOther.m_layers;
45  m_via = aOther.m_via;
46  m_hasVia = aOther.m_hasVia;
47  m_marker = aOther.m_marker;
48  m_rank = aOther.m_rank;
49  m_blockingObstacle = aOther.m_blockingObstacle;
50 
51  copyLinks( &aOther );
52 }
VIA m_via
Definition: pns_line.h:250
LAYER_RANGE m_layers
Definition: pns_item.h:246
int m_rank
Definition: pns_item.h:251
bool m_movable
Definition: pns_item.h:248
int m_marker
Definition: pns_item.h:250
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: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 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:246
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: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, 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:246
int m_rank
Definition: pns_item.h:251
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: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 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 55 of file pns_line.cpp.

56 {
57 }

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 220 of file pns_item.h.

221  {
222  return 0;
223  }

◆ AppendVia()

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

Definition at line 1030 of file pns_line.cpp.

1031 {
1032  if( m_line.PointCount() > 1 && aVia.Pos() == m_line.CPoint( 0 ) )
1033  {
1034  Reverse();
1035  }
1036 
1037  m_hasVia = true;
1038  m_via = aVia;
1039  m_via.SetNet( m_net );
1040 }
VIA m_via
Definition: pns_line.h:250
int PointCount() const
Return the number of points (vertices) in this line chain.
void SetNet(int aNet)
Definition: pns_item.h:149
SHAPE_LINE_CHAIN m_line
The actual shape of the line.
Definition: pns_line.h:243
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
void Reverse()
Clip the line to the nearest obstacle, traversing from the line's start vertex (0).
Definition: pns_line.cpp:1022
bool m_hasVia
Optional via at the end point.
Definition: pns_line.h:249
int m_net
Definition: pns_item.h:249

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 179 of file pns_item.h.

180  {
181  return m_owner == aNode;
182  }
NODE * m_owner
Definition: pns_item.h:245

References PNS::ITEM::m_owner.

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

◆ ChangedArea()

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

Definition at line 1151 of file pns_line.cpp.

1152 {
1153  BOX2I area;
1154  bool areaDefined = false;
1155 
1156  int i_start = -1;
1157  int i_end_self = -1, i_end_other = -1;
1158 
1159  SHAPE_LINE_CHAIN self( m_line );
1160  self.Simplify();
1161  SHAPE_LINE_CHAIN other( aOther->m_line );
1162  other.Simplify();
1163 
1164  int np_self = self.PointCount();
1165  int np_other = other.PointCount();
1166 
1167  int n = std::min( np_self, np_other );
1168 
1169  for( int i = 0; i < n; i++ )
1170  {
1171  const VECTOR2I p1 = self.CPoint( i );
1172  const VECTOR2I p2 = other.CPoint( i );
1173 
1174  if( p1 != p2 )
1175  {
1176  if( i != n - 1 )
1177  {
1178  SEG s = self.CSegment( i );
1179 
1180  if( !s.Contains( p2 ) )
1181  {
1182  i_start = i;
1183  break;
1184  }
1185  }
1186  else
1187  {
1188  i_start = i;
1189  break;
1190  }
1191  }
1192  }
1193 
1194  for( int i = 0; i < n; i++ )
1195  {
1196  const VECTOR2I p1 = self.CPoint( np_self - 1 - i );
1197  const VECTOR2I p2 = other.CPoint( np_other - 1 - i );
1198 
1199  if( p1 != p2 )
1200  {
1201  i_end_self = np_self - 1 - i;
1202  i_end_other = np_other - 1 - i;
1203  break;
1204  }
1205  }
1206 
1207  if( i_start < 0 )
1208  i_start = n;
1209 
1210  if( i_end_self < 0 )
1211  i_end_self = np_self - 1;
1212 
1213  if( i_end_other < 0 )
1214  i_end_other = np_other - 1;
1215 
1216  for( int i = i_start; i <= i_end_self; i++ )
1217  extendBox( area, areaDefined, self.CPoint( i ) );
1218 
1219  for( int i = i_start; i <= i_end_other; i++ )
1220  extendBox( area, areaDefined, other.CPoint( i ) );
1221 
1222  if( areaDefined )
1223  {
1224  area.Inflate( std::max( Width(), aOther->Width() ) );
1225  return area;
1226  }
1227 
1228  return OPT_BOX2I();
1229 }
SHAPE_LINE_CHAIN & Simplify(bool aRemoveColinear=true)
Simplify the line chain by removing colinear adjacent segments and duplicate vertices.
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:40
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:281
Represent a polyline (an zero-thickness chain of connected line segments).
static void extendBox(BOX2I &aBox, bool &aDefined, const VECTOR2I &aP)
Definition: pns_line.cpp:1137
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:509
bool Contains(const SEG &aSeg) const
Definition: seg.h:331

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 1242 of file pns_line.cpp.

1243 {
1244  m_hasVia = false;
1245  m_line.Clear();
1246 }
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()
Remove all points from the line chain.

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

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

◆ 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::TOPOLOGY::AssembleTuningPath(), 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::dragShove(), PNS::DRAGGER::dragViaMarkObstacles(), PNS::DRAGGER::dragViaWalkaround(), PNS::DRAGGER::dragWalkaround(), 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::OPTIMIZER::Optimize(), 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::LINE_PLACER::routeStep(), PNS::SHOVE::ShoveLines(), PNS::SHOVE::shoveLineToHullSet(), PNS::SHOVE::ShoveObstacleLine(), PNS::TOPOLOGY::SimplifyLine(), PNS::LINE_PLACER::simplifyNewLine(), PNS::WALKAROUND::singleStep(), PNS::OPTIMIZER::smartPadsSingle(), PNS::COMPONENT_DRAGGER::Start(), PNS::DRAGGER::startDragSegment(), 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 566 of file pns_line.cpp.

567 {
568  const int IterationLimit = 5;
569  int i;
570  LINE l( *this );
571 
572  for( i = 0; i < IterationLimit; i++ )
573  {
574  NODE::OPT_OBSTACLE obs = aNode->NearestObstacle( &l );
575 
576  if( obs )
577  {
578  l.RemoveVia();
579  int p = l.Line().Split( obs->m_ipFirst );
580  l.Line().Remove( p + 1, -1 );
581  } else
582  break;
583  }
584 
585  if( i == IterationLimit )
586  l.Line().Clear();
587 
588  return l;
589 }
LINE()
Makes an empty line.
Definition: pns_line.h:66
OPT< OBSTACLE > OPT_OBSTACLE
Definition: pns_node.h:147

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

◆ 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 1072 of file pns_line.cpp.

1073 {
1080  int firstLink = 0;
1081  int lastLink = std::max( 0, static_cast<int>( m_links.size() ) - 1 );
1082  int arcIdx = -1;
1083  int linkIdx = 0;
1084 
1085  int numPoints = static_cast<int>( m_line.PointCount() );
1086 
1087  for( int i = 0; i < m_line.PointCount(); i = m_line.NextShape( i ) )
1088  {
1089  if( i <= aStart )
1090  firstLink = linkIdx;
1091 
1092  if( i < 0 || i >= aEnd - 1 || linkIdx >= lastLink )
1093  {
1094  lastLink = linkIdx;
1095  break;
1096  }
1097 
1098  linkIdx++;
1099  }
1100 
1101  wxASSERT( lastLink >= firstLink );
1102 
1103  m_line = m_line.Slice( aStart, aEnd );
1104 
1105  if( IsLinked() )
1106  {
1107  wxASSERT( m_links.size() < INT_MAX );
1108  wxASSERT( static_cast<int>( m_links.size() ) >= ( lastLink - firstLink ) );
1109 
1110  // Note: The range includes aEnd, but we have n-1 segments.
1111  std::rotate(
1112  m_links.begin(),
1113  m_links.begin() + firstLink,
1114  m_links.begin() + lastLink
1115  );
1116 
1117  m_links.resize( lastLink - firstLink + 1 );
1118  }
1119 }
const SHAPE_LINE_CHAIN Slice(int aStartIndex, int aEndIndex=-1) const
Return a subset of this line chain containing the [start_index, end_index] range of points.
int PointCount() const
Return the number of points (vertices) in this line chain.
SHAPE_LINE_CHAIN m_line
The actual shape of the line.
Definition: pns_line.h:243
int NextShape(int aPointIndex, bool aForwards=true) const
Return the vertex index of the next shape in the chain, or -1 if aPointIndex is the last shape.

References PNS::LINK_HOLDER::IsLinked(), m_line, PNS::LINK_HOLDER::m_links, SHAPE_LINE_CHAIN::NextShape(), 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 81 of file pns_line.cpp.

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

References LINE().

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

◆ 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 independent
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:242
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 1016 of file pns_line.cpp.

1017 {
1018  return m_line.CompareGeometry( aOther.m_line );
1019 }
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:99

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 135 of file pns_line.cpp.

136 {
137  int count = 0;
138 
139  for( int i = 0; i < m_line.SegmentCount() - 1; i++ )
140  {
141  const SEG seg1 = m_line.CSegment( i );
142  const SEG seg2 = m_line.CSegment( i + 1 );
143 
144  const DIRECTION_45 dir1( seg1 );
145  const DIRECTION_45 dir2( seg2 );
146 
147  DIRECTION_45::AngleType a = dir1.Angle( dir2 );
148 
149  if( a & aAngles )
150  count++;
151  }
152 
153  return count;
154 }
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
Return the number of segments in this line chain.
Definition: seg.h:40
AngleType
Represent kind of angle formed by vectors heading in two DIRECTION_45s.
Definition: direction45.h:65
const SEG CSegment(int aIndex) const
Return a constant copy of the aIndex segment in the line chain.

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

Referenced by PNS::CORNER_COUNT_LIMIT_CONSTRAINT::Check(), PNS::LINE_PLACER::mergeHead(), PNS::OPTIMIZER::Optimize(), 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 733 of file pns_line.cpp.

734 {
735  wxCHECK_RET( aIndex >= 0, "Negative index passed to LINE::DragCorner" );
736 
737  if( aFreeAngle )
738  {
739  dragCornerFree( aP, aIndex );
740  }
741  else
742  {
743  dragCorner45( aP, aIndex );
744  }
745 }
void dragCorner45(const VECTOR2I &aP, int aIndex)
Definition: pns_line.cpp:676
void dragCornerFree(const VECTOR2I &aP, int aIndex)
Definition: pns_line.cpp:706

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 676 of file pns_line.cpp.

677 {
679 
680  int width = m_line.Width();
681  VECTOR2I snapped = snapDraggedCorner( m_line, aP, aIndex );
682 
683  if( aIndex == 0 )
684  path = dragCornerInternal( m_line.Reverse(), snapped ).Reverse();
685  else if( aIndex == m_line.SegmentCount() )
686  path = dragCornerInternal( m_line, snapped );
687  else
688  {
689  // Are we next to an arc? Insert a new point so we slice correctly
690  if( m_line.IsPtOnArc( static_cast<size_t>( aIndex ) + 1 ) )
691  m_line.Insert( aIndex + 1, m_line.CPoint( aIndex + 1 ) );
692 
693  // fixme: awkward behaviour for "outwards" drags
694  path = dragCornerInternal( m_line.Slice( 0, aIndex ), snapped );
695  SHAPE_LINE_CHAIN path_rev =
696  dragCornerInternal( m_line.Slice( aIndex + 1, -1 ).Reverse(), snapped ).Reverse();
697  path.Append( path_rev );
698  }
699 
700  path.Simplify();
701  path.SetWidth( width );
702  m_line = path;
703 }
const SHAPE_LINE_CHAIN Slice(int aStartIndex, int aEndIndex=-1) const
Return a subset of this line chain containing the [start_index, end_index] range of points.
int Width() const
Get the current width of the segments in the chain.
const SHAPE_LINE_CHAIN Reverse() const
Reverse point order in the line chain.
SHAPE_LINE_CHAIN dragCornerInternal(const SHAPE_LINE_CHAIN &aOrigin, const VECTOR2I &aP)
Definition: pns_line.cpp:593
SHAPE_LINE_CHAIN m_line
The actual shape of the line.
Definition: pns_line.h:243
void Insert(size_t aVertex, const VECTOR2I &aP)
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
void Reverse()
Clip the line to the nearest obstacle, traversing from the line's start vertex (0).
Definition: pns_line.cpp:1022
int SegmentCount() const
Return the number of segments in this line chain.
bool IsPtOnArc(size_t aPtIndex) const
Represent a polyline (an zero-thickness chain of connected line segments).
VECTOR2I snapDraggedCorner(const SHAPE_LINE_CHAIN &aPath, const VECTOR2I &aP, int aIndex) const
Definition: pns_line.cpp:759

References SHAPE_LINE_CHAIN::CPoint(), PNS::dragCornerInternal(), SHAPE_LINE_CHAIN::Insert(), SHAPE_LINE_CHAIN::IsPtOnArc(), m_line, path, Reverse(), SHAPE_LINE_CHAIN::Reverse(), SHAPE_LINE_CHAIN::SegmentCount(), SHAPE_LINE_CHAIN::Slice(), snapDraggedCorner(), and SHAPE_LINE_CHAIN::Width().

Referenced by DragCorner().

◆ dragCornerFree()

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

Definition at line 706 of file pns_line.cpp.

707 {
708  ssize_t idx = static_cast<ssize_t>( aIndex );
709  ssize_t numpts = static_cast<ssize_t>( m_line.PointCount() );
710 
711  // If we're asked to drag the end of an arc, insert a new vertex to drag instead
712  if( m_line.IsPtOnArc( idx ) )
713  {
714  if( idx == 0 || ( idx > 0 && !m_line.IsPtOnArc( idx - 1 ) ) )
715  {
716  m_line.Insert( idx, m_line.GetPoint( idx ) );
717  }
718  else if( ( idx == numpts - 1 ) || ( idx < numpts - 1 && !m_line.IsArcSegment( idx ) ) )
719  {
720  idx++;
721  m_line.Insert( idx, m_line.GetPoint( idx ) );
722  }
723  else
724  {
725  wxASSERT_MSG( false, "Attempt to dragCornerFree in the middle of an arc!" );
726  }
727  }
728 
729  m_line.SetPoint( idx, aP );
730  m_line.Simplify();
731 }
SHAPE_LINE_CHAIN & Simplify(bool aRemoveColinear=true)
Simplify the line chain by removing colinear adjacent segments and duplicate vertices.
void SetPoint(int aIndex, const VECTOR2I &aPos)
Move a point to a specific location.
int PointCount() const
Return the number of points (vertices) in this line chain.
SHAPE_LINE_CHAIN m_line
The actual shape of the line.
Definition: pns_line.h:243
void Insert(size_t aVertex, const VECTOR2I &aP)
bool IsArcSegment(size_t aSegment) const
virtual const VECTOR2I GetPoint(int aIndex) const override
bool IsPtOnArc(size_t aPtIndex) const

References SHAPE_LINE_CHAIN::GetPoint(), SHAPE_LINE_CHAIN::Insert(), SHAPE_LINE_CHAIN::IsArcSegment(), SHAPE_LINE_CHAIN::IsPtOnArc(), m_line, SHAPE_LINE_CHAIN::PointCount(), 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 747 of file pns_line.cpp.

748 {
749  if( aFreeAngle )
750  {
751  assert( false );
752  }
753  else
754  {
755  dragSegment45( aP, aIndex );
756  }
757 }
void dragSegment45(const VECTOR2I &aP, int aIndex)
Definition: pns_line.cpp:846

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 846 of file pns_line.cpp.

847 {
849  VECTOR2I target( aP );
850 
851  wxASSERT( aIndex < m_line.PointCount() );
852 
853  SEG guideA[2], guideB[2];
854  int index = aIndex;
855 
856  target = snapToNeighbourSegments( path, aP, aIndex );
857 
858  // We require a valid s_prev and s_next. If we are at the start or end of the line, we insert
859  // a new point at the start or end so there is a zero-length segment for prev or next (we will
860  // resize it as part of the drag operation). If we are next to an arc, we do this also, as we
861  // cannot drag away one of the arc's points.
862 
863  if( index == 0 || path.IsPtOnArc( index ) )
864  {
865  path.Insert( index > 0 ? index + 1 : 0, path.CPoint( index ) );
866  index++;
867  }
868 
869  if( index == path.SegmentCount() - 1 )
870  {
871  path.Insert( path.PointCount() - 1, path.CPoint( -1 ) );
872  }
873  else if( path.IsPtOnArc( index + 1 ) )
874  {
875  path.Insert( index + 1, path.CPoint( index + 1 ) );
876  }
877 
878  SEG dragged = path.CSegment( index );
879  DIRECTION_45 drag_dir( dragged );
880 
881  SEG s_prev = path.CSegment( index - 1 );
882  SEG s_next = path.CSegment( index + 1 );
883 
884  DIRECTION_45 dir_prev( s_prev );
885  DIRECTION_45 dir_next( s_next );
886 
887  if( dir_prev == drag_dir )
888  {
889  dir_prev = dir_prev.Left();
890  path.Insert( index, path.CPoint( index ) );
891  index++;
892  }
893  else if( dir_prev == DIRECTION_45::UNDEFINED )
894  {
895  dir_prev = drag_dir.Left();
896  }
897 
898  if( dir_next == drag_dir )
899  {
900  dir_next = dir_next.Right();
901  path.Insert( index + 1, path.CPoint( index + 1 ) );
902  }
903  else if( dir_next == DIRECTION_45::UNDEFINED )
904  {
905  dir_next = drag_dir.Right();
906  }
907 
908  s_prev = path.CSegment( index - 1 );
909  s_next = path.CSegment( index + 1 );
910  dragged = path.CSegment( index );
911 
912  if( aIndex == 0 )
913  {
914  guideA[0] = SEG( dragged.A, dragged.A + drag_dir.Right().ToVector() );
915  guideA[1] = SEG( dragged.A, dragged.A + drag_dir.Left().ToVector() );
916  }
917  else
918  {
919  if( dir_prev.Angle( drag_dir )
921  {
922  guideA[0] = SEG( s_prev.A, s_prev.A + drag_dir.Left().ToVector() );
923  guideA[1] = SEG( s_prev.A, s_prev.A + drag_dir.Right().ToVector() );
924  }
925  else
926  guideA[0] = guideA[1] = SEG( dragged.A, dragged.A + dir_prev.ToVector() );
927  }
928 
929  if( aIndex == m_line.SegmentCount() - 1 )
930  {
931  guideB[0] = SEG( dragged.B, dragged.B + drag_dir.Right().ToVector() );
932  guideB[1] = SEG( dragged.B, dragged.B + drag_dir.Left().ToVector() );
933  }
934  else
935  {
936  if( dir_next.Angle( drag_dir )
938  {
939  guideB[0] = SEG( s_next.B, s_next.B + drag_dir.Left().ToVector() );
940  guideB[1] = SEG( s_next.B, s_next.B + drag_dir.Right().ToVector() );
941  }
942  else
943  guideB[0] = guideB[1] = SEG( dragged.B, dragged.B + dir_next.ToVector() );
944  }
945 
946  SEG s_current( target, target + drag_dir.ToVector() );
947 
948  int best_len = INT_MAX;
949  SHAPE_LINE_CHAIN best;
950 
951  for( int i = 0; i < 2; i++ )
952  {
953  for( int j = 0; j < 2; j++ )
954  {
955  OPT_VECTOR2I ip1 = s_current.IntersectLines( guideA[i] );
956  OPT_VECTOR2I ip2 = s_current.IntersectLines( guideB[j] );
957 
958  SHAPE_LINE_CHAIN np;
959 
960  if( !ip1 || !ip2 )
961  continue;
962 
963  SEG s1( s_prev.A, *ip1 );
964  SEG s2( *ip1, *ip2 );
965  SEG s3( *ip2, s_next.B );
966 
967  OPT_VECTOR2I ip;
968 
969  if( ( ip = s1.Intersect( s_next ) ) )
970  {
971  np.Append( s1.A );
972  np.Append( *ip );
973  np.Append( s_next.B );
974  }
975  else if( ( ip = s3.Intersect( s_prev ) ) )
976  {
977  np.Append( s_prev.A );
978  np.Append( *ip );
979  np.Append( s3.B );
980  }
981  else if( ( ip = s1.Intersect( s3 ) ) )
982  {
983  np.Append( s_prev.A );
984  np.Append( *ip );
985  np.Append( s_next.B );
986  }
987  else
988  {
989  np.Append( s_prev.A );
990  np.Append( *ip1 );
991  np.Append( *ip2 );
992  np.Append( s_next.B );
993  }
994 
995  if( np.Length() < best_len )
996  {
997  best_len = np.Length();
998  best = np;
999  }
1000  }
1001  }
1002 
1003  if( m_line.PointCount() == 1 )
1004  m_line = best;
1005  else if( aIndex == 0 )
1006  m_line.Replace( 0, 1, best );
1007  else if( aIndex == m_line.SegmentCount() - 1 )
1008  m_line.Replace( -2, -1, best );
1009  else
1010  m_line.Replace( aIndex, aIndex + 1, best );
1011 
1012  m_line.Simplify();
1013 }
long long int Length() const
Return length of the line chain in Euclidean metric.
SHAPE_LINE_CHAIN & Simplify(bool aRemoveColinear=true)
Simplify the line chain by removing colinear adjacent segments and duplicate vertices.
VECTOR2I snapToNeighbourSegments(const SHAPE_LINE_CHAIN &aPath, const VECTOR2I &aP, int aIndex) const
Definition: pns_line.cpp:801
int PointCount() const
Return the number of points (vertices) in this line chain.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
SHAPE_LINE_CHAIN m_line
The actual shape of the line.
Definition: pns_line.h:243
OPT< VECTOR2I > OPT_VECTOR2I
Definition: seg.h:38
Represent route directions & corner angles in a 45-degree metric.
Definition: direction45.h:36
int SegmentCount() const
Return the number of segments in this line chain.
Definition: seg.h:40
Represent a polyline (an zero-thickness chain of connected line segments).
VECTOR2I A
Definition: seg.h:48
void Replace(int aStartIndex, int aEndIndex, const VECTOR2I &aP)
Replace points with indices in range [start_index, end_index] with a single point aP.
VECTOR2I B
Definition: seg.h:49

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

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 1232 of file pns_line.cpp.

1233 {
1234  for( const auto seg : m_links )
1235  {
1236  if( seg->Marker() & MK_LOCKED )
1237  return true;
1238  }
1239  return false;
1240 }

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 1122 of file pns_line.cpp.

1123 {
1124  for( int i = 0; i < PointCount(); i++ )
1125  {
1126  for( int j = i + 2; j < PointCount(); j++ )
1127  {
1128  if( CPoint( i ) == CPoint( j ) )
1129  return true;
1130  }
1131  }
1132 
1133  return false;
1134 }
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 203 of file pns_item.h.

204  {
205  return nullptr;
206  }

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 119 of file pns_item.h.

121  {
122  return SHAPE_LINE_CHAIN();
123  }
Represent a polyline (an zero-thickness chain of connected line segments).

◆ 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 113 of file pns_item.h.

115  {
116  return SHAPE_LINE_CHAIN();
117  }
Represent a polyline (an zero-thickness chain of connected line segments).

◆ Is45Degree()

bool PNS::LINE::Is45Degree ( ) const

Print out all linked segments.

Definition at line 537 of file pns_line.cpp.

538 {
539  for( int i = 0; i < m_line.SegmentCount(); i++ )
540  {
541  const SEG& s = m_line.CSegment( i );
542 
543  if( m_line.IsArcSegment( i ) )
544  continue;
545 
546  if( s.Length() < 10 )
547  continue;
548 
549  double angle = 180.0 / M_PI *
550  atan2( (double) s.B.y - (double) s.A.y,
551  (double) s.B.x - (double) s.A.x );
552 
553  if( angle < 0 )
554  angle += 360.0;
555 
556  double angle_a = fabs( fmod( angle, 45.0 ) );
557 
558  if( angle_a > 1.0 && angle_a < 44.0 )
559  return false;
560  }
561 
562  return true;
563 }
int Length() const
Return the length (this).
Definition: seg.h:350
SHAPE_LINE_CHAIN m_line
The actual shape of the line.
Definition: pns_line.h:243
bool IsArcSegment(size_t aSegment) const
int SegmentCount() const
Return the number of segments in this line chain.
Definition: seg.h:40
const SEG CSegment(int aIndex) const
Return a constant copy of the aIndex segment in the line chain.
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
VECTOR2I A
Definition: seg.h:48
VECTOR2I B
Definition: seg.h:49

References SEG::A, PNS::angle(), SEG::B, SHAPE_LINE_CHAIN::CSegment(), SHAPE_LINE_CHAIN::IsArcSegment(), 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 ShapeCount().

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

◆ IsLocked()

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

Definition at line 225 of file pns_item.h.

226  {
227  return Marker() & MK_LOCKED;
228  }
virtual int Marker() const
Definition: pns_item.h:210

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 231 of file pns_item.h.

231 { return m_routable; }
bool m_routable
Definition: pns_item.h:252

References PNS::ITEM::m_routable.

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

◆ IsVirtual()

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

◆ 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:242

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 152 of file pns_item.h.

152 { return m_layers; }
LAYER_RANGE m_layers
Definition: pns_item.h:246

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(), PNS::NODE::FixupVirtualVias(), 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::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 161 of file pns_item.h.

162  {
163  return Layers().Overlaps( aOther->Layers() );
164  }
bool Overlaps(const LAYER_RANGE &aOther) const
Definition: pns_layerset.h:67
const LAYER_RANGE & Layers() const
Definition: pns_item.h:152

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 89 of file pns_line.cpp.

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

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 108 of file pns_line.cpp.

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

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 60 of file pns_line.cpp.

61 {
62  m_line = aOther.m_line;
63  m_width = aOther.m_width;
64  m_net = aOther.m_net;
65  m_movable = aOther.m_movable;
66  m_layers = aOther.m_layers;
67  m_via = aOther.m_via;
68  m_hasVia = aOther.m_hasVia;
69  m_marker = aOther.m_marker;
70  m_rank = aOther.m_rank;
71  m_owner = aOther.m_owner;
72  m_snapThreshhold = aOther.m_snapThreshhold;
73  m_blockingObstacle = aOther.m_blockingObstacle;
74 
75  copyLinks( &aOther );
76 
77  return *this;
78 }
VIA m_via
Definition: pns_line.h:250
NODE * m_owner
Definition: pns_item.h:245
LAYER_RANGE m_layers
Definition: pns_item.h:246
int m_rank
Definition: pns_item.h:251
bool m_movable
Definition: pns_item.h:248
int m_marker
Definition: pns_item.h:250
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: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 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 169 of file pns_item.h.

169 { return m_owner; }
NODE * m_owner
Definition: pns_item.h:245

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 1053 of file pns_line.cpp.

1054 {
1055  int min_rank = INT_MAX;
1056 
1057  if( IsLinked() ) {
1058  for( auto s : m_links )
1059  {
1060  min_rank = std::min( min_rank, s->Rank() );
1061  }
1062  } else {
1063  min_rank = m_rank;
1064  }
1065 
1066  int rank = ( min_rank == INT_MAX ) ? -1 : min_rank;
1067 
1068  return rank;
1069 }
int m_rank
Definition: pns_item.h:251

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

◆ 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 1022 of file pns_line.cpp.

1023 {
1024  m_line = m_line.Reverse();
1025 
1026  std::reverse( m_links.begin(), m_links.end() );
1027 }
const SHAPE_LINE_CHAIN Reverse() const
Reverse point order in the line chain.
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 153 of file pns_item.h.

153 { m_layers = aLayers; }
LAYER_RANGE m_layers
Definition: pns_item.h:246

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 174 of file pns_item.h.

174 { m_owner = aOwner; }
NODE * m_owner
Definition: pns_item.h:245

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 146 of file pns_item.h.

146 { m_parent = aParent; }
BOARD_ITEM * m_parent
Definition: pns_item.h:244

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 1043 of file pns_line.cpp.

1044 {
1045  m_rank = aRank;
1046 
1047  for( auto s : m_links )
1048  s->SetRank( aRank );
1049 
1050 }
int m_rank
Definition: pns_item.h:251

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 230 of file pns_item.h.

230 { m_routable = aRoutable; }
bool m_routable
Definition: pns_item.h:252

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:113

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:120

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 IsLinkedChecked(), and 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 759 of file pns_line.cpp.

761 {
762  int s_start = std::max( aIndex - 2, 0 );
763  int s_end = std::min( aIndex + 2, aPath.SegmentCount() - 1 );
764 
765  int i, j;
766  int best_dist = INT_MAX;
767  VECTOR2I best_snap = aP;
768 
769  if( m_snapThreshhold <= 0 )
770  return aP;
771 
772  for( i = s_start; i <= s_end; i++ )
773  {
774  const SEG& a = aPath.CSegment( i );
775 
776  for( j = s_start; j < i; j++ )
777  {
778  const SEG& b = aPath.CSegment( j );
779 
780  if( !( DIRECTION_45( a ).IsObtuse( DIRECTION_45( b ) ) ) )
781  continue;
782 
783  OPT_VECTOR2I ip = a.IntersectLines( b );
784 
785  if( ip )
786  {
787  int dist = ( *ip - aP ).EuclideanNorm();
788 
789  if( dist < m_snapThreshhold && dist < best_dist )
790  {
791  best_dist = dist;
792  best_snap = *ip;
793  }
794  }
795  }
796  }
797 
798  return best_snap;
799 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:146
OPT_VECTOR2I IntersectLines(const SEG &aSeg) const
Compute the intersection point of lines passing through ends of (this) and aSeg.
Definition: seg.h:209
OPT< VECTOR2I > OPT_VECTOR2I
Definition: seg.h:38
Represent route directions & corner angles in a 45-degree metric.
Definition: direction45.h:36
int SegmentCount() const
Return the number of segments in this line chain.
Definition: seg.h:40
const SEG CSegment(int aIndex) const
Return a constant copy of the aIndex segment in the line chain.
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 801 of file pns_line.cpp.

803 {
804  VECTOR2I snap_p[2];
805  DIRECTION_45 dragDir( aPath.CSegment( aIndex ) );
806  int snap_d[2] = { -1, -1 };
807 
808  if( m_snapThreshhold == 0 )
809  return aP;
810 
811  if( aIndex >= 2 )
812  {
813  SEG s = aPath.CSegment( aIndex - 2 );
814 
815  if( DIRECTION_45( s ) == dragDir )
816  snap_d[0] = s.LineDistance( aP );
817 
818  snap_p[0] = s.A;
819  }
820 
821  if( aIndex < aPath.SegmentCount() - 2 )
822  {
823  SEG s = aPath.CSegment( aIndex + 2 );
824 
825  if( DIRECTION_45( s ) == dragDir )
826  snap_d[1] = s.LineDistance( aP );
827 
828  snap_p[1] = s.A;
829  }
830 
831  VECTOR2I best = aP;
832  int minDist = INT_MAX;
833 
834  for( int i = 0; i < 2; i++ )
835  {
836  if( snap_d[i] >= 0 && snap_d[i] < minDist && snap_d[i] <= m_snapThreshhold )
837  {
838  minDist = snap_d[i];
839  best = snap_p[i];
840  }
841  }
842 
843  return best;
844 }
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.cpp:297
Represent route directions & corner angles in a 45-degree metric.
Definition: direction45.h:36
int SegmentCount() const
Return the number of segments in this line chain.
Definition: seg.h:40
const SEG CSegment(int aIndex) const
Return a constant copy of the aIndex segment in the line chain.
int m_snapThreshhold
Width to smooth out jagged segments.
Definition: pns_line.h:247
VECTOR2I A
Definition: seg.h:48

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 99 of file pns_line.cpp.

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

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(), and PNS::WALKAROUND::singleStep().

◆ Walkaround() [2/2]

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

Definition at line 172 of file pns_line.cpp.

173 {
174  const SHAPE_LINE_CHAIN& line( CLine() );
175 
176  if( line.SegmentCount() < 1 )
177  {
178  return false;
179  }
180 
181  const auto pFirst = line.CPoint(0);
182 
183  bool inFirst = aObstacle.PointInside( pFirst ) && !aObstacle.PointOnEdge( pFirst );
184 
185  // We can't really walk around if the beginning of the path lies inside the obstacle hull.
186  // Double check if it's not on the hull itself as this triggers many unroutable corner cases.
187  if( inFirst )
188  {
189  return false;
190  }
191 
192  enum VERTEX_TYPE { INSIDE = 0, OUTSIDE, ON_EDGE };
193 
194  // Represents an entry in directed graph of hull/path vertices. Scanning this graph
195  // starting from the path's first point results (if possible) with a correct walkaround path
196  struct VERTEX
197  {
198  // vertex classification (inside/outside/exactly on the hull)
199  VERTEX_TYPE type;
200  // true = vertex coming from the hull primitive
201  bool isHull;
202  // position
203  VECTOR2I pos;
204  // list of neighboring vertices
205  std::vector<VERTEX*> neighbours;
206  // index of this vertex in path (pnew)
207  int indexp = -1;
208  // index of this vertex in the hull (hnew)
209  int indexh = -1;
210  // visited indicator (for BFS search)
211  bool visited = false;
212  };
213 
215 
216  HullIntersection( aObstacle, line, ips );
217 
218  SHAPE_LINE_CHAIN pnew( CLine() ), hnew( aObstacle );
219 
220  std::vector<VERTEX> vts;
221 
222  auto findVertex = [&]( VECTOR2I pos) -> VERTEX*
223  {
224  for( VERTEX& v : vts )
225  {
226  if(v.pos == pos )
227  return &v;
228  }
229 
230  return nullptr;
231  };
232 
233 
234  // corner case for loopy tracks: insert the end loop point back into the hull
235  if( auto isect = pnew.SelfIntersecting() )
236  {
237  if( isect->p != pnew.CPoint( -1 ) )
238  {
239  pnew.Split( isect->p );
240  }
241  }
242 
243  // insert all intersections found into the new hull/path SLCs
244  for( auto& ip : ips )
245  {
246  if( pnew.Find( ip.p, 1 ) < 0)
247  {
248  pnew.Split(ip.p);
249  }
250 
251  if( hnew.Find( ip.p, 1 ) < 0 )
252  {
253  hnew.Split(ip.p);
254  }
255  }
256 
257  for( int i = 0; i < pnew.PointCount(); i++ )
258  {
259  auto p = pnew.CPoint(i);
260  bool onEdge = hnew.PointOnEdge( p );
261 
262  if ( !onEdge )
263  continue;
264 
265  int idx = hnew.Find( p );
266 
267  if(idx < 0 )
268  {
269  hnew.Split(p);
270  }
271  }
272 
273  #ifdef TOM_EXTRA_DEBUG
274  for( auto& ip : ips )
275  {
276  printf("Chk: %d %d\n", pnew.Find( ip.p ), hnew.Find(ip.p) );
277  }
278  #endif
279 
280  // we assume the default orientation of the hulls is clockwise, so just reverse the vertex
281  // order if the caller wants a counter-clockwise walkaround
282  if ( !aCw )
283  hnew = hnew.Reverse();
284 
285  vts.reserve( 2 * ( hnew.PointCount() + pnew.PointCount() ) );
286 
287  // create a graph of hull/path vertices and classify them (inside/on edge/outside the hull)
288  for( int i = 0; i < pnew.PointCount(); i++ )
289  {
290  auto p = pnew.CPoint(i);
291  bool onEdge = hnew.PointOnEdge( p );
292  bool inside = hnew.PointInside( p );
293 
294  #ifdef TOM_EXTRA_DEBUG
295  printf("pnew %d inside %d onedge %d\n", i, !!inside, !!onEdge );
296  #endif
297 
298  VERTEX v;
299 
300  v.indexp = i;
301  v.isHull = false;
302  v.pos = p;
303  v.type = inside && !onEdge ? INSIDE : onEdge ? ON_EDGE : OUTSIDE;
304  vts.push_back( v );
305  }
306 
307  #ifdef TOM_EXTRA_DEBUG
308  g_pnew = pnew;
309  g_hnew = hnew;
310  #endif
311 
312  // each path vertex neighbour list points for sure to the next vertex in the path
313  for( int i = 0; i < pnew.PointCount() - 1; i++ )
314  {
315  vts[i].neighbours.push_back( &vts[ i+1 ] );
316  }
317 
318  // each path vertex neighbour list points for sure to the next vertex in the path
319  for( int i = 1; i < pnew.PointCount() ; i++ )
320  {
321  vts[i].neighbours.push_back( &vts[ i-1 ] );
322  }
323 
324  // insert hull vertices into the graph
325  for( int i = 0; i < hnew.PointCount(); i++ )
326  {
327  auto hp = hnew.CPoint( i );
328  auto vn = findVertex( hp );
329 
330  // if vertex already present (it's very likely that in recursive shoving hull and path vertices will overlap)
331  // just mark it as a path vertex that also belongs to the hull
332  if( vn )
333  {
334  vn->isHull = true;
335  vn->indexh = i;
336  }
337  else // new hull vertex
338  {
339  VERTEX v;
340  v.pos = hp;
341  v.type = ON_EDGE;
342  v.indexh = i;
343  v.isHull = true;
344  vts.push_back( v );
345  }
346  }
347 
348  // go around the hull and fix up the neighbour link lists
349  for( int i = 0; i < hnew.PointCount(); i++ )
350  {
351  auto vc = findVertex( hnew.CPoint(i ) );
352  auto vnext = findVertex( hnew.CPoint( i+1 ) );
353 
354  if(vc && vnext)
355  vc->neighbours.push_back(vnext);
356  }
357 
358  // In the case that the initial path ends *inside* the current obstacle (i.e. the mouse cursor
359  // is somewhere inside the hull for the current obstacle) we want to end the walkaround at the
360  // point closest to the cursor
361  bool inLast = aObstacle.PointInside( CPoint( -1 ) ) && !aObstacle.PointOnEdge( CPoint( -1 ) );
362  bool appendV = true;
363  int lastDst = INT_MAX;
364 
365  int i = 0;
366 #ifdef TOM_EXTRA_DEBUG
367  for(auto &v: vts)
368  {
369  if( v.indexh < 0 && v.type == ON_EDGE )
370  {
371  v.type = OUTSIDE; // hack
372  }
373  printf("V %d pos %d %d ip %d ih %d type %d\n", i++, v.pos.x, v.pos.y, v.indexp, v.indexh, v.type );
374  }
375 #endif
376  // vts[0] = start point
377  VERTEX* v = &vts[0], *v_prev = nullptr;
378  SHAPE_LINE_CHAIN out;
379 
380  int iterLimit = 1000;
381 
382  // keep scanning the graph until we reach the end point of the path
383  while( v->indexp != ( pnew.PointCount() - 1 ) )
384  {
385  iterLimit--;
386 
387  // I'm not 100% sure this algorithm doesn't have bugs that may cause it to freeze,
388  // so here's a temporary iteration limit
389  if( iterLimit == 0 )
390  {
391  return false;
392  }
393 
394  if( v->visited )
395  {
396  // loop found? stop walking
397  break;
398  }
399 #ifdef TOM_EXTRA_DEBUG
400  printf("---\nvisit ip %d ih %d type %d outs %d neig %d\n", v->indexp, v->indexh, v->type, out.PointCount(), v->neighbours.size() );
401 #endif
402  out.Append( v->pos );
403 
404  VERTEX* v_next = nullptr;
405 
406  if( v->type == OUTSIDE )
407  {
408  // current vertex is outside? first look for any vertex further down the path
409  // that is not inside the hull
410  out.Append( v->pos );
411  VERTEX* v_next_fallback = nullptr;
412  for( auto vn : v->neighbours )
413  {
414  if( areNeighbours( vn->indexp , v->indexp, pnew.PointCount() ) &&
415  vn->type != INSIDE )
416  {
417  if( !vn->visited )
418  {
419  v_next = vn;
420  break;
421  }
422  else if( vn != v_prev )
423  v_next_fallback = vn;
424  }
425  }
426 
427  if( !v_next )
428  v_next = v_next_fallback;
429 
430  // such a vertex must always be present, if not, bummer.
431  if( !v_next )
432  {
433  #ifdef TOM_EXTRA_DEBUG
434  printf("FAIL VN fallback %p\n", v_next_fallback );
435  #endif
436  return false;
437  }
438 
439  }
440  else if( v->type == ON_EDGE )
441  {
442  // look first for the first vertex outside the hull
443  for( VERTEX* vn : v->neighbours )
444  {
445 #ifdef TOM_EXTRA_DEBUG
446  printf( "- OUT scan ip %d ih %d type %d\n", vn->indexp, vn->indexh, vn->type );
447 #endif
448 
449  if( vn->type == OUTSIDE && !vn->visited )
450  {
451  v_next = vn;
452  break;
453  }
454  }
455 
456  // no outside vertices found? continue traversing the hull
457  if( !v_next )
458  {
459  for( VERTEX* vn : v->neighbours )
460  {
461  #ifdef TOM_EXTRA_DEBUG
462  printf("- scan ip %d ih %d type %d\n", vn->indexp, vn->indexh, vn->type );
463  #endif
464  if( vn->type == ON_EDGE && !vn->isHull &&
465  areNeighbours( vn->indexp, v->indexp, pnew.PointCount() ) &&
466  ( vn->indexh == ( ( v->indexh + 1 ) % hnew.PointCount() ) ) )
467  {
468  v_next = vn;
469  break;
470  }
471  }
472  }
473 
474  // still nothing found? try to find the next (index-wise) point on the hull. I guess
475  // we should never reach this part of the code, but who really knows?
476  if( !v_next )
477  {
478  for( VERTEX* vn : v->neighbours )
479  {
480  if( vn->type == ON_EDGE )
481  {
482  if( vn->indexh == ( ( v->indexh + 1 ) % hnew.PointCount() ) )
483  {
484  v_next = vn;
485  break;
486  }
487  }
488  }
489 
490  // Did we get the next hull point but the end of the line is inside? Instead of walking
491  // around the hull some more (which will just end up taking us back to the start), lets
492  // just project the normal of the endpoint onto this next segment and call it quits.
493  if( inLast && v_next )
494  {
495  int d = ( v_next->pos - CPoint( -1 ) ).SquaredEuclideanNorm();
496 
497  if( d < lastDst )
498  {
499  lastDst = d;
500  }
501  else
502  {
503  VECTOR2I proj = SEG( v->pos, v_next->pos ).NearestPoint( CPoint( -1 ) );
504  out.Append( proj );
505  appendV = false;
506  break;
507  }
508  }
509  }
510  }
511 
512  v->visited = true;
513  v_prev = v;
514  v = v_next;
515 
516  if( !v )
517  {
518  return false;
519  }
520  }
521 
522  if( appendV )
523  out.Append( v->pos );
524 
525  aPath = out;
526 
527  return true;
528 }
const SHAPE_LINE_CHAIN & CLine() const
Definition: pns_line.h:137
void HullIntersection(const SHAPE_LINE_CHAIN &hull, const SHAPE_LINE_CHAIN &line, SHAPE_LINE_CHAIN::INTERSECTIONS &ips)
Definition: pns_utils.cpp:275
std::vector< INTERSECTION > INTERSECTIONS
Text appears outside the dimension line (default)
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)
SHAPE_LINE_CHAIN g_pnew
Definition: pns_line.cpp:169
int PointCount() const
Return the number of points (vertices) in this line chain.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
const VECTOR2I & CPoint(int aIdx) const
Definition: pns_line.h:145
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
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.
const VECTOR2I NearestPoint(const VECTOR2I &aP) const
Compute a point on the segment (this) that is closest to point aP.
Definition: seg.cpp:227
SHAPE_LINE_CHAIN g_hnew
Definition: pns_line.cpp:169
static int areNeighbours(int x, int y, int max=0)
Definition: pns_line.cpp:156
Definition: seg.h:40
Represent a polyline (an zero-thickness chain of connected line segments).

References SHAPE_LINE_CHAIN::Append(), PNS::areNeighbours(), CLine(), CPoint(), SHAPE_LINE_CHAIN::CPoint(), SHAPE_LINE_CHAIN::Find(), findVertex(), PNS::g_hnew, PNS::g_pnew, PNS::HullIntersection(), SEG::NearestPoint(), OUTSIDE, SHAPE_LINE_CHAIN::PointCount(), SHAPE_LINE_CHAIN_BASE::PointInside(), SHAPE_LINE_CHAIN_BASE::PointOnEdge(), SHAPE_LINE_CHAIN::Reverse(), SHAPE_LINE_CHAIN::SegmentCount(), 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_isVirtual

bool PNS::ITEM::m_isVirtual
protectedinherited

◆ 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 248 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 252 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: