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
 
void SetIsCompoundShapePrimitive ()
 
bool IsCompoundShapePrimitive () 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
 
bool m_isCompoundShapePrimitive
 

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:251
int m_rank
Definition: pns_item.h:256
bool m_movable
Definition: pns_item.h:253
int m_marker
Definition: pns_item.h:255
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:254
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:251
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:254
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:251
int m_rank
Definition: pns_item.h:256
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:254
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 222 of file pns_item.h.

223  {
224  return 0;
225  }

◆ AppendVia()

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

Definition at line 1046 of file pns_line.cpp.

1047 {
1048  if( m_line.PointCount() > 1 && aVia.Pos() == m_line.CPoint( 0 ) )
1049  {
1050  Reverse();
1051  }
1052 
1053  m_hasVia = true;
1054  m_via = aVia;
1055  m_via.SetNet( m_net );
1056 }
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:151
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:1038
bool m_hasVia
Optional via at the end point.
Definition: pns_line.h:249
int m_net
Definition: pns_item.h:254

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

182  {
183  return m_owner == aNode;
184  }
NODE * m_owner
Definition: pns_item.h:250

References PNS::ITEM::m_owner.

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

◆ ChangedArea()

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

Definition at line 1166 of file pns_line.cpp.

1167 {
1168  BOX2I area;
1169  bool areaDefined = false;
1170 
1171  int i_start = -1;
1172  int i_end_self = -1, i_end_other = -1;
1173 
1174  SHAPE_LINE_CHAIN self( m_line );
1175  self.Simplify();
1176  SHAPE_LINE_CHAIN other( aOther->m_line );
1177  other.Simplify();
1178 
1179  int np_self = self.PointCount();
1180  int np_other = other.PointCount();
1181 
1182  int n = std::min( np_self, np_other );
1183 
1184  for( int i = 0; i < n; i++ )
1185  {
1186  const VECTOR2I p1 = self.CPoint( i );
1187  const VECTOR2I p2 = other.CPoint( i );
1188 
1189  if( p1 != p2 )
1190  {
1191  if( i != n - 1 )
1192  {
1193  SEG s = self.CSegment( i );
1194 
1195  if( !s.Contains( p2 ) )
1196  {
1197  i_start = i;
1198  break;
1199  }
1200  }
1201  else
1202  {
1203  i_start = i;
1204  break;
1205  }
1206  }
1207  }
1208 
1209  for( int i = 0; i < n; i++ )
1210  {
1211  const VECTOR2I p1 = self.CPoint( np_self - 1 - i );
1212  const VECTOR2I p2 = other.CPoint( np_other - 1 - i );
1213 
1214  if( p1 != p2 )
1215  {
1216  i_end_self = np_self - 1 - i;
1217  i_end_other = np_other - 1 - i;
1218  break;
1219  }
1220  }
1221 
1222  if( i_start < 0 )
1223  i_start = n;
1224 
1225  if( i_end_self < 0 )
1226  i_end_self = np_self - 1;
1227 
1228  if( i_end_other < 0 )
1229  i_end_other = np_other - 1;
1230 
1231  for( int i = i_start; i <= i_end_self; i++ )
1232  extendBox( area, areaDefined, self.CPoint( i ) );
1233 
1234  for( int i = i_start; i <= i_end_other; i++ )
1235  extendBox( area, areaDefined, other.CPoint( i ) );
1236 
1237  if( areaDefined )
1238  {
1239  area.Inflate( std::max( Width(), aOther->Width() ) );
1240  return area;
1241  }
1242 
1243  return OPT_BOX2I();
1244 }
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 containing arcs as well as line segments: A chain of connected line and/or arc s...
static void extendBox(BOX2I &aBox, bool &aDefined, const VECTOR2I &aP)
Definition: pns_line.cpp:1152
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 1257 of file pns_line.cpp.

1258 {
1259  m_hasVia = false;
1260  m_line.Clear();
1261 }
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::COMPONENT_DRAGGER::Drag(), 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  VECTOR2I collisionPoint = obs->m_ipFirst;
580  int segIdx = l.Line().NearestSegment( collisionPoint );
581 
582  if( l.Line().IsArcSegment( segIdx ) )
583  {
584  // Don't clip at arcs, start again
585  l.Line().Clear();
586  }
587  else
588  {
589  SEG nearestSegment = l.Line().CSegment( segIdx );
590  VECTOR2I nearestPt = nearestSegment.NearestPoint( collisionPoint );
591  int p = l.Line().Split( nearestPt );
592  l.Line().Remove( p + 1, -1 );
593  }
594  }
595  else
596  {
597  break;
598  }
599  }
600 
601  if( i == IterationLimit )
602  l.Line().Clear();
603 
604  return l;
605 }
LINE()
Makes an empty line.
Definition: pns_line.h:66
const VECTOR2I NearestPoint(const VECTOR2I &aP) const
Compute a point on the segment (this) that is closest to point aP.
Definition: seg.cpp:227
Definition: seg.h:40
OPT< OBSTACLE > OPT_OBSTACLE
Definition: pns_node.h:149

References SHAPE_LINE_CHAIN::Clear(), SHAPE_LINE_CHAIN::CSegment(), SHAPE_LINE_CHAIN::IsArcSegment(), Line(), PNS::NODE::NearestObstacle(), SEG::NearestPoint(), SHAPE_LINE_CHAIN::NearestSegment(), 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 1088 of file pns_line.cpp.

1089 {
1096  int firstLink = 0;
1097  int lastLink = std::max( 0, static_cast<int>( m_links.size() ) - 1 );
1098  int linkIdx = 0;
1099 
1100  int numPoints = static_cast<int>( m_line.PointCount() );
1101 
1102  for( int i = 0; i >= 0 && i < m_line.PointCount(); i = m_line.NextShape( i ) )
1103  {
1104  if( i <= aStart )
1105  firstLink = linkIdx;
1106 
1107  if( i < 0 || i >= aEnd - 1 || linkIdx >= lastLink )
1108  {
1109  lastLink = linkIdx;
1110  break;
1111  }
1112 
1113  linkIdx++;
1114  }
1115 
1116  wxASSERT( lastLink >= firstLink );
1117 
1118  m_line = m_line.Slice( aStart, aEnd );
1119 
1120  if( IsLinked() )
1121  {
1122  wxASSERT( m_links.size() < INT_MAX );
1123  wxASSERT( static_cast<int>( m_links.size() ) >= ( lastLink - firstLink ) );
1124 
1125  // Note: The range includes aEnd, but we have n-1 segments.
1126  std::rotate(
1127  m_links.begin(),
1128  m_links.begin() + firstLink,
1129  m_links.begin() + lastLink
1130  );
1131 
1132  m_links.resize( lastLink - firstLink + 1 );
1133  }
1134 }
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 131 of file pns_item.cpp.

132 {
133  if( collideSimple( aOther, aNode, aDifferentNetsOnly ) )
134  return true;
135 
136  // Special cases for "head" lines with vias attached at the end. Note that this does not
137  // support head-line-via to head-line-via collisions, but you can't route two independent
138  // tracks at once so it shouldn't come up.
139 
140  if( m_kind == LINE_T )
141  {
142  const LINE* line = static_cast<const LINE*>( this );
143 
144  if( line->EndsWithVia() && line->Via().collideSimple( aOther, aNode, aDifferentNetsOnly ) )
145  return true;
146  }
147 
148  if( aOther->m_kind == LINE_T )
149  {
150  const LINE* line = static_cast<const LINE*>( aOther );
151 
152  if( line->EndsWithVia() && line->Via().collideSimple( this, aNode, aDifferentNetsOnly ) )
153  return true;
154  }
155 
156  return false;
157 }
PnsKind m_kind
Definition: pns_item.h:247
bool collideSimple(const ITEM *aOther, const NODE *aNode, bool aDifferentNetsOnly) const
Definition: pns_item.cpp:32

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

1033 {
1034  return m_line.CompareGeometry( aOther.m_line );
1035 }
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:77
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 749 of file pns_line.cpp.

750 {
751  wxCHECK_RET( aIndex >= 0, wxT( "Negative index passed to LINE::DragCorner" ) );
752 
753  if( aFreeAngle )
754  {
755  dragCornerFree( aP, aIndex );
756  }
757  else
758  {
759  dragCorner45( aP, aIndex );
760  }
761 }
void dragCorner45(const VECTOR2I &aP, int aIndex)
Definition: pns_line.cpp:692
void dragCornerFree(const VECTOR2I &aP, int aIndex)
Definition: pns_line.cpp:722

References dragCorner45(), and dragCornerFree().

Referenced by PNS::COMPONENT_DRAGGER::Drag(), 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 692 of file pns_line.cpp.

693 {
695 
696  int width = m_line.Width();
697  VECTOR2I snapped = snapDraggedCorner( m_line, aP, aIndex );
698 
699  if( aIndex == 0 )
700  path = dragCornerInternal( m_line.Reverse(), snapped ).Reverse();
701  else if( aIndex == m_line.SegmentCount() )
702  path = dragCornerInternal( m_line, snapped );
703  else
704  {
705  // Are we next to an arc? Insert a new point so we slice correctly
706  if( m_line.IsPtOnArc( static_cast<size_t>( aIndex ) + 1 ) )
707  m_line.Insert( aIndex + 1, m_line.CPoint( aIndex + 1 ) );
708 
709  // fixme: awkward behaviour for "outwards" drags
710  path = dragCornerInternal( m_line.Slice( 0, aIndex ), snapped );
711  SHAPE_LINE_CHAIN path_rev =
712  dragCornerInternal( m_line.Slice( aIndex + 1, -1 ).Reverse(), snapped ).Reverse();
713  path.Append( path_rev );
714  }
715 
716  path.Simplify();
717  path.SetWidth( width );
718  m_line = path;
719 }
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:609
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:1038
int SegmentCount() const
Return the number of segments in this line chain.
bool IsPtOnArc(size_t aPtIndex) const
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
VECTOR2I snapDraggedCorner(const SHAPE_LINE_CHAIN &aPath, const VECTOR2I &aP, int aIndex) const
Definition: pns_line.cpp:775

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

723 {
724  ssize_t idx = static_cast<ssize_t>( aIndex );
725  ssize_t numpts = static_cast<ssize_t>( m_line.PointCount() );
726 
727  // If we're asked to drag the end of an arc, insert a new vertex to drag instead
728  if( m_line.IsPtOnArc( idx ) )
729  {
730  if( idx == 0 || ( idx > 0 && !m_line.IsPtOnArc( idx - 1 ) ) )
731  {
732  m_line.Insert( idx, m_line.GetPoint( idx ) );
733  }
734  else if( ( idx == numpts - 1 ) || ( idx < numpts - 1 && !m_line.IsArcSegment( idx ) ) )
735  {
736  idx++;
737  m_line.Insert( idx, m_line.GetPoint( idx ) );
738  }
739  else
740  {
741  wxASSERT_MSG( false, wxT( "Attempt to dragCornerFree in the middle of an arc!" ) );
742  }
743  }
744 
745  m_line.SetPoint( idx, aP );
746  m_line.Simplify();
747 }
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 763 of file pns_line.cpp.

764 {
765  if( aFreeAngle )
766  {
767  assert( false );
768  }
769  else
770  {
771  dragSegment45( aP, aIndex );
772  }
773 }
void dragSegment45(const VECTOR2I &aP, int aIndex)
Definition: pns_line.cpp:862

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

863 {
865  VECTOR2I target( aP );
866 
867  wxASSERT( aIndex < m_line.PointCount() );
868 
869  SEG guideA[2], guideB[2];
870  int index = aIndex;
871 
872  target = snapToNeighbourSegments( path, aP, aIndex );
873 
874  // We require a valid s_prev and s_next. If we are at the start or end of the line, we insert
875  // a new point at the start or end so there is a zero-length segment for prev or next (we will
876  // resize it as part of the drag operation). If we are next to an arc, we do this also, as we
877  // cannot drag away one of the arc's points.
878 
879  if( index == 0 || path.IsPtOnArc( index ) )
880  {
881  path.Insert( index > 0 ? index + 1 : 0, path.CPoint( index ) );
882  index++;
883  }
884 
885  if( index == path.SegmentCount() - 1 )
886  {
887  path.Insert( path.PointCount() - 1, path.CPoint( -1 ) );
888  }
889  else if( path.IsPtOnArc( index + 1 ) )
890  {
891  path.Insert( index + 1, path.CPoint( index + 1 ) );
892  }
893 
894  SEG dragged = path.CSegment( index );
895  DIRECTION_45 drag_dir( dragged );
896 
897  SEG s_prev = path.CSegment( index - 1 );
898  SEG s_next = path.CSegment( index + 1 );
899 
900  DIRECTION_45 dir_prev( s_prev );
901  DIRECTION_45 dir_next( s_next );
902 
903  if( dir_prev == drag_dir )
904  {
905  dir_prev = dir_prev.Left();
906  path.Insert( index, path.CPoint( index ) );
907  index++;
908  }
909  else if( dir_prev == DIRECTION_45::UNDEFINED )
910  {
911  dir_prev = drag_dir.Left();
912  }
913 
914  if( dir_next == drag_dir )
915  {
916  dir_next = dir_next.Right();
917  path.Insert( index + 1, path.CPoint( index + 1 ) );
918  }
919  else if( dir_next == DIRECTION_45::UNDEFINED )
920  {
921  dir_next = drag_dir.Right();
922  }
923 
924  s_prev = path.CSegment( index - 1 );
925  s_next = path.CSegment( index + 1 );
926  dragged = path.CSegment( index );
927 
928  if( aIndex == 0 )
929  {
930  guideA[0] = SEG( dragged.A, dragged.A + drag_dir.Right().ToVector() );
931  guideA[1] = SEG( dragged.A, dragged.A + drag_dir.Left().ToVector() );
932  }
933  else
934  {
935  if( dir_prev.Angle( drag_dir )
937  {
938  guideA[0] = SEG( s_prev.A, s_prev.A + drag_dir.Left().ToVector() );
939  guideA[1] = SEG( s_prev.A, s_prev.A + drag_dir.Right().ToVector() );
940  }
941  else
942  guideA[0] = guideA[1] = SEG( dragged.A, dragged.A + dir_prev.ToVector() );
943  }
944 
945  if( aIndex == m_line.SegmentCount() - 1 )
946  {
947  guideB[0] = SEG( dragged.B, dragged.B + drag_dir.Right().ToVector() );
948  guideB[1] = SEG( dragged.B, dragged.B + drag_dir.Left().ToVector() );
949  }
950  else
951  {
952  if( dir_next.Angle( drag_dir )
954  {
955  guideB[0] = SEG( s_next.B, s_next.B + drag_dir.Left().ToVector() );
956  guideB[1] = SEG( s_next.B, s_next.B + drag_dir.Right().ToVector() );
957  }
958  else
959  guideB[0] = guideB[1] = SEG( dragged.B, dragged.B + dir_next.ToVector() );
960  }
961 
962  SEG s_current( target, target + drag_dir.ToVector() );
963 
964  int best_len = INT_MAX;
965  SHAPE_LINE_CHAIN best;
966 
967  for( int i = 0; i < 2; i++ )
968  {
969  for( int j = 0; j < 2; j++ )
970  {
971  OPT_VECTOR2I ip1 = s_current.IntersectLines( guideA[i] );
972  OPT_VECTOR2I ip2 = s_current.IntersectLines( guideB[j] );
973 
974  SHAPE_LINE_CHAIN np;
975 
976  if( !ip1 || !ip2 )
977  continue;
978 
979  SEG s1( s_prev.A, *ip1 );
980  SEG s2( *ip1, *ip2 );
981  SEG s3( *ip2, s_next.B );
982 
983  OPT_VECTOR2I ip;
984 
985  if( ( ip = s1.Intersect( s_next ) ) )
986  {
987  np.Append( s1.A );
988  np.Append( *ip );
989  np.Append( s_next.B );
990  }
991  else if( ( ip = s3.Intersect( s_prev ) ) )
992  {
993  np.Append( s_prev.A );
994  np.Append( *ip );
995  np.Append( s3.B );
996  }
997  else if( ( ip = s1.Intersect( s3 ) ) )
998  {
999  np.Append( s_prev.A );
1000  np.Append( *ip );
1001  np.Append( s_next.B );
1002  }
1003  else
1004  {
1005  np.Append( s_prev.A );
1006  np.Append( *ip1 );
1007  np.Append( *ip2 );
1008  np.Append( s_next.B );
1009  }
1010 
1011  if( np.Length() < best_len )
1012  {
1013  best_len = np.Length();
1014  best = np;
1015  }
1016  }
1017  }
1018 
1019  if( m_line.PointCount() == 1 )
1020  m_line = best;
1021  else if( aIndex == 0 )
1022  m_line.Replace( 0, 1, best );
1023  else if( aIndex == m_line.SegmentCount() - 1 )
1024  m_line.Replace( -2, -1, best );
1025  else
1026  m_line.Replace( aIndex, aIndex + 1, best );
1027 
1028  m_line.Simplify();
1029 }
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:817
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 containing arcs as well as line segments: A chain of connected line and/or arc s...
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 1247 of file pns_line.cpp.

1248 {
1249  for( const auto seg : m_links )
1250  {
1251  if( seg->Marker() & MK_LOCKED )
1252  return true;
1253  }
1254  return false;
1255 }

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

1138 {
1139  for( int i = 0; i < PointCount(); i++ )
1140  {
1141  for( int j = i + 2; j < PointCount(); j++ )
1142  {
1143  if( CPoint( i ) == CPoint( j ) )
1144  return true;
1145  }
1146  }
1147 
1148  return false;
1149 }
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 205 of file pns_item.h.

206  {
207  return nullptr;
208  }

Referenced by PNS::ITEM::collideSimple(), ROUTER_PREVIEW_ITEM::ROUTER_PREVIEW_ITEM(), and ROUTER_PREVIEW_ITEM::Update().

◆ HoleHull()

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

Reimplemented in PNS::SOLID.

Definition at line 121 of file pns_item.h.

123  {
124  return SHAPE_LINE_CHAIN();
125  }
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...

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

117  {
118  return SHAPE_LINE_CHAIN();
119  }
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...

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

◆ IsCompoundShapePrimitive()

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

Definition at line 241 of file pns_item.h.

241 { return m_isCompoundShapePrimitive; }
bool m_isCompoundShapePrimitive
Definition: pns_item.h:259

References PNS::ITEM::m_isCompoundShapePrimitive.

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

228  {
229  return Marker() & MK_LOCKED;
230  }
virtual int Marker() const
Definition: pns_item.h:212

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

233 { return m_routable; }
bool m_routable
Definition: pns_item.h:257

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 160 of file pns_item.cpp.

161 {
162  switch( m_kind )
163  {
164  case ARC_T: return "arc";
165  case LINE_T: return "line";
166  case SEGMENT_T: return "segment";
167  case VIA_T: return "via";
168  case JOINT_T: return "joint";
169  case SOLID_T: return "solid";
170  case DIFF_PAIR_T: return "diff-pair";
171  default: return "unknown";
172  }
173 }
PnsKind m_kind
Definition: pns_item.h:247

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

154 { return m_layers; }
LAYER_RANGE m_layers
Definition: pns_item.h:251

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(), PNS::COMPONENT_DRAGGER::Start(), 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 163 of file pns_item.h.

164  {
165  return Layers().Overlaps( aOther->Layers() );
166  }
bool Overlaps(const LAYER_RANGE &aOther) const
Definition: pns_layerset.h:67
const LAYER_RANGE & Layers() const
Definition: pns_item.h:154

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

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

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

Definition at line 152 of file pns_item.h.

152 { return m_net; }
int m_net
Definition: pns_item.h:254

References PNS::ITEM::m_net.

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::LINE_PLACER::buildInitialLine(), PNS::KEEP_TOPOLOGY_CONSTRAINT::Check(), PNS::VIA::Clone(), PNS::MEANDER_PLACER::CurrentNets(), PNS::DRAGGER::CurrentNets(), PNS::DIFF_PAIR::DIFF_PAIR(), PNS::OPTIMIZER::fanoutCleanup(), PNS::DIFF_PAIR_PLACER::FindDpPrimitivePair(), PNS::NODE::FindJoint(), PNS::NODE::findRedundantArc(), PNS::NODE::findRedundantSegment(), PNS::LINE_PLACER::FixRoute(), ROUTER_TOOL::InlineDrag(), PNS_PCBNEW_RULE_RESOLVER::IsDiffPair(), PNS::ROUTER::isStartingPointRoutable(), LINE(), PNS::NODE::LockJoint(), PNS::VIA::MakeHandle(), ROUTER_TOOL::performDragging(), LENGTH_TUNER_TOOL::performTuning(), ROUTER_TOOL::prepareInteractive(), PNS_PCBNEW_RULE_RESOLVER::QueryConstraint(), PNS::NODE::rebuildJoint(), PNS::INDEX::Remove(), PNS::NODE::removeArcIndex(), PNS::NODE::removeSegmentIndex(), PNS::NODE::removeSolidIndex(), PNS::NODE::removeViaIndex(), PNS::OPTIMIZER::runSmartPads(), PNS::SEGMENT::SEGMENT(), PNS::SHOVE::ShoveObstacleLine(), PNS::MEANDER_SKEW_PLACER::Start(), PNS::DIFF_PAIR_PLACER::Start(), PNS::LINE_PLACER::Start(), ROUTER_TOOL::UpdateMessagePanel(), and PNS::VIA::VIA().

◆ 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:250
LAYER_RANGE m_layers
Definition: pns_item.h:251
int m_rank
Definition: pns_item.h:256
bool m_movable
Definition: pns_item.h:253
int m_marker
Definition: pns_item.h:255
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:254
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 171 of file pns_item.h.

171 { return m_owner; }
NODE * m_owner
Definition: pns_item.h:250

References PNS::ITEM::m_owner.

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

◆ Parent()

◆ PointCount()

◆ Rank()

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

Reimplemented from PNS::ITEM.

Definition at line 1069 of file pns_line.cpp.

1070 {
1071  int min_rank = INT_MAX;
1072 
1073  if( IsLinked() ) {
1074  for( auto s : m_links )
1075  {
1076  min_rank = std::min( min_rank, s->Rank() );
1077  }
1078  } else {
1079  min_rank = m_rank;
1080  }
1081 
1082  int rank = ( min_rank == INT_MAX ) ? -1 : min_rank;
1083 
1084  return rank;
1085 }
int m_rank
Definition: pns_item.h:256

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

1039 {
1040  m_line = m_line.Reverse();
1041 
1042  std::reverse( m_links.begin(), m_links.end() );
1043 }
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().

◆ SetIsCompoundShapePrimitive()

void PNS::ITEM::SetIsCompoundShapePrimitive ( )
inlineinherited

Definition at line 240 of file pns_item.h.

240 { m_isCompoundShapePrimitive = true; }
bool m_isCompoundShapePrimitive
Definition: pns_item.h:259

References PNS::ITEM::m_isCompoundShapePrimitive.

◆ SetLayer()

◆ SetLayers()

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

Definition at line 155 of file pns_item.h.

155 { m_layers = aLayers; }
LAYER_RANGE m_layers
Definition: pns_item.h:251

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

176 { m_owner = aOwner; }
NODE * m_owner
Definition: pns_item.h:250

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

148 { m_parent = aParent; }
BOARD_ITEM * m_parent
Definition: pns_item.h:249

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

1060 {
1061  m_rank = aRank;
1062 
1063  for( auto s : m_links )
1064  s->SetRank( aRank );
1065 
1066 }
int m_rank
Definition: pns_item.h:256

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

232 { m_routable = aRoutable; }
bool m_routable
Definition: pns_item.h:257

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

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

777 {
778  int s_start = std::max( aIndex - 2, 0 );
779  int s_end = std::min( aIndex + 2, aPath.SegmentCount() - 1 );
780 
781  int i, j;
782  int best_dist = INT_MAX;
783  VECTOR2I best_snap = aP;
784 
785  if( m_snapThreshhold <= 0 )
786  return aP;
787 
788  for( i = s_start; i <= s_end; i++ )
789  {
790  const SEG& a = aPath.CSegment( i );
791 
792  for( j = s_start; j < i; j++ )
793  {
794  const SEG& b = aPath.CSegment( j );
795 
796  if( !( DIRECTION_45( a ).IsObtuse( DIRECTION_45( b ) ) ) )
797  continue;
798 
799  OPT_VECTOR2I ip = a.IntersectLines( b );
800 
801  if( ip )
802  {
803  int dist = ( *ip - aP ).EuclideanNorm();
804 
805  if( dist < m_snapThreshhold && dist < best_dist )
806  {
807  best_dist = dist;
808  best_snap = *ip;
809  }
810  }
811  }
812  }
813 
814  return best_snap;
815 }
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 817 of file pns_line.cpp.

819 {
820  VECTOR2I snap_p[2];
821  DIRECTION_45 dragDir( aPath.CSegment( aIndex ) );
822  int snap_d[2] = { -1, -1 };
823 
824  if( m_snapThreshhold == 0 )
825  return aP;
826 
827  if( aIndex >= 2 )
828  {
829  SEG s = aPath.CSegment( aIndex - 2 );
830 
831  if( DIRECTION_45( s ) == dragDir )
832  snap_d[0] = s.LineDistance( aP );
833 
834  snap_p[0] = s.A;
835  }
836 
837  if( aIndex < aPath.SegmentCount() - 2 )
838  {
839  SEG s = aPath.CSegment( aIndex + 2 );
840 
841  if( DIRECTION_45( s ) == dragDir )
842  snap_d[1] = s.LineDistance( aP );
843 
844  snap_p[1] = s.A;
845  }
846 
847  VECTOR2I best = aP;
848  int minDist = INT_MAX;
849 
850  for( int i = 0; i < 2; i++ )
851  {
852  if( snap_d[i] >= 0 && snap_d[i] < minDist && snap_d[i] <= m_snapThreshhold )
853  {
854  minDist = snap_d[i];
855  best = snap_p[i];
856  }
857  }
858 
859  return best;
860 }
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:255

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

Referenced by PNS::COMPONENT_DRAGGER::Drag(), 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:296
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 containing arcs as well as line segments: A chain of connected line and/or arc s...

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_isCompoundShapePrimitive

bool PNS::ITEM::m_isCompoundShapePrimitive
protectedinherited

◆ 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 253 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 257 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: