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
 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=0, int aLayer=-1) 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, int aOverrideClearance=-1) 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
 
void SetIsFreePad (bool aIsFreePad=true)
 
bool IsFreePad () const
 
bool IsVirtual () const
 
void SetIsCompoundShapePrimitive ()
 
bool IsCompoundShapePrimitive () const
 
virtual const std::string Format () 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_isFreePad
 
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
 
bool collideSimple (const ITEM *aOther, const NODE *aNode, bool aDifferentNetsOnly, int aOverrideClearance) 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 };
@ SOLID_T
Definition: pns_item.h:63
@ LINE_T
Definition: pns_item.h:64
@ SEGMENT_T
Definition: pns_item.h:66
@ DIFF_PAIR_T
Definition: pns_item.h:69
@ JOINT_T
Definition: pns_item.h:65

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
73 }
int m_width
Our width.
Definition: pns_line.h:247
ITEM * m_blockingObstacle
For mark obstacle mode.
Definition: pns_line.h:255
bool m_hasVia
Optional via at the end point.
Definition: pns_line.h:252
int m_snapThreshhold
Width to smooth out jagged segments.
Definition: pns_line.h:250

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}
int m_net
Definition: pns_item.h:261
bool m_movable
Definition: pns_item.h:260
LAYER_RANGE m_layers
Definition: pns_item.h:258
int m_marker
Definition: pns_item.h:262
int m_rank
Definition: pns_item.h:263
SHAPE_LINE_CHAIN m_line
The actual shape of the line.
Definition: pns_line.h:246
VIA m_via
Definition: pns_line.h:253

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 }

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();
106 }

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::ARC, PNS::SEGMENT, PNS::SOLID, and PNS::VIA.

Definition at line 224 of file pns_item.h.

225 {
226 return 0;
227 }

◆ AppendVia()

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

Definition at line 1031 of file pns_line.cpp.

1032{
1033 if( m_line.PointCount() > 1 && aVia.Pos() == m_line.CPoint( 0 ) )
1034 {
1035 Reverse();
1036 }
1037
1038 m_hasVia = true;
1039 m_via = aVia;
1040 m_via.SetNet( m_net );
1041}
void SetNet(int aNet)
Definition: pns_item.h:153
void Reverse()
Clip the line to the nearest obstacle, traversing from the line's start vertex (0).
Definition: pns_line.cpp:1023
int PointCount() const
Return the number of points (vertices) in this line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.

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::rhWalkBase(), PNS::LINE_PLACER::rhWalkOnly(), and PNS::DIFF_PAIR::updateLine().

◆ ArcCount()

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

Definition at line 146 of file pns_line.h.

146{ return m_line.ArcCount(); }
size_t ArcCount() const

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

184 {
185 return m_owner == aNode;
186 }
NODE * m_owner
Definition: pns_item.h:257

References PNS::ITEM::m_owner.

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

◆ ChangedArea()

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

Definition at line 1152 of file pns_line.cpp.

1153{
1154 BOX2I area;
1155 bool areaDefined = false;
1156
1157 int i_start = -1;
1158 int i_end_self = -1, i_end_other = -1;
1159
1160 SHAPE_LINE_CHAIN self( m_line );
1161 self.Simplify();
1162 SHAPE_LINE_CHAIN other( aOther->m_line );
1163 other.Simplify();
1164
1165 int np_self = self.PointCount();
1166 int np_other = other.PointCount();
1167
1168 int n = std::min( np_self, np_other );
1169
1170 for( int i = 0; i < n; i++ )
1171 {
1172 const VECTOR2I p1 = self.CPoint( i );
1173 const VECTOR2I p2 = other.CPoint( i );
1174
1175 if( p1 != p2 )
1176 {
1177 if( i != n - 1 )
1178 {
1179 SEG s = self.CSegment( i );
1180
1181 if( !s.Contains( p2 ) )
1182 {
1183 i_start = i;
1184 break;
1185 }
1186 }
1187 else
1188 {
1189 i_start = i;
1190 break;
1191 }
1192 }
1193 }
1194
1195 for( int i = 0; i < n; i++ )
1196 {
1197 const VECTOR2I p1 = self.CPoint( np_self - 1 - i );
1198 const VECTOR2I p2 = other.CPoint( np_other - 1 - i );
1199
1200 if( p1 != p2 )
1201 {
1202 i_end_self = np_self - 1 - i;
1203 i_end_other = np_other - 1 - i;
1204 break;
1205 }
1206 }
1207
1208 if( i_start < 0 )
1209 i_start = n;
1210
1211 if( i_end_self < 0 )
1212 i_end_self = np_self - 1;
1213
1214 if( i_end_other < 0 )
1215 i_end_other = np_other - 1;
1216
1217 for( int i = i_start; i <= i_end_self; i++ )
1218 extendBox( area, areaDefined, self.CPoint( i ) );
1219
1220 for( int i = i_start; i <= i_end_other; i++ )
1221 extendBox( area, areaDefined, other.CPoint( i ) );
1222
1223 if( areaDefined )
1224 {
1225 area.Inflate( std::max( Width(), aOther->Width() ) );
1226 return area;
1227 }
1228
1229 return OPT_BOX2I();
1230}
std::optional< BOX2I > OPT_BOX2I
Definition: box2.h:850
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:506
int Width() const
Return true if the line is geometrically identical as line aOther.
Definition: pns_line.h:161
Definition: seg.h:42
bool Contains(const SEG &aSeg) const
Definition: seg.h:307
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:1138

References SEG::Contains(), SHAPE_LINE_CHAIN::CPoint(), SHAPE_LINE_CHAIN::CSegment(), 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 1244 of file pns_line.cpp.

1245{
1246 m_hasVia = false;
1247 m_line.Clear();
1248}
void Clear()
Remove all points from the line chain.

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

Referenced by PNS::LINE_PLACER::rhWalkBase(), PNS::LINE_PLACER::routeStep(), and PNS::LINE_PLACER::splitHeadTail().

◆ ClearLinks()

◆ CLine()

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

Definition at line 142 of file pns_line.h.

142{ return m_line; }

References m_line.

Referenced by PNS::COST_ESTIMATOR::Add(), PNS::TOPOLOGY::AssembleTuningPath(), PNS::DIFF_PAIR_PLACER::attemptWalk(), PNS::KEEP_TOPOLOGY_CONSTRAINT::Check(), PNS::NODE::CheckColliding(), PNS::SHOVE::checkShoveDirection(), PNS::COST_ESTIMATOR::CornerCost(), PNS::DIFF_PAIR::DIFF_PAIR(), PNS::MEANDER_PLACER::doMove(), PNS::DRAGGER::dragShove(), PNS::DRAGGER::dragViaMarkObstacles(), PNS::DRAGGER::dragViaWalkaround(), PNS::DRAGGER::dragWalkaround(), PNS::OPTIMIZER::fanoutCleanup(), PNS::NODE::FindLinesBetweenJoints(), PNS::LINE_PLACER::FixRoute(), PNS::TOPOLOGY::followTrivialPath(), PNS::LINE_PLACER::Move(), PNS::NODE::NearestObstacle(), PNS::SHOVE::onCollidingArc(), PNS::SHOVE::onCollidingSegment(), PNS::SHOVE::onReverseCollidingVia(), PNS::DRAGGER::optimizeAndUpdateDraggedLine(), PNS::LINE_PLACER::optimizeTailHeadTransition(), PNS::COST_ESTIMATOR::Remove(), PNS::LINE_PLACER::removeLoops(), PNS::COST_ESTIMATOR::Replace(), PNS_LOG_PLAYER::ReplayLog(), PNS::LINE_PLACER::rhWalkBase(), PNS::WALKAROUND::Route(), PNS::SHOVE::shoveLineToHullSet(), PNS::SHOVE::ShoveObstacleLine(), PNS::TOPOLOGY::SimplifyLine(), PNS::LINE_PLACER::simplifyNewLine(), PNS::WALKAROUND::singleStep(), PNS::OPTIMIZER::smartPadsSingle(), PNS::LINE_PLACER::splitHeadTail(), PNS::COMPONENT_DRAGGER::Start(), PNS::DRAGGER::startDragSegment(), PNS::Tighten(), PNS::LINE_PLACER::Trace(), PNS::DRAGGER::tryWalkaround(), PNS::LINE_PLACER::updatePStart(), and Walkaround().

◆ ClipToNearestObstacle()

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

Clip the line to a given range of vertices.

Definition at line 551 of file pns_line.cpp.

552{
553 const int IterationLimit = 5;
554 int i;
555 LINE l( *this );
556
557 for( i = 0; i < IterationLimit; i++ )
558 {
559 NODE::OPT_OBSTACLE obs = aNode->NearestObstacle( &l );
560
561 if( obs )
562 {
563 l.RemoveVia();
564 VECTOR2I collisionPoint = obs->m_ipFirst;
565 int segIdx = l.Line().NearestSegment( collisionPoint );
566
567 if( l.Line().IsArcSegment( segIdx ) )
568 {
569 // Don't clip at arcs, start again
570 l.Line().Clear();
571 }
572 else
573 {
574 SEG nearestSegment = l.Line().CSegment( segIdx );
575 VECTOR2I nearestPt = nearestSegment.NearestPoint( collisionPoint );
576 int p = l.Line().Split( nearestPt );
577 l.Line().Remove( p + 1, -1 );
578 }
579 }
580 else
581 {
582 break;
583 }
584 }
585
586 if( i == IterationLimit )
587 l.Line().Clear();
588
589 return l;
590}
LINE()
Makes an empty line.
Definition: pns_line.h:66
std::optional< OBSTACLE > OPT_OBSTACLE
Definition: pns_node.h:166
const VECTOR2I NearestPoint(const VECTOR2I &aP) const
Compute a point on the segment (this) that is closest to point aP.
Definition: seg.cpp:269

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

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

1075{
1082 int firstLink = 0;
1083 int lastLink = std::max( 0, static_cast<int>( m_links.size() ) - 1 );
1084 int linkIdx = 0;
1085
1086 int numPoints = static_cast<int>( m_line.PointCount() );
1087
1088 for( int i = 0; i >= 0 && i < m_line.PointCount(); i = m_line.NextShape( i ) )
1089 {
1090 if( i <= aStart )
1091 firstLink = linkIdx;
1092
1093 if( i < 0 || i >= aEnd - 1 || linkIdx >= lastLink )
1094 {
1095 lastLink = linkIdx;
1096 break;
1097 }
1098
1099 linkIdx++;
1100 }
1101
1102 wxASSERT( lastLink >= firstLink );
1103
1104 m_line = m_line.Slice( aStart, aEnd );
1105
1106 if( IsLinked() )
1107 {
1108 wxASSERT( m_links.size() < INT_MAX );
1109 wxASSERT( static_cast<int>( m_links.size() ) >= ( lastLink - firstLink ) );
1110
1111 // Note: The range includes aEnd, but we have n-1 segments.
1112 std::rotate(
1113 m_links.begin(),
1114 m_links.begin() + firstLink,
1115 m_links.begin() + lastLink
1116 );
1117
1118 m_links.resize( lastLink - firstLink + 1 );
1119 }
1120}
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.
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.

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}

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,
int  aOverrideClearance = -1 
) 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 169 of file pns_item.cpp.

170{
171 if( collideSimple( aOther, aNode, aDifferentNetsOnly, aOverrideClearance ) )
172 return true;
173
174 // Special cases for "head" lines with vias attached at the end. Note that this does not
175 // support head-line-via to head-line-via collisions, but you can't route two independent
176 // tracks at once so it shouldn't come up.
177
178 if( m_kind == LINE_T )
179 {
180 const LINE* line = static_cast<const LINE*>( this );
181
182 if( line->EndsWithVia() && line->Via().collideSimple( aOther, aNode, aDifferentNetsOnly, aOverrideClearance ) )
183 return true;
184 }
185
186 if( aOther->m_kind == LINE_T )
187 {
188 const LINE* line = static_cast<const LINE*>( aOther );
189
190 if( line->EndsWithVia() && line->Via().collideSimple( this, aNode, aDifferentNetsOnly, aOverrideClearance ) )
191 return true;
192 }
193
194 return false;
195}
PnsKind m_kind
Definition: pns_item.h:254
bool collideSimple(const ITEM *aOther, const NODE *aNode, bool aDifferentNetsOnly, int aOverrideClearance) 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::fixupViaCollisions(), PNS::SHOVE::onCollidingSolid(), PNS::NODE::DEFAULT_OBSTACLE_VISITOR::operator()(), PNS::OPTIMIZER::CACHE_VISITOR::operator()(), PNS::SHOVE::shoveLineFromLoneVia(), PNS::SHOVE::shoveLineToHullSet(), PNS::COMPONENT_DRAGGER::Start(), and PNS::verifyDpBypass().

◆ collideSimple()

bool PNS::ITEM::collideSimple ( const ITEM aOther,
const NODE aNode,
bool  aDifferentNetsOnly,
int  aOverrideClearance 
) const
privateinherited

Definition at line 32 of file pns_item.cpp.

33{
34 const ROUTER_IFACE* iface = ROUTER::GetInstance()->GetInterface();
35 const SHAPE* shapeA = Shape();
36 const SHAPE* holeA = Hole();
37 int lineWidthA = 0;
38 const SHAPE* shapeB = aOther->Shape();
39 const SHAPE* holeB = aOther->Hole();
40 int lineWidthB = 0;
41
42 // Sadly collision routines ignore SHAPE_POLY_LINE widths so we have to pass them in as part
43 // of the clearance value.
44 if( m_kind == LINE_T )
45 lineWidthA = static_cast<const LINE*>( this )->Width() / 2;
46
47 if( aOther->m_kind == LINE_T )
48 lineWidthB = static_cast<const LINE*>( aOther )->Width() / 2;
49
50 // same nets? no collision!
51 if( aDifferentNetsOnly && m_net == aOther->m_net && m_net >= 0 && aOther->m_net >= 0 )
52 return false;
53
54 // a pad associated with a "free" pin (NIC) doesn't have a net until it has been used
55 if( aDifferentNetsOnly && ( IsFreePad() || aOther->IsFreePad() ) )
56 return false;
57
58 // check if we are not on completely different layers first
59 if( !m_layers.Overlaps( aOther->m_layers ) )
60 return false;
61
62 auto checkKeepout =
63 []( const ZONE* aKeepout, const BOARD_ITEM* aOther )
64 {
65 if( aKeepout->GetDoNotAllowTracks() && aOther->IsType( { PCB_ARC_T, PCB_TRACE_T } ) )
66 return true;
67
68 if( aKeepout->GetDoNotAllowVias() && aOther->Type() == PCB_VIA_T )
69 return true;
70
71 if( aKeepout->GetDoNotAllowPads() && aOther->Type() == PCB_PAD_T )
72 return true;
73
74 // Incomplete test, but better than nothing:
75 if( aKeepout->GetDoNotAllowFootprints() && aOther->Type() == PCB_PAD_T )
76 {
77 return !aKeepout->GetParentFootprint()
78 || aKeepout->GetParentFootprint() != aOther->GetParentFootprint();
79 }
80
81 return false;
82 };
83
84 const ZONE* zoneA = dynamic_cast<ZONE*>( Parent() );
85 const ZONE* zoneB = dynamic_cast<ZONE*>( aOther->Parent() );
86
87 if( zoneA && aOther->Parent() && !checkKeepout( zoneA, aOther->Parent() ) )
88 return false;
89
90 if( zoneB && Parent() && !checkKeepout( zoneB, Parent() ) )
91 return false;
92
93 bool thisNotFlashed = !iface->IsFlashedOnLayer( this, aOther->Layer() );
94 bool otherNotFlashed = !iface->IsFlashedOnLayer( aOther, Layer() );
95
96 if( ( aNode->GetCollisionQueryScope() == NODE::CQS_ALL_RULES
97 || ( thisNotFlashed || otherNotFlashed ) )
98 && ( holeA || holeB ) )
99 {
100 int holeClearance = aNode->GetHoleClearance( this, aOther );
101
102 if( holeClearance >= 0 && holeA && holeA->Collide( shapeB, holeClearance + lineWidthB ) )
103 {
104 Mark( Marker() | MK_HOLE );
105 return true;
106 }
107
108 if( holeB && holeClearance >= 0 && holeB->Collide( shapeA, holeClearance + lineWidthA ) )
109 {
110 aOther->Mark( aOther->Marker() | MK_HOLE );
111 return true;
112 }
113
114 if( holeA && holeB )
115 {
116 int holeToHoleClearance = aNode->GetHoleToHoleClearance( this, aOther );
117
118 if( holeToHoleClearance >= 0 && holeA->Collide( holeB, holeToHoleClearance ) )
119 {
120 Mark( Marker() | MK_HOLE );
121 aOther->Mark( aOther->Marker() | MK_HOLE );
122 return true;
123 }
124 }
125 }
126
127 if( !aOther->Layers().IsMultilayer() && thisNotFlashed )
128 return false;
129
130 if( !Layers().IsMultilayer() && otherNotFlashed )
131 return false;
132
133 int clearance = aOverrideClearance >= 0 ? aOverrideClearance : aNode->GetClearance( this, aOther );
134
135 if( clearance >= 0 )
136 {
137 bool checkCastellation = ( m_parent && m_parent->GetLayer() == Edge_Cuts );
138 bool checkNetTie = aNode->GetRuleResolver()->IsInNetTie( this );
139
140 if( checkCastellation || checkNetTie )
141 {
142 // Slow method
143 int actual;
144 VECTOR2I pos;
145
146 if( shapeA->Collide( shapeB, clearance + lineWidthA, &actual, &pos ) )
147 {
148 if( checkCastellation && aNode->QueryEdgeExclusions( pos ) )
149 return false;
150
151 if( checkNetTie && aNode->GetRuleResolver()->IsNetTieExclusion( aOther, pos, this ) )
152 return false;
153
154 return true;
155 }
156 }
157 else
158 {
159 // Fast method
160 if( shapeA->Collide( shapeB, clearance + lineWidthA + lineWidthB ) )
161 return true;
162 }
163 }
164
165 return false;
166}
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:70
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:192
BOARD_ITEM_CONTAINER * GetParentFootprint() const
Definition: board_item.cpp:239
bool Overlaps(const LAYER_RANGE &aOther) const
Definition: pns_layerset.h:67
BOARD_ITEM * Parent() const
Definition: pns_item.h:151
bool IsFreePad() const
Definition: pns_item.h:238
virtual const SHAPE * Hole() const
Definition: pns_item.h:207
virtual int Layer() const
Definition: pns_item.h:160
virtual const SHAPE * Shape() const
Return the geometrical shape of the item.
Definition: pns_item.h:202
const LAYER_RANGE & Layers() const
Definition: pns_item.h:156
virtual void Mark(int aMarker) const
Definition: pns_item.h:212
virtual int Marker() const
Definition: pns_item.h:214
BOARD_ITEM * m_parent
Definition: pns_item.h:256
@ CQS_ALL_RULES
check all rules
Definition: pns_node.h:162
ROUTER_IFACE * GetInterface() const
Definition: pns_router.h:215
static ROUTER * GetInstance()
Definition: pns_router.cpp:78
An abstract shape on 2D plane.
Definition: shape.h:124
virtual bool Collide(const VECTOR2I &aP, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const
Check if the boundary of shape (this) lies closer to the point aP than aClearance,...
Definition: shape.h:179
Handle a list of polygons defining a copper zone.
Definition: zone.h:57
bool GetDoNotAllowVias() const
Definition: zone.h:705
bool GetDoNotAllowPads() const
Definition: zone.h:707
bool GetDoNotAllowTracks() const
Definition: zone.h:706
bool GetDoNotAllowFootprints() const
Definition: zone.h:708
@ Edge_Cuts
Definition: layer_ids.h:113
@ MK_HOLE
Definition: pns_item.h:45
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:102
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition: typeinfo.h:87
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
Definition: typeinfo.h:103
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:101

References SHAPE::Collide(), PNS::NODE::CQS_ALL_RULES, Edge_Cuts, PNS::NODE::GetClearance(), PNS::NODE::GetCollisionQueryScope(), ZONE::GetDoNotAllowFootprints(), ZONE::GetDoNotAllowPads(), ZONE::GetDoNotAllowTracks(), ZONE::GetDoNotAllowVias(), PNS::NODE::GetHoleClearance(), PNS::NODE::GetHoleToHoleClearance(), PNS::ROUTER::GetInstance(), PNS::ROUTER::GetInterface(), BOARD_ITEM::GetLayer(), BOARD_ITEM::GetParentFootprint(), PNS::NODE::GetRuleResolver(), PNS::ITEM::Hole(), PNS::ROUTER_IFACE::IsFlashedOnLayer(), PNS::ITEM::IsFreePad(), PNS::RULE_RESOLVER::IsInNetTie(), LAYER_RANGE::IsMultilayer(), PNS::RULE_RESOLVER::IsNetTieExclusion(), PNS::ITEM::Layer(), PNS::ITEM::Layers(), PNS::ITEM::LINE_T, PNS::ITEM::m_kind, PNS::ITEM::m_layers, PNS::ITEM::m_net, PNS::ITEM::m_parent, PNS::ITEM::Mark(), PNS::ITEM::Marker(), PNS::MK_HOLE, LAYER_RANGE::Overlaps(), PNS::ITEM::Parent(), PCB_ARC_T, PCB_PAD_T, PCB_TRACE_T, PCB_VIA_T, PNS::NODE::QueryEdgeExclusions(), and PNS::ITEM::Shape().

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

◆ CompareGeometry()

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

Reverse the point/vertex order.

Definition at line 1017 of file pns_line.cpp.

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

Referenced by PNS::TOOL_BASE::checkSnap().

◆ 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}
Represent route directions & corner angles in a 45-degree metric.
Definition: direction45.h:37
AngleType
Represent kind of angle formed by vectors heading in two DIRECTION_45s.
Definition: direction45.h:78
int SegmentCount() const
Return the number of segments in this line chain.
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 734 of file pns_line.cpp.

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

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

678{
680
681 int width = m_line.Width();
682 VECTOR2I snapped = snapDraggedCorner( m_line, aP, aIndex );
683
684 if( aIndex == 0 )
685 path = dragCornerInternal( m_line.Reverse(), snapped ).Reverse();
686 else if( aIndex == m_line.SegmentCount() )
687 path = dragCornerInternal( m_line, snapped );
688 else
689 {
690 // Are we next to an arc? Insert a new point so we slice correctly
691 if( m_line.IsPtOnArc( static_cast<size_t>( aIndex ) + 1 ) )
692 m_line.Insert( aIndex + 1, m_line.CPoint( aIndex + 1 ) );
693
694 // fixme: awkward behaviour for "outwards" drags
695 path = dragCornerInternal( m_line.Slice( 0, aIndex ), snapped );
696 SHAPE_LINE_CHAIN path_rev =
697 dragCornerInternal( m_line.Slice( aIndex, -1 ).Reverse(), snapped ).Reverse();
698 path.Append( path_rev );
699 }
700
701 path.Simplify();
702 path.SetWidth( width );
703 m_line = path;
704}
VECTOR2I snapDraggedCorner(const SHAPE_LINE_CHAIN &aPath, const VECTOR2I &aP, int aIndex) const
Definition: pns_line.cpp:760
const SHAPE_LINE_CHAIN Reverse() const
Reverse point order in the line chain.
bool IsPtOnArc(size_t aPtIndex) const
int Width() const
Get the current width of the segments in the chain.
void Insert(size_t aVertex, const VECTOR2I &aP)
SHAPE_LINE_CHAIN dragCornerInternal(const SHAPE_LINE_CHAIN &aOrigin, const VECTOR2I &aP)
Definition: pns_line.cpp:594

References SHAPE_LINE_CHAIN::CPoint(), PNS::dragCornerInternal(), SHAPE_LINE_CHAIN::Insert(), SHAPE_LINE_CHAIN::IsPtOnArc(), m_line, path, 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 707 of file pns_line.cpp.

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

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

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

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

References SEG::A, DIRECTION_45::ANG_HALF_FULL, DIRECTION_45::ANG_OBTUSE, DIRECTION_45::Angle(), SHAPE_LINE_CHAIN::Append(), SEG::B, SEG::Intersect(), SEG::IntersectLines(), 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()

◆ Format()

const std::string PNS::ITEM::Format ( ) const
virtualinherited

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

Definition at line 218 of file pns_item.cpp.

219{
220 std::stringstream ss;
221 ss << KindStr() << " ";
222 ss << "net " << m_net << " ";
223 ss << "layers " << m_layers.Start() << " " << m_layers.End();
224 return ss.str();
225}
int Start() const
Definition: pns_layerset.h:82
int End() const
Definition: pns_layerset.h:87
std::string KindStr() const
Returns the kind of the item, as string.
Definition: pns_item.cpp:198

References LAYER_RANGE::End(), PNS::ITEM::KindStr(), PNS::ITEM::m_layers, PNS::ITEM::m_net, and LAYER_RANGE::Start().

Referenced by PNS::NODE::Dump(), PNS::SEGMENT::Format(), and PNS::VIA::Format().

◆ GetBlockingObstacle()

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

Definition at line 209 of file pns_line.h.

209{ return m_blockingObstacle; }

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::DP_MEANDER_PLACER::Start(), and PNS::MEANDER_SKEW_PLACER::Start().

◆ GetSnapThreshhold()

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

Definition at line 229 of file pns_line.h.

230 {
231 return m_snapThreshhold;
232 }

References m_snapThreshhold.

◆ HasLockedSegments()

bool PNS::LINE::HasLockedSegments ( ) const

Definition at line 1233 of file pns_line.cpp.

1234{
1235 for( const auto seg : m_links )
1236 {
1237 if( seg->Marker() & MK_LOCKED )
1238 return true;
1239 }
1240 return false;
1241}
@ MK_LOCKED
Definition: pns_item.h:43

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

1124{
1125 for( int i = 0; i < PointCount(); i++ )
1126 {
1127 for( int j = i + 2; j < PointCount(); j++ )
1128 {
1129 if( CPoint( i ) == CPoint( j ) )
1130 return true;
1131 }
1132 }
1133
1134 return false;
1135}
const VECTOR2I & CPoint(int aIdx) const
Definition: pns_line.h:150
int PointCount() const
Definition: pns_line.h:145

References CPoint(), and PointCount().

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

◆ Hole()

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

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

Definition at line 207 of file pns_item.h.

208 {
209 return nullptr;
210 }

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

◆ HoleHull()

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

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

Definition at line 123 of file pns_item.h.

125 {
126 return SHAPE_LINE_CHAIN();
127 }

◆ Hull()

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

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

Definition at line 117 of file pns_item.h.

119 {
120 return SHAPE_LINE_CHAIN();
121 }

◆ IsCompoundShapePrimitive()

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

Definition at line 246 of file pns_item.h.

bool m_isCompoundShapePrimitive
Definition: pns_item.h:267

References PNS::ITEM::m_isCompoundShapePrimitive.

◆ IsFreePad()

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

Definition at line 238 of file pns_item.h.

238{ return m_isFreePad; }
bool m_isFreePad
Definition: pns_item.h:266

References PNS::ITEM::m_isFreePad.

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

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

230 {
231 return Marker() & MK_LOCKED;
232 }

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

235{ return m_routable; }
bool m_routable
Definition: pns_item.h:264

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

199{
200 switch( m_kind )
201 {
202 case ARC_T: return "arc";
203 case LINE_T: return "line";
204 case SEGMENT_T: return "segment";
205 case VIA_T: return "via";
206 case JOINT_T: return "joint";
207 case SOLID_T: return "solid";
208 case DIFF_PAIR_T: return "diff-pair";
209 default: return "unknown";
210 }
211}

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::ITEM::Format(), PNS::TOOL_BASE::pickSingleItem(), and PNS::TOOL_BASE::updateEndItem().

◆ Layer()

◆ Layers()

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

Definition at line 156 of file pns_item.h.

156{ return m_layers; }

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(), comparePnsItems(), PNS::DP_MEANDER_PLACER::CurrentLayer(), PNS::MEANDER_PLACER::CurrentLayer(), PNS::DIFF_PAIR_PLACER::FindDpPrimitivePair(), PNS::NODE::FindJoint(), PNS::NODE::FindLinesBetweenJoints(), PNS::NODE::findRedundantArc(), PNS::NODE::findRedundantSegment(), PNS::NODE::FixupVirtualVias(), PNS::ROUTER::getNearestRatnestAnchor(), ROUTER_TOOL::getStartLayer(), PNS_PCBNEW_RULE_RESOLVER::HoleClearance(), PNS_PCBNEW_RULE_RESOLVER::HoleToHoleClearance(), PNS_KICAD_IFACE_BASE::IsFlashedOnLayer(), PNS::ITEM::Layer(), PNS::ITEM::LayersOverlap(), LINE(), PNS::NODE::LockJoint(), PNS::VIA::MakeHandle(), PNS::ROUTER::markViolations(), PNS::TOPOLOGY::NearestUnconnectedAnchorPoint(), 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_LOG_PLAYER::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 165 of file pns_item.h.

166 {
167 return Layers().Overlaps( aOther->Layers() );
168 }

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

Referenced by PNS::MEANDER_PLACER_BASE::lineLength(), 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}

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}

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

154{ return m_net; }

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::AssembleCluster(), PNS::TOPOLOGY::AssembleDiffPair(), PNS::NODE::AssembleLine(), PNS::LINE_PLACER::buildInitialLine(), PNS::KEEP_TOPOLOGY_CONSTRAINT::Check(), PNS::VIA::Clone(), comparePnsItems(), PNS::DRAGGER::CurrentNets(), PNS::MEANDER_PLACER::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(), PNS_KICAD_IFACE_BASE::ImportSizes(), ROUTER_TOOL::InlineDrag(), PNS_PCBNEW_RULE_RESOLVER::IsDiffPair(), PNS_PCBNEW_RULE_RESOLVER::IsNetTieExclusion(), PNS::ROUTER::isStartingPointRoutable(), LINE(), PNS::NODE::LockJoint(), PNS::VIA::MakeHandle(), PNS::MEANDER_SKEW_PLACER::Move(), PNS::MEANDER_SKEW_PLACER::origPathLength(), 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::DIFF_PAIR_PLACER::Start(), PNS::LINE_PLACER::Start(), PNS::MEANDER_SKEW_PLACER::Start(), 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}

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

173{ return m_owner; }

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

1055{
1056 int min_rank = INT_MAX;
1057
1058 if( IsLinked() )
1059 {
1060 for( const LINKED_ITEM* item : m_links )
1061 min_rank = std::min( min_rank, item->Rank() );
1062 }
1063 else
1064 {
1065 min_rank = m_rank;
1066 }
1067
1068 int rank = ( min_rank == INT_MAX ) ? -1 : min_rank;
1069
1070 return rank;
1071}

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

1024{
1025 m_line = m_line.Reverse();
1026
1027 std::reverse( m_links.begin(), m_links.end() );
1028}

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

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

◆ SegmentCount()

◆ SetBlockingObstacle()

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

Definition at line 208 of file pns_line.h.

208{ m_blockingObstacle = aObstacle; }

References m_blockingObstacle.

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

◆ SetIsCompoundShapePrimitive()

void PNS::ITEM::SetIsCompoundShapePrimitive ( )
inlineinherited

Definition at line 245 of file pns_item.h.

References PNS::ITEM::m_isCompoundShapePrimitive.

◆ SetIsFreePad()

void PNS::ITEM::SetIsFreePad ( bool  aIsFreePad = true)
inlineinherited

Definition at line 237 of file pns_item.h.

237{ m_isFreePad = aIsFreePad; }

References PNS::ITEM::m_isFreePad.

◆ SetLayer()

◆ SetLayers()

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

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

178{ m_owner = aOwner; }

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

150{ m_parent = aParent; }

References PNS::ITEM::m_parent.

Referenced by PNS_KICAD_IFACE::AddItem().

◆ SetRank()

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

◆ SetRoutable()

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

Definition at line 234 of file pns_item.h.

234{ m_routable = aRoutable; }

References PNS::ITEM::m_routable.

◆ SetShape()

◆ SetSnapThreshhold()

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

Definition at line 224 of file pns_line.h.

225 {
226 m_snapThreshhold = aThreshhold;
227 }

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 201 of file pns_line.h.

201{ m_via.SetDiameter( aDiameter ); }
void SetDiameter(int aDiameter)
Definition: pns_via.h:114

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

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

◆ SetViaDrill()

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

Definition at line 202 of file pns_line.h.

202{ m_via.SetDrill( aDrill ); }
void SetDrill(int aDrill)
Definition: pns_via.h:122

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 138 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 147 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 760 of file pns_line.cpp.

762{
763 int s_start = std::max( aIndex - 2, 0 );
764 int s_end = std::min( aIndex + 2, aPath.SegmentCount() - 1 );
765
766 int i, j;
767 int best_dist = INT_MAX;
768 VECTOR2I best_snap = aP;
769
770 if( m_snapThreshhold <= 0 )
771 return aP;
772
773 for( i = s_start; i <= s_end; i++ )
774 {
775 const SEG& a = aPath.CSegment( i );
776
777 for( j = s_start; j < i; j++ )
778 {
779 const SEG& b = aPath.CSegment( j );
780
781 if( !( DIRECTION_45( a ).IsObtuse( DIRECTION_45( b ) ) ) )
782 continue;
783
784 OPT_VECTOR2I ip = a.IntersectLines( b );
785
786 if( ip )
787 {
788 int dist = ( *ip - aP ).EuclideanNorm();
789
790 if( dist < m_snapThreshhold && dist < best_dist )
791 {
792 best_dist = dist;
793 best_snap = *ip;
794 }
795 }
796 }
797 }
798
799 return best_snap;
800}
OPT_VECTOR2I IntersectLines(const SEG &aSeg) const
Compute the intersection point of lines passing through ends of (this) and aSeg.
Definition: seg.h:210
double EuclideanNorm(const VECTOR2I &vector)
Definition: trigo.h:129

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

804{
805 VECTOR2I snap_p[2];
806 DIRECTION_45 dragDir( aPath.CSegment( aIndex ) );
807 int snap_d[2] = { -1, -1 };
808
809 if( m_snapThreshhold == 0 )
810 return aP;
811
812 if( aIndex >= 2 )
813 {
814 SEG s = aPath.CSegment( aIndex - 2 );
815
816 if( DIRECTION_45( s ) == dragDir )
817 snap_d[0] = s.LineDistance( aP );
818
819 snap_p[0] = s.A;
820 }
821
822 if( aIndex < aPath.SegmentCount() - 2 )
823 {
824 SEG s = aPath.CSegment( aIndex + 2 );
825
826 if( DIRECTION_45( s ) == dragDir )
827 snap_d[1] = s.LineDistance( aP );
828
829 snap_p[1] = s.A;
830 }
831
832 VECTOR2I best = aP;
833 int minDist = INT_MAX;
834
835 for( int i = 0; i < 2; i++ )
836 {
837 if( snap_d[i] >= 0 && snap_d[i] < minDist && snap_d[i] <= m_snapThreshhold )
838 {
839 minDist = snap_d[i];
840 best = snap_p[i];
841 }
842 }
843
844 return best;
845}
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:341

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}

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 ( const SHAPE_LINE_CHAIN aObstacle,
SHAPE_LINE_CHAIN aPath,
bool  aCw 
) const

Print out all linked segments.

Definition at line 171 of file pns_line.cpp.

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

References SHAPE_LINE_CHAIN::Append(), PNS::areNeighbours(), CLine(), CPoint(), SHAPE_LINE_CHAIN::CPoint(), SHAPE_LINE_CHAIN::Find(), findVertex(), 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().

◆ Walkaround() [2/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().

◆ Width()

Member Data Documentation

◆ m_blockingObstacle

ITEM* PNS::LINE::m_blockingObstacle
private

For mark obstacle mode.

Definition at line 255 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 252 of file pns_line.h.

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

◆ m_isCompoundShapePrimitive

bool PNS::ITEM::m_isCompoundShapePrimitive
protectedinherited

◆ m_isFreePad

bool PNS::ITEM::m_isFreePad
protectedinherited

Definition at line 266 of file pns_item.h.

Referenced by PNS::ITEM::IsFreePad(), PNS::ITEM::ITEM(), and PNS::ITEM::SetIsFreePad().

◆ 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 260 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 264 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 250 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 253 of file pns_line.h.

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

◆ m_width

int PNS::LINE::m_width
private

Our width.

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