KiCad PCB EDA Suite
PNS::LINE Class Reference

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

#include <pns_line.h>

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

Public Types

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

Public Member Functions

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

Static Public Member Functions

static bool ClassOf (const ITEM *aItem)
 

Static Public Attributes

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

Protected Member Functions

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

Protected Attributes

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

Private Member Functions

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

Private Attributes

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

Detailed Description

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

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

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

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

Definition at line 60 of file pns_line.h.

Member Typedef Documentation

◆ LINKS

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

Definition at line 36 of file pns_link_holder.h.

Member Enumeration Documentation

◆ PnsKind

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

Definition at line 61 of file pns_item.h.

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

Constructor & Destructor Documentation

◆ LINE() [1/4]

PNS::LINE::LINE ( )
inline

Makes an empty line.

Definition at line 66 of file pns_line.h.

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

References m_hasVia, m_snapThreshhold, and m_width.

Referenced by Clone().

◆ LINE() [2/4]

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

Definition at line 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:239
int m_rank
Definition: pns_item.h:244
bool m_movable
Definition: pns_item.h:241
int m_marker
Definition: pns_item.h:243
ITEM * m_blockingObstacle
For mark obstacle mode.
Definition: pns_line.h:252
SHAPE_LINE_CHAIN m_line
The actual shape of the line.
Definition: pns_line.h:243
bool m_hasVia
Optional via at the end point.
Definition: pns_line.h:249
int m_net
Definition: pns_item.h:242
int m_snapThreshhold
Width to smooth out jagged segments.
Definition: pns_line.h:247
int m_width
Our width.
Definition: pns_line.h:244

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

◆ LINE() [3/4]

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

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

Definition at line 80 of file pns_line.h.

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

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

◆ LINE() [4/4]

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

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

Definition at line 95 of file pns_line.h.

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

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

◆ ~LINE()

PNS::LINE::~LINE ( )

Definition at line 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 218 of file pns_item.h.

219  {
220  return 0;
221  }

◆ AppendVia()

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

Definition at line 915 of file pns_line.cpp.

916 {
917  if( m_line.PointCount() > 1 && aVia.Pos() == m_line.CPoint( 0 ) )
918  {
919  Reverse();
920  }
921 
922  m_hasVia = true;
923  m_via = aVia;
924  m_via.SetNet( m_net );
925 }
VIA m_via
Definition: pns_line.h:250
int PointCount() const
Function PointCount()
void SetNet(int aNet)
Definition: pns_item.h:147
SHAPE_LINE_CHAIN m_line
The actual shape of the line.
Definition: pns_line.h:243
const VECTOR2I & CPoint(int aIndex) const
Function Point()
void Reverse()
Clip the line to the nearest obstacle, traversing from the line's start vertex (0).
Definition: pns_line.cpp:907
bool m_hasVia
Optional via at the end point.
Definition: pns_line.h:249
int m_net
Definition: pns_item.h:242

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

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

◆ ArcCount()

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

Definition at line 141 of file pns_line.h.

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

References SHAPE_LINE_CHAIN::ArcCount(), and m_line.

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

◆ BelongsTo()

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

Definition at line 177 of file pns_item.h.

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

References PNS::ITEM::m_owner.

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

◆ ChangedArea()

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

Definition at line 1053 of file pns_line.cpp.

1054 {
1055  BOX2I area;
1056  bool areaDefined = false;
1057 
1058  int i_start = -1;
1059  int i_end_self = -1, i_end_other = -1;
1060 
1061  SHAPE_LINE_CHAIN self( m_line );
1062  self.Simplify();
1063  SHAPE_LINE_CHAIN other( aOther->m_line );
1064  other.Simplify();
1065 
1066  int np_self = self.PointCount();
1067  int np_other = other.PointCount();
1068 
1069  int n = std::min( np_self, np_other );
1070 
1071  for( int i = 0; i < n; i++ )
1072  {
1073  const VECTOR2I p1 = self.CPoint( i );
1074  const VECTOR2I p2 = other.CPoint( i );
1075 
1076  if( p1 != p2 )
1077  {
1078  if( i != n - 1 )
1079  {
1080  SEG s = self.CSegment( i );
1081 
1082  if( !s.Contains( p2 ) )
1083  {
1084  i_start = i;
1085  break;
1086  }
1087  }
1088  else
1089  {
1090  i_start = i;
1091  break;
1092  }
1093  }
1094  }
1095 
1096  for( int i = 0; i < n; i++ )
1097  {
1098  const VECTOR2I p1 = self.CPoint( np_self - 1 - i );
1099  const VECTOR2I p2 = other.CPoint( np_other - 1 - i );
1100 
1101  if( p1 != p2 )
1102  {
1103  i_end_self = np_self - 1 - i;
1104  i_end_other = np_other - 1 - i;
1105  break;
1106  }
1107  }
1108 
1109  if( i_start < 0 )
1110  i_start = n;
1111 
1112  if( i_end_self < 0 )
1113  i_end_self = np_self - 1;
1114 
1115  if( i_end_other < 0 )
1116  i_end_other = np_other - 1;
1117 
1118  for( int i = i_start; i <= i_end_self; i++ )
1119  extendBox( area, areaDefined, self.CPoint( i ) );
1120 
1121  for( int i = i_start; i <= i_end_other; i++ )
1122  extendBox( area, areaDefined, other.CPoint( i ) );
1123 
1124  if( areaDefined )
1125  {
1126  area.Inflate( std::max( Width(), aOther->Width() ) );
1127  return area;
1128  }
1129 
1130  return OPT_BOX2I();
1131 }
SHAPE_LINE_CHAIN & Simplify(bool aRemoveColinear=true)
Function Simplify()
const VECTOR2I & CPoint(int aIdx) const
Definition: pns_line.h:145
SHAPE_LINE_CHAIN m_line
The actual shape of the line.
Definition: pns_line.h:243
Definition: seg.h:41
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:302
SHAPE_LINE_CHAIN.
static void extendBox(BOX2I &aBox, bool &aDefined, const VECTOR2I &aP)
Definition: pns_line.cpp:1039
int Width() const
Return true if the line is geometrically identical as line aOther.
Definition: pns_line.h:156
OPT< BOX2I > OPT_BOX2I
Definition: box2.h:525
bool Contains(const SEG &aSeg) const
Definition: seg.h:336

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

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

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

◆ ClearLinks()

◆ CLine()

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

Definition at line 137 of file pns_line.h.

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

References m_line.

Referenced by PNS::COST_ESTIMATOR::Add(), PNS::DIFF_PAIR_PLACER::attemptWalk(), PNS::KEEP_TOPOLOGY_CONSTRAINT::Check(), PNS::NODE::CheckColliding(), PNS::SHOVE::checkShoveDirection(), PNS::COST_ESTIMATOR::CornerCost(), PNS::DIFF_PAIR::DIFF_PAIR(), PNS::MEANDER_PLACER::doMove(), PNS::DRAGGER::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::SHOVE::ShoveLines(), PNS::SHOVE::shoveLineToHullSet(), PNS::SHOVE::ShoveObstacleLine(), PNS::TOPOLOGY::SimplifyLine(), PNS::WALKAROUND::singleStep(), PNS::OPTIMIZER::smartPadsSingle(), 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 454 of file pns_line.cpp.

455 {
456  const int IterationLimit = 5;
457  int i;
458  LINE l( *this );
459 
460  for( i = 0; i < IterationLimit; i++ )
461  {
462  NODE::OPT_OBSTACLE obs = aNode->NearestObstacle( &l );
463 
464  if( obs )
465  {
466  l.RemoveVia();
467  int p = l.Line().Split( obs->m_ipFirst );
468  l.Line().Remove( p + 1, -1 );
469  } else
470  break;
471  }
472 
473  if( i == IterationLimit )
474  l.Line().Clear();
475 
476  return l;
477 }
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(), PNS::LINE_PLACER::rhWalkOnly(), and PNS::WALKAROUND::singleStep().

◆ ClipVertexRange()

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

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

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

Definition at line 957 of file pns_line.cpp.

958 {
965  int firstLink = 0;
966  int lastLink = std::max( 0, static_cast<int>( m_links.size() ) - 1 );
967  int arcIdx = -1;
968  int linkIdx = 0;
969 
970  auto shapes = m_line.CShapes();
971  int numPoints = static_cast<int>( shapes.size() );
972 
973  for( int i = 0; i < m_line.PointCount(); i++ )
974  {
975  if( i <= aStart )
976  firstLink = linkIdx;
977 
978  if( shapes[i] >= 0 )
979  {
980  // Account for "hidden segments" between two arcs
981  if( i > aStart && ( shapes[i - 1] >= 0 ) && ( shapes[i - 1] != shapes[i] ) )
982  linkIdx++;
983 
984  arcIdx = shapes[i];
985 
986  // Skip over the rest of the arc vertices
987  while( i < numPoints && shapes[i] == arcIdx )
988  i++;
989 
990  // Back up two vertices to restart at the segment coincident with the end of the arc
991  i -= 2;
992  }
993 
994  if( i >= aEnd - 1 || linkIdx >= lastLink )
995  {
996  lastLink = linkIdx;
997  break;
998  }
999 
1000  linkIdx++;
1001  }
1002 
1003  wxASSERT( lastLink >= firstLink );
1004 
1005  m_line = m_line.Slice( aStart, aEnd );
1006 
1007  if( IsLinked() )
1008  {
1009  wxASSERT( m_links.size() < INT_MAX );
1010  wxASSERT( static_cast<int>( m_links.size() ) >= ( lastLink - firstLink ) );
1011 
1012  // Note: The range includes aEnd, but we have n-1 segments.
1013  std::rotate(
1014  m_links.begin(),
1015  m_links.begin() + firstLink,
1016  m_links.begin() + lastLink
1017  );
1018 
1019  m_links.resize( lastLink - firstLink + 1 );
1020  }
1021 }
const SHAPE_LINE_CHAIN Slice(int aStartIndex, int aEndIndex=-1) const
Function Slice()
int PointCount() const
Function PointCount()
SHAPE_LINE_CHAIN m_line
The actual shape of the line.
Definition: pns_line.h:243
const std::vector< ssize_t > & CShapes() const

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

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

◆ Clone()

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

Return a deep copy of the item.

Implements PNS::ITEM.

Definition at line 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 independant
104  // tracks at once so it shouldn't come up.
105 
106  if( m_kind == LINE_T )
107  {
108  const LINE* line = static_cast<const LINE*>( this );
109 
110  if( line->EndsWithVia() && line->Via().collideSimple( aOther, aNode, aDifferentNetsOnly ) )
111  return true;
112  }
113 
114  if( aOther->m_kind == LINE_T )
115  {
116  const LINE* line = static_cast<const LINE*>( aOther );
117 
118  if( line->EndsWithVia() && line->Via().collideSimple( this, aNode, aDifferentNetsOnly ) )
119  return true;
120  }
121 
122  return false;
123 }
PnsKind m_kind
Definition: pns_item.h:235
bool collideSimple(const ITEM *aOther, const NODE *aNode, bool aDifferentNetsOnly) const
Definition: pns_item.cpp:31

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

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

◆ CompareGeometry()

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

Reverse the point/vertex order.

Definition at line 901 of file pns_line.cpp.

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

References SHAPE_LINE_CHAIN::CompareGeometry(), and m_line.

◆ ContainsLink()

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

Definition at line 58 of file pns_link_holder.h.

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

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

◆ copyLinks()

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

< Copy m_links from the line aParent.

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

Definition at line 98 of file pns_link_holder.h.

References PNS::LINK_HOLDER::m_links.

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

◆ CountCorners()

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

Definition at line 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
Function SegmentCount()
Definition: seg.h:41
AngleType
Represent kind of angle formed by vectors heading in two DIRECTION_45s.
Definition: direction45.h:65
const SEG CSegment(int aIndex) const
Function CSegment()

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

Referenced by PNS::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 616 of file pns_line.cpp.

617 {
618  wxCHECK_RET( aIndex >= 0, "Negative index passed to LINE::DragCorner" );
619 
620  if( aFreeAngle )
621  {
622  dragCornerFree( aP, aIndex );
623  }
624  else
625  {
626  dragCorner45( aP, aIndex );
627  }
628 }
void dragCorner45(const VECTOR2I &aP, int aIndex)
Definition: pns_line.cpp:564
void dragCornerFree(const VECTOR2I &aP, int aIndex)
Definition: pns_line.cpp:594

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

565 {
567 
568  int width = m_line.Width();
569  VECTOR2I snapped = snapDraggedCorner( m_line, aP, aIndex );
570 
571  if( aIndex == 0 )
572  path = dragCornerInternal( m_line.Reverse(), snapped ).Reverse();
573  else if( aIndex == m_line.SegmentCount() )
574  path = dragCornerInternal( m_line, snapped );
575  else
576  {
577  // Are we next to an arc? Insert a new point so we slice correctly
578  if( m_line.CShapes()[aIndex + 1] >= 0 )
579  m_line.Insert( aIndex + 1, m_line.CPoint( aIndex + 1 ) );
580 
581  // fixme: awkward behaviour for "outwards" drags
582  path = dragCornerInternal( m_line.Slice( 0, aIndex ), snapped );
583  SHAPE_LINE_CHAIN path_rev =
584  dragCornerInternal( m_line.Slice( aIndex + 1, -1 ).Reverse(), snapped ).Reverse();
585  path.Append( path_rev );
586  }
587 
588  path.Simplify();
589  path.SetWidth( width );
590  m_line = path;
591 }
const SHAPE_LINE_CHAIN Slice(int aStartIndex, int aEndIndex=-1) const
Function Slice()
int Width() const
Gets the current width of the segments in the chain.
const SHAPE_LINE_CHAIN Reverse() const
Function Reverse()
SHAPE_LINE_CHAIN dragCornerInternal(const SHAPE_LINE_CHAIN &aOrigin, const VECTOR2I &aP)
Definition: pns_line.cpp:481
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 std::vector< ssize_t > & CShapes() const
const VECTOR2I & CPoint(int aIndex) const
Function Point()
void Reverse()
Clip the line to the nearest obstacle, traversing from the line's start vertex (0).
Definition: pns_line.cpp:907
int SegmentCount() const
Function SegmentCount()
SHAPE_LINE_CHAIN.
VECTOR2I snapDraggedCorner(const SHAPE_LINE_CHAIN &aPath, const VECTOR2I &aP, int aIndex) const
Definition: pns_line.cpp:642

References SHAPE_LINE_CHAIN::CPoint(), SHAPE_LINE_CHAIN::CShapes(), PNS::dragCornerInternal(), SHAPE_LINE_CHAIN::Insert(), 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 594 of file pns_line.cpp.

595 {
596  const std::vector<ssize_t>& shapes = m_line.CShapes();
597 
598  // If we're asked to drag the end of an arc, insert a new vertex to drag instead
599  if( shapes[aIndex] >= 0 )
600  {
601  if( aIndex > 0 && shapes[aIndex - 1] == -1 )
602  m_line.Insert( aIndex, m_line.GetPoint( aIndex ) );
603  else if( aIndex < shapes.size() - 1 && shapes[aIndex + 1] != shapes[aIndex] )
604  {
605  aIndex++;
606  m_line.Insert( aIndex, m_line.GetPoint( aIndex ) );
607  }
608  else
609  wxASSERT_MSG( false, "Attempt to dragCornerFree in the middle of an arc!" );
610  }
611 
612  m_line.SetPoint( aIndex, aP );
613  m_line.Simplify();
614 }
SHAPE_LINE_CHAIN & Simplify(bool aRemoveColinear=true)
Function Simplify()
void SetPoint(int aIndex, const VECTOR2I &aPos)
Accessor Function to move a point to a specific location.
SHAPE_LINE_CHAIN m_line
The actual shape of the line.
Definition: pns_line.h:243
void Insert(size_t aVertex, const VECTOR2I &aP)
const std::vector< ssize_t > & CShapes() const
virtual const VECTOR2I GetPoint(int aIndex) const override

References SHAPE_LINE_CHAIN::CShapes(), SHAPE_LINE_CHAIN::GetPoint(), SHAPE_LINE_CHAIN::Insert(), m_line, SHAPE_LINE_CHAIN::SetPoint(), and SHAPE_LINE_CHAIN::Simplify().

Referenced by DragCorner().

◆ DragSegment()

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

Definition at line 630 of file pns_line.cpp.

631 {
632  if( aFreeAngle )
633  {
634  assert( false );
635  }
636  else
637  {
638  dragSegment45( aP, aIndex );
639  }
640 }
void dragSegment45(const VECTOR2I &aP, int aIndex)
Definition: pns_line.cpp:729

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

730 {
732  VECTOR2I target( aP );
733 
734  wxASSERT( aIndex < m_line.PointCount() );
735 
736  SEG guideA[2], guideB[2];
737  int index = aIndex;
738 
739  target = snapToNeighbourSegments( path, aP, aIndex );
740 
741  const std::vector<ssize_t>& shapes = path.CShapes();
742 
743  // We require a valid s_prev and s_next. If we are at the start or end of the line, we insert
744  // a new point at the start or end so there is a zero-length segment for prev or next (we will
745  // resize it as part of the drag operation). If we are next to an arc, we do this also, as we
746  // cannot drag away one of the arc's points.
747 
748  if( index == 0 || shapes[index] >= 0 )
749  {
750  path.Insert( index > 0 ? index + 1 : 0, path.CPoint( index ) );
751  index++;
752  }
753 
754  if( index == path.SegmentCount() - 1 )
755  {
756  path.Insert( path.PointCount() - 1, path.CPoint( -1 ) );
757  }
758  else if( shapes[index + 1] >= 0 )
759  {
760  path.Insert( index + 1, path.CPoint( index + 1 ) );
761  }
762 
763  SEG dragged = path.CSegment( index );
764  DIRECTION_45 drag_dir( dragged );
765 
766  SEG s_prev = path.CSegment( index - 1 );
767  SEG s_next = path.CSegment( index + 1 );
768 
769  DIRECTION_45 dir_prev( s_prev );
770  DIRECTION_45 dir_next( s_next );
771 
772  if( dir_prev == drag_dir )
773  {
774  dir_prev = dir_prev.Left();
775  path.Insert( index, path.CPoint( index ) );
776  index++;
777  }
778  else if( dir_prev == DIRECTION_45::UNDEFINED )
779  {
780  dir_prev = drag_dir.Left();
781  }
782 
783  if( dir_next == drag_dir )
784  {
785  dir_next = dir_next.Right();
786  path.Insert( index + 1, path.CPoint( index + 1 ) );
787  }
788  else if( dir_next == DIRECTION_45::UNDEFINED )
789  {
790  dir_next = drag_dir.Right();
791  }
792 
793  s_prev = path.CSegment( index - 1 );
794  s_next = path.CSegment( index + 1 );
795  dragged = path.CSegment( index );
796 
797  if( aIndex == 0 )
798  {
799  guideA[0] = SEG( dragged.A, dragged.A + drag_dir.Right().ToVector() );
800  guideA[1] = SEG( dragged.A, dragged.A + drag_dir.Left().ToVector() );
801  }
802  else
803  {
804  if( dir_prev.Angle( drag_dir )
806  {
807  guideA[0] = SEG( s_prev.A, s_prev.A + drag_dir.Left().ToVector() );
808  guideA[1] = SEG( s_prev.A, s_prev.A + drag_dir.Right().ToVector() );
809  }
810  else
811  guideA[0] = guideA[1] = SEG( dragged.A, dragged.A + dir_prev.ToVector() );
812  }
813 
814  if( aIndex == m_line.SegmentCount() - 1 )
815  {
816  guideB[0] = SEG( dragged.B, dragged.B + drag_dir.Right().ToVector() );
817  guideB[1] = SEG( dragged.B, dragged.B + drag_dir.Left().ToVector() );
818  }
819  else
820  {
821  if( dir_next.Angle( drag_dir )
823  {
824  guideB[0] = SEG( s_next.B, s_next.B + drag_dir.Left().ToVector() );
825  guideB[1] = SEG( s_next.B, s_next.B + drag_dir.Right().ToVector() );
826  }
827  else
828  guideB[0] = guideB[1] = SEG( dragged.B, dragged.B + dir_next.ToVector() );
829  }
830 
831  SEG s_current( target, target + drag_dir.ToVector() );
832 
833  int best_len = INT_MAX;
834  SHAPE_LINE_CHAIN best;
835 
836  for( int i = 0; i < 2; i++ )
837  {
838  for( int j = 0; j < 2; j++ )
839  {
840  OPT_VECTOR2I ip1 = s_current.IntersectLines( guideA[i] );
841  OPT_VECTOR2I ip2 = s_current.IntersectLines( guideB[j] );
842 
843  SHAPE_LINE_CHAIN np;
844 
845  if( !ip1 || !ip2 )
846  continue;
847 
848  SEG s1( s_prev.A, *ip1 );
849  SEG s2( *ip1, *ip2 );
850  SEG s3( *ip2, s_next.B );
851 
852  OPT_VECTOR2I ip;
853 
854  if( ( ip = s1.Intersect( s_next ) ) )
855  {
856  np.Append( s1.A );
857  np.Append( *ip );
858  np.Append( s_next.B );
859  }
860  else if( ( ip = s3.Intersect( s_prev ) ) )
861  {
862  np.Append( s_prev.A );
863  np.Append( *ip );
864  np.Append( s3.B );
865  }
866  else if( ( ip = s1.Intersect( s3 ) ) )
867  {
868  np.Append( s_prev.A );
869  np.Append( *ip );
870  np.Append( s_next.B );
871  }
872  else
873  {
874  np.Append( s_prev.A );
875  np.Append( *ip1 );
876  np.Append( *ip2 );
877  np.Append( s_next.B );
878  }
879 
880  if( np.Length() < best_len )
881  {
882  best_len = np.Length();
883  best = np;
884  }
885  }
886  }
887 
888  if( m_line.PointCount() == 1 )
889  m_line = best;
890  else if( aIndex == 0 )
891  m_line.Replace( 0, 1, best );
892  else if( aIndex == m_line.SegmentCount() - 1 )
893  m_line.Replace( -2, -1, best );
894  else
895  m_line.Replace( aIndex, aIndex + 1, best );
896 
897  m_line.Simplify();
898 }
long long int Length() const
Function Length()
SHAPE_LINE_CHAIN & Simplify(bool aRemoveColinear=true)
Function Simplify()
VECTOR2I snapToNeighbourSegments(const SHAPE_LINE_CHAIN &aPath, const VECTOR2I &aP, int aIndex) const
Definition: pns_line.cpp:684
int PointCount() const
Function PointCount()
void Append(int aX, int aY, bool aAllowDuplication=false)
Function Append()
SHAPE_LINE_CHAIN m_line
The actual shape of the line.
Definition: pns_line.h:243
OPT< VECTOR2I > OPT_VECTOR2I
Definition: seg.h:39
Represent route directions & corner angles in a 45-degree metric.
Definition: direction45.h:36
int SegmentCount() const
Function SegmentCount()
Definition: seg.h:41
SHAPE_LINE_CHAIN.
VECTOR2I A
Definition: seg.h:49
void Replace(int aStartIndex, int aEndIndex, const VECTOR2I &aP)
Function Replace()
VECTOR2I B
Definition: seg.h:50

References SEG::A, DIRECTION_45::ANG_HALF_FULL, DIRECTION_45::ANG_OBTUSE, DIRECTION_45::Angle(), SHAPE_LINE_CHAIN::Append(), SEG::B, 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 1134 of file pns_line.cpp.

1135 {
1136  for( const auto seg : m_links )
1137  {
1138  if( seg->Marker() & MK_LOCKED )
1139  return true;
1140  }
1141  return false;
1142 }

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

1025 {
1026  for( int i = 0; i < PointCount(); i++ )
1027  {
1028  for( int j = i + 2; j < PointCount(); j++ )
1029  {
1030  if( CPoint( i ) == CPoint( j ) )
1031  return true;
1032  }
1033  }
1034 
1035  return false;
1036 }
int PointCount() const
Definition: pns_line.h:140
const VECTOR2I & CPoint(int aIdx) const
Definition: pns_line.h:145

References CPoint(), and PointCount().

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

◆ Hole()

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

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

Definition at line 201 of file pns_item.h.

202  {
203  return nullptr;
204  }

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

◆ HoleHull()

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

Reimplemented in PNS::SOLID.

Definition at line 117 of file pns_item.h.

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

◆ Hull()

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

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

Definition at line 111 of file pns_item.h.

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

◆ Is45Degree()

bool PNS::LINE::Is45Degree ( ) const

Print out all linked segments.

Definition at line 425 of file pns_line.cpp.

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

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

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

◆ IsLinked()

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

◆ IsLinkedChecked()

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

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

Definition at line 120 of file pns_line.h.

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

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

◆ IsLocked()

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

Definition at line 223 of file pns_item.h.

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

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

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

◆ IsRoutable()

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

Definition at line 229 of file pns_item.h.

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

References PNS::ITEM::m_routable.

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

◆ Kind()

◆ KindStr()

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

Returns the kind of the item, as string.

Definition at line 126 of file pns_item.cpp.

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

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

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

◆ Layer()

◆ Layers()

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

Definition at line 150 of file pns_item.h.

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

References PNS::ITEM::m_layers.

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

◆ LayersOverlap()

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

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

Definition at line 159 of file pns_item.h.

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

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

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

◆ Line()

◆ Link()

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

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

Definition at line 42 of file pns_link_holder.h.

References PNS::LINK_HOLDER::m_links.

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

◆ LinkCount()

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

Definition at line 75 of file pns_link_holder.h.

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

References PNS::LINK_HOLDER::m_links.

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

◆ Links() [1/2]

◆ Links() [2/2]

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

Definition at line 50 of file pns_link_holder.h.

50 { return m_links; }

References PNS::LINK_HOLDER::m_links.

◆ Mark()

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

Reimplemented from PNS::ITEM.

Definition at line 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:243

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

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

◆ Marker()

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

Reimplemented from PNS::ITEM.

Definition at line 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:243

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

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

◆ Net()

◆ 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:238
LAYER_RANGE m_layers
Definition: pns_item.h:239
int m_rank
Definition: pns_item.h:244
bool m_movable
Definition: pns_item.h:241
int m_marker
Definition: pns_item.h:243
ITEM * m_blockingObstacle
For mark obstacle mode.
Definition: pns_line.h:252
SHAPE_LINE_CHAIN m_line
The actual shape of the line.
Definition: pns_line.h:243
bool m_hasVia
Optional via at the end point.
Definition: pns_line.h:249
int m_net
Definition: pns_item.h:242
int m_snapThreshhold
Width to smooth out jagged segments.
Definition: pns_line.h:247
int m_width
Our width.
Definition: pns_line.h:244

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

◆ Owner()

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

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

Definition at line 167 of file pns_item.h.

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

References PNS::ITEM::m_owner.

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

◆ Parent()

◆ PointCount()

◆ Rank()

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

Reimplemented from PNS::ITEM.

Definition at line 938 of file pns_line.cpp.

939 {
940  int min_rank = INT_MAX;
941 
942  if( IsLinked() ) {
943  for( auto s : m_links )
944  {
945  min_rank = std::min( min_rank, s->Rank() );
946  }
947  } else {
948  min_rank = m_rank;
949  }
950 
951  int rank = ( min_rank == INT_MAX ) ? -1 : min_rank;
952 
953  return rank;
954 }
int m_rank
Definition: pns_item.h:244

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

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

◆ RemoveVia()

void PNS::LINE::RemoveVia ( )
inline

◆ Reverse()

void PNS::LINE::Reverse ( )

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

Returns the clipped line.

Definition at line 907 of file pns_line.cpp.

908 {
909  m_line = m_line.Reverse();
910 
911  std::reverse( m_links.begin(), m_links.end() );
912 }
const SHAPE_LINE_CHAIN Reverse() const
Function Reverse()
SHAPE_LINE_CHAIN m_line
The actual shape of the line.
Definition: pns_line.h:243

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

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

◆ SegmentCount()

◆ SetBlockingObstacle()

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

Definition at line 205 of file pns_line.h.

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

References m_blockingObstacle.

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

◆ SetLayer()

◆ SetLayers()

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

Definition at line 151 of file pns_item.h.

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

References PNS::ITEM::m_layers.

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

◆ SetNet()

◆ SetOwner()

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

Set the node that owns this item.

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

Definition at line 172 of file pns_item.h.

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

References PNS::ITEM::m_owner.

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

◆ SetParent()

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

Definition at line 144 of file pns_item.h.

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

References PNS::ITEM::m_parent.

Referenced by PNS_KICAD_IFACE::AddItem().

◆ SetRank()

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

Reimplemented from PNS::ITEM.

Definition at line 928 of file pns_line.cpp.

929 {
930  m_rank = aRank;
931 
932  for( auto s : m_links )
933  s->SetRank( aRank );
934 
935 }
int m_rank
Definition: pns_item.h:244

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

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

◆ SetRoutable()

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

Definition at line 228 of file pns_item.h.

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

References PNS::ITEM::m_routable.

◆ SetShape()

◆ SetSnapThreshhold()

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

Definition at line 221 of file pns_line.h.

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

References m_snapThreshhold.

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

◆ SetViaDiameter()

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

Definition at line 198 of file pns_line.h.

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

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

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

644 {
645  int s_start = std::max( aIndex - 2, 0 );
646  int s_end = std::min( aIndex + 2, aPath.SegmentCount() - 1 );
647 
648  int i, j;
649  int best_dist = INT_MAX;
650  VECTOR2I best_snap = aP;
651 
652  if( m_snapThreshhold <= 0 )
653  return aP;
654 
655  for( i = s_start; i <= s_end; i++ )
656  {
657  const SEG& a = aPath.CSegment( i );
658 
659  for( j = s_start; j < i; j++ )
660  {
661  const SEG& b = aPath.CSegment( j );
662 
663  if( !( DIRECTION_45( a ).IsObtuse( DIRECTION_45( b ) ) ) )
664  continue;
665 
666  OPT_VECTOR2I ip = a.IntersectLines( b );
667 
668  if( ip )
669  {
670  int dist = ( *ip - aP ).EuclideanNorm();
671 
672  if( dist < m_snapThreshhold && dist < best_dist )
673  {
674  best_dist = dist;
675  best_snap = *ip;
676  }
677  }
678  }
679  }
680 
681  return best_snap;
682 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:148
OPT_VECTOR2I IntersectLines(const SEG &aSeg) const
Compute the intersection point of lines passing through ends of (this) and aSeg.
Definition: seg.h:208
OPT< VECTOR2I > OPT_VECTOR2I
Definition: seg.h:39
Represent route directions & corner angles in a 45-degree metric.
Definition: direction45.h:36
int SegmentCount() const
Function SegmentCount()
Definition: seg.h:41
const SEG CSegment(int aIndex) const
Function CSegment()
int m_snapThreshhold
Width to smooth out jagged segments.
Definition: pns_line.h:247

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

Referenced by dragCorner45().

◆ snapToNeighbourSegments()

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

Definition at line 684 of file pns_line.cpp.

686 {
687  VECTOR2I snap_p[2];
688  DIRECTION_45 dragDir( aPath.CSegment( aIndex ) );
689  int snap_d[2] = { -1, -1 };
690 
691  if( m_snapThreshhold == 0 )
692  return aP;
693 
694  if( aIndex >= 2 )
695  {
696  SEG s = aPath.CSegment( aIndex - 2 );
697 
698  if( DIRECTION_45( s ) == dragDir )
699  snap_d[0] = s.LineDistance( aP );
700 
701  snap_p[0] = s.A;
702  }
703 
704  if( aIndex < aPath.SegmentCount() - 2 )
705  {
706  SEG s = aPath.CSegment( aIndex + 2 );
707 
708  if( DIRECTION_45( s ) == dragDir )
709  snap_d[1] = s.LineDistance( aP );
710 
711  snap_p[1] = s.A;
712  }
713 
714  VECTOR2I best = aP;
715  int minDist = INT_MAX;
716 
717  for( int i = 0; i < 2; i++ )
718  {
719  if( snap_d[i] >= 0 && snap_d[i] < minDist && snap_d[i] <= m_snapThreshhold )
720  {
721  minDist = snap_d[i];
722  best = snap_p[i];
723  }
724  }
725 
726  return best;
727 }
int LineDistance(const VECTOR2I &aP, bool aDetermineSide=false) const
Return the closest Euclidean distance between point aP and the line defined by the ends of segment (t...
Definition: seg.h:420
Represent route directions & corner angles in a 45-degree metric.
Definition: direction45.h:36
int SegmentCount() const
Function SegmentCount()
Definition: seg.h:41
const SEG CSegment(int aIndex) const
Function CSegment()
int m_snapThreshhold
Width to smooth out jagged segments.
Definition: pns_line.h:247
VECTOR2I A
Definition: seg.h:49

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

Referenced by dragSegment45().

◆ Unmark()

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

Reimplemented from PNS::ITEM.

Definition at line 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:243

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

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

◆ Via()

◆ Walkaround() [1/2]

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

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

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

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

◆ Walkaround() [2/2]

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

Definition at line 156 of file pns_line.cpp.

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

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

◆ Width()

Member Data Documentation

◆ m_blockingObstacle

ITEM* PNS::LINE::m_blockingObstacle
private

For mark obstacle mode.

Definition at line 252 of file pns_line.h.

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

◆ m_hasVia

bool PNS::LINE::m_hasVia
private

Optional via at the end point.

Definition at line 249 of file pns_line.h.

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

◆ m_kind

PnsKind PNS::ITEM::m_kind
protectedinherited

◆ m_layers

◆ m_line

◆ m_links

◆ m_marker

◆ m_movable

bool PNS::ITEM::m_movable
protectedinherited

Definition at line 241 of file pns_item.h.

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

◆ m_net

◆ m_owner

NODE* PNS::ITEM::m_owner
protectedinherited

◆ m_parent

BOARD_ITEM* PNS::ITEM::m_parent
protectedinherited

◆ m_rank

◆ m_routable

bool PNS::ITEM::m_routable
protectedinherited

Definition at line 245 of file pns_item.h.

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

◆ m_snapThreshhold

int PNS::LINE::m_snapThreshhold
private

Width to smooth out jagged segments.

Definition at line 247 of file pns_line.h.

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

◆ m_via

VIA PNS::LINE::m_via
private

Definition at line 250 of file pns_line.h.

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

◆ m_width

int PNS::LINE::m_width
private

Our width.

Definition at line 244 of file pns_line.h.

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

◆ UnusedNet

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

Supported item types.

Definition at line 58 of file pns_item.h.

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


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