KiCad PCB EDA Suite
SHAPE_LINE_CHAIN Class Reference

Represent a polyline (an zero-thickness chain of connected line segments). More...

#include <shape_line_chain.h>

Inheritance diagram for SHAPE_LINE_CHAIN:
SHAPE_LINE_CHAIN_BASE SHAPE SHAPE_BASE

Classes

struct  compareOriginDistance
 
struct  INTERSECTION
 Represent an intersection between two line segments. More...
 
class  POINT_INSIDE_TRACKER
 A dynamic state checking if a point lies within polygon with a dynamically built outline ( with each piece of the outline added by AddPolyline () More...
 

Public Types

typedef std::vector< INTERSECTIONINTERSECTIONS
 

Public Member Functions

 SHAPE_LINE_CHAIN ()
 Initialize an empty line chain. More...
 
 SHAPE_LINE_CHAIN (const SHAPE_LINE_CHAIN &aShape)
 
 SHAPE_LINE_CHAIN (const std::vector< int > &aV)
 
 SHAPE_LINE_CHAIN (const std::vector< wxPoint > &aV, bool aClosed=false)
 
 SHAPE_LINE_CHAIN (const std::vector< VECTOR2I > &aV, bool aClosed=false)
 
 SHAPE_LINE_CHAIN (const SHAPE_ARC &aArc, bool aClosed=false)
 
 SHAPE_LINE_CHAIN (const ClipperLib::Path &aPath, const std::vector< CLIPPER_Z_VALUE > &aZValueBuffer, const std::vector< SHAPE_ARC > &aArcBuffer)
 
virtual ~SHAPE_LINE_CHAIN ()
 
SHAPE_LINE_CHAINoperator= (const SHAPE_LINE_CHAIN &)=default
 
SHAPEClone () const override
 Return a dynamically allocated copy of the shape. More...
 
void Clear ()
 Remove all points from the line chain. More...
 
void SetClosed (bool aClosed)
 Mark the line chain as closed (i.e. More...
 
bool IsClosed () const override
 
void SetWidth (int aWidth)
 Set the width of all segments in the chain. More...
 
int Width () const
 Get the current width of the segments in the chain. More...
 
int SegmentCount () const
 Return the number of segments in this line chain. More...
 
int ShapeCount () const
 Return the number of shapes (line segments or arcs) in this line chain. More...
 
int PointCount () const
 Return the number of points (vertices) in this line chain. More...
 
SEG Segment (int aIndex)
 Return a copy of the aIndex-th segment in the line chain. More...
 
const SEG CSegment (int aIndex) const
 Return a constant copy of the aIndex segment in the line chain. More...
 
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. More...
 
int PrevShape (int aPointIndex) const
 
void SetPoint (int aIndex, const VECTOR2I &aPos)
 Move a point to a specific location. More...
 
const VECTOR2ICPoint (int aIndex) const
 Return a reference to a given point in the line chain. More...
 
const std::vector< VECTOR2I > & CPoints () const
 
const VECTOR2ICLastPoint () const
 Return the last point in the line chain. More...
 
const std::vector< SHAPE_ARC > & CArcs () const
 
const std::vector< std::pair< ssize_t, ssize_t > > & CShapes () const
 
const BOX2I BBox (int aClearance=0) const override
 Compute a bounding box of the shape, with a margin of aClearance a collision. More...
 
void GenerateBBoxCache () const
 
BOX2IGetCachedBBox () const override
 
int Distance (const VECTOR2I &aP, bool aOutlineOnly=false) const
 Compute the minimum distance between the line chain and a point aP. More...
 
const SHAPE_LINE_CHAIN Reverse () const
 Reverse point order in the line chain. More...
 
void ClearArcs ()
 Remove all arc references in the line chain, resulting in a chain formed only of straight segments. More...
 
long long int Length () const
 Return length of the line chain in Euclidean metric. More...
 
void Append (int aX, int aY, bool aAllowDuplication=false)
 Append a new point at the end of the line chain. More...
 
void Append (const VECTOR2I &aP, bool aAllowDuplication=false)
 Append a new point at the end of the line chain. More...
 
void Append (const SHAPE_LINE_CHAIN &aOtherLine)
 Append another line chain at the end. More...
 
void Append (const SHAPE_ARC &aArc)
 
void Insert (size_t aVertex, const VECTOR2I &aP)
 
void Insert (size_t aVertex, const SHAPE_ARC &aArc)
 
void Replace (int aStartIndex, int aEndIndex, const VECTOR2I &aP)
 Replace points with indices in range [start_index, end_index] with a single point aP. More...
 
void Replace (int aStartIndex, int aEndIndex, const SHAPE_LINE_CHAIN &aLine)
 Replace points with indices in range [start_index, end_index] with the points from line chain aLine. More...
 
void Remove (int aStartIndex, int aEndIndex)
 Remove the range of points [start_index, end_index] from the line chain. More...
 
void Remove (int aIndex)
 Remove the aIndex-th point from the line chain. More...
 
void RemoveShape (int aPointIndex)
 Remove the shape at the given index from the line chain. More...
 
int Split (const VECTOR2I &aP)
 Insert the point aP belonging to one of the our segments, splitting the adjacent segment in two. More...
 
int Find (const VECTOR2I &aP, int aThreshold=0) const
 Search for point aP. More...
 
int FindSegment (const VECTOR2I &aP, int aThreshold=1) const
 Search for segment containing point aP. More...
 
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. More...
 
bool Intersects (const SHAPE_LINE_CHAIN &aChain) const
 
int Intersect (const SEG &aSeg, INTERSECTIONS &aIp) const
 Find all intersection points between our line chain and the segment aSeg. More...
 
int Intersect (const SHAPE_LINE_CHAIN &aChain, INTERSECTIONS &aIp, bool aExcludeColinearAndTouching=false) const
 Find all intersection points between our line chain and the line chain aChain. More...
 
int PathLength (const VECTOR2I &aP, int aIndex=-1) const
 Compute the walk path length from the beginning of the line chain and the point aP belonging to our line. More...
 
bool CheckClearance (const VECTOR2I &aP, const int aDist) const
 Check if point aP is closer to (or on) an edge or vertex of the line chain. More...
 
const OPT< INTERSECTIONSelfIntersecting () const
 Check if the line chain is self-intersecting. More...
 
SHAPE_LINE_CHAINSimplify (bool aRemoveColinear=true)
 Simplify the line chain by removing colinear adjacent segments and duplicate vertices. More...
 
int NearestSegment (const VECTOR2I &aP) const
 Find the segment nearest the given point. More...
 
const VECTOR2I NearestPoint (const VECTOR2I &aP, bool aAllowInternalShapePoints=true) const
 Find a point on the line chain that is closest to point aP. More...
 
const VECTOR2I NearestPoint (const SEG &aSeg, int &dist) const
 Find a point on the line chain that is closest to the line defined by the points of segment aSeg, also returns the distance. More...
 
const std::string Format () const override
 
bool Parse (std::stringstream &aStream) override
 
bool operator!= (const SHAPE_LINE_CHAIN &aRhs) const
 
bool CompareGeometry (const SHAPE_LINE_CHAIN &aOther) const
 
void Move (const VECTOR2I &aVector) override
 
void Mirror (bool aX=true, bool aY=false, const VECTOR2I &aRef={ 0, 0 })
 Mirror the line points about y or x (or both). More...
 
void Mirror (const SEG &axis)
 Mirror the line points using an given axis. More...
 
void Rotate (double aAngle, const VECTOR2I &aCenter=VECTOR2I(0, 0)) override
 Rotate all vertices by a given angle. More...
 
bool IsSolid () const override
 
const VECTOR2I PointAlong (int aPathLength) const
 
double Area (bool aAbsolute=true) const
 Return the area of this chain. More...
 
size_t ArcCount () const
 
ssize_t ArcIndex (size_t aSegment) const
 Return the arc index for the given segment index. More...
 
const SHAPE_ARCArc (size_t aArc) const
 
bool IsSharedPt (size_t aIndex) const
 Test if a point is shared between multiple shapes. More...
 
bool IsPtOnArc (size_t aPtIndex) const
 
bool IsArcSegment (size_t aSegment) const
 
bool IsArcStart (size_t aIndex) const
 
bool IsArcEnd (size_t aIndex) const
 
virtual const VECTOR2I GetPoint (int aIndex) const override
 
virtual const SEG GetSegment (int aIndex) const override
 
virtual size_t GetPointCount () const override
 
virtual size_t GetSegmentCount () const override
 
virtual bool Collide (const VECTOR2I &aP, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
 Check if point aP lies closer to us than aClearance. More...
 
virtual bool Collide (const SEG &aSeg, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
 Check if segment aSeg lies closer to us than aClearance. More...
 
virtual bool Collide (const SHAPE *aShape, int aClearance, VECTOR2I *aMTV) const
 Check if the boundary of shape (this) lies closer to the shape aShape than aClearance, indicating a collision. More...
 
virtual bool Collide (const SHAPE *aShape, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const
 
SEG::ecoord SquaredDistance (const VECTOR2I &aP, bool aOutlineOnly=false) const
 
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. More...
 
bool PointOnEdge (const VECTOR2I &aP, int aAccuracy=0) const
 Check if point aP lies on an edge or vertex of the line chain. More...
 
int EdgeContainingPoint (const VECTOR2I &aP, int aAccuracy=0) const
 Check if point aP lies on an edge or vertex of the line chain. More...
 
bool IsNull () const
 Return true if the shape is a null shape. More...
 
virtual VECTOR2I Centre () const
 Compute a center-of-mass of the shape. More...
 
FACETNewFacet ()
 
SGNODECalcShape (SGNODE *aParent, SGNODE *aColor, WRL1_ORDER aVertexOrder, float aCreaseLimit=0.74317, bool isVRML2=false)
 
SHAPE_TYPE Type () const
 Return the type of the shape. More...
 
virtual bool HasIndexableSubshapes () const
 
virtual size_t GetIndexableSubshapeCount () const
 
virtual void GetIndexableSubshapes (std::vector< SHAPE * > &aSubshapes)
 

Static Public Attributes

static const int MIN_PRECISION_IU = 4
 This is the minimum precision for all the points in a shape. More...
 

Protected Types

typedef VECTOR2I::extended_type ecoord
 

Protected Member Functions

void convertArc (ssize_t aArcIndex)
 Convert an arc to only a point chain by removing the arc and references. More...
 
void splitArc (ssize_t aPtIndex, bool aCoincident=false)
 Splits an arc into two arcs at aPtIndex. More...
 
void amendArc (size_t aArcIndex, const VECTOR2I &aNewStart, const VECTOR2I &aNewEnd)
 
void amendArcStart (size_t aArcIndex, const VECTOR2I &aNewStart)
 
void amendArcEnd (size_t aArcIndex, const VECTOR2I &aNewEnd)
 
ssize_t reversedArcIndex (size_t aSegment) const
 Return the arc index for the given segment index, looking backwards. More...
 
ClipperLib::Path convertToClipper (bool aRequiredOrientation, std::vector< CLIPPER_Z_VALUE > &aZValueBuffer, std::vector< SHAPE_ARC > &aArcBuffer) const
 Create a new Clipper path from the SHAPE_LINE_CHAIN in a given orientation. More...
 

Protected Attributes

SHAPE_TYPE m_type
 < type of our shape More...
 

Private Types

typedef std::vector< VECTOR2I >::iterator point_iter
 
typedef std::vector< VECTOR2I >::const_iterator point_citer
 

Private Attributes

std::vector< VECTOR2Im_points
 array of vertices More...
 
std::vector< std::pair< ssize_t, ssize_t > > m_shapes
 Array of indices that refer to the index of the shape if the point is part of a larger shape, e.g. More...
 
std::vector< SHAPE_ARCm_arcs
 
bool m_closed
 is the line chain closed? More...
 
int m_width
 Width of the segments (for BBox calculations in RTree) TODO Adjust usage of SHAPE_LINE_CHAIN to account for where we need a width and where not Alternatively, we could split the class into a LINE_CHAIN (no width) and SHAPE_LINE_CHAIN that derives from SHAPE as well that does have a width. More...
 
BOX2I m_bbox
 cached bounding box More...
 

Static Private Attributes

static const ssize_t SHAPE_IS_PT = -1
 
static const std::pair< ssize_t, ssize_t > SHAPES_ARE_PT = { SHAPE_IS_PT, SHAPE_IS_PT }
 

Friends

class SHAPE_POLY_SET
 

Detailed Description

Represent a polyline (an zero-thickness chain of connected line segments).

It is purposely not named "polyline" to avoid confusion with the existing CPolyLine in Pcbnew.

Note
The SHAPE_LINE_CHAIN class shall not be used for polygons!

Definition at line 76 of file shape_line_chain.h.

Member Typedef Documentation

◆ ecoord

typedef VECTOR2I::extended_type SHAPE::ecoord
protectedinherited

Definition at line 236 of file shape.h.

◆ INTERSECTIONS

Definition at line 137 of file shape_line_chain.h.

◆ point_citer

typedef std::vector<VECTOR2I>::const_iterator SHAPE_LINE_CHAIN::point_citer
private

Definition at line 80 of file shape_line_chain.h.

◆ point_iter

typedef std::vector<VECTOR2I>::iterator SHAPE_LINE_CHAIN::point_iter
private

Definition at line 79 of file shape_line_chain.h.

Constructor & Destructor Documentation

◆ SHAPE_LINE_CHAIN() [1/7]

SHAPE_LINE_CHAIN::SHAPE_LINE_CHAIN ( )
inline

Initialize an empty line chain.

Definition at line 143 of file shape_line_chain.h.

143  :
145  m_closed( false ),
146  m_width( 0 )
147  {}
SHAPE_LINE_CHAIN_BASE(SHAPE_TYPE aType)
Definition: shape.h:243
bool m_closed
is the line chain closed?
int m_width
Width of the segments (for BBox calculations in RTree) TODO Adjust usage of SHAPE_LINE_CHAIN to accou...
line chain (polyline)
Definition: shape.h:45

Referenced by Clone().

◆ SHAPE_LINE_CHAIN() [2/7]

SHAPE_LINE_CHAIN::SHAPE_LINE_CHAIN ( const SHAPE_LINE_CHAIN aShape)
inline

Definition at line 149 of file shape_line_chain.h.

149  :
151  m_points( aShape.m_points ),
152  m_shapes( aShape.m_shapes ),
153  m_arcs( aShape.m_arcs ),
154  m_closed( aShape.m_closed ),
155  m_width( aShape.m_width ),
156  m_bbox( aShape.m_bbox )
157  {}
SHAPE_LINE_CHAIN_BASE(SHAPE_TYPE aType)
Definition: shape.h:243
BOX2I m_bbox
cached bounding box
std::vector< SHAPE_ARC > m_arcs
bool m_closed
is the line chain closed?
std::vector< VECTOR2I > m_points
array of vertices
std::vector< std::pair< ssize_t, ssize_t > > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
int m_width
Width of the segments (for BBox calculations in RTree) TODO Adjust usage of SHAPE_LINE_CHAIN to accou...
line chain (polyline)
Definition: shape.h:45

◆ SHAPE_LINE_CHAIN() [3/7]

SHAPE_LINE_CHAIN::SHAPE_LINE_CHAIN ( const std::vector< int > &  aV)

Definition at line 48 of file shape_line_chain.cpp.

50 {
51  for(size_t i = 0; i < aV.size(); i+= 2 )
52  {
53  Append( aV[i], aV[i+1] );
54  }
55 }
SHAPE_LINE_CHAIN_BASE(SHAPE_TYPE aType)
Definition: shape.h:243
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
bool m_closed
is the line chain closed?
int m_width
Width of the segments (for BBox calculations in RTree) TODO Adjust usage of SHAPE_LINE_CHAIN to accou...
line chain (polyline)
Definition: shape.h:45

References Append().

◆ SHAPE_LINE_CHAIN() [4/7]

SHAPE_LINE_CHAIN::SHAPE_LINE_CHAIN ( const std::vector< wxPoint > &  aV,
bool  aClosed = false 
)
inline

Definition at line 161 of file shape_line_chain.h.

161  :
163  m_closed( aClosed ),
164  m_width( 0 )
165  {
166  m_points.reserve( aV.size() );
167 
168  for( auto pt : aV )
169  m_points.emplace_back( pt.x, pt.y );
170 
171  m_shapes = std::vector<std::pair<ssize_t, ssize_t>>( aV.size(), SHAPES_ARE_PT );
172  }
SHAPE_LINE_CHAIN_BASE(SHAPE_TYPE aType)
Definition: shape.h:243
bool m_closed
is the line chain closed?
std::vector< VECTOR2I > m_points
array of vertices
std::vector< std::pair< ssize_t, ssize_t > > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
int m_width
Width of the segments (for BBox calculations in RTree) TODO Adjust usage of SHAPE_LINE_CHAIN to accou...
line chain (polyline)
Definition: shape.h:45
static const std::pair< ssize_t, ssize_t > SHAPES_ARE_PT

References m_points, m_shapes, and SHAPES_ARE_PT.

◆ SHAPE_LINE_CHAIN() [5/7]

SHAPE_LINE_CHAIN::SHAPE_LINE_CHAIN ( const std::vector< VECTOR2I > &  aV,
bool  aClosed = false 
)
inline

Definition at line 174 of file shape_line_chain.h.

174  :
176  m_closed( aClosed ),
177  m_width( 0 )
178  {
179  m_points = aV;
180  m_shapes = std::vector<std::pair<ssize_t, ssize_t>>( aV.size(), SHAPES_ARE_PT );
181  }
SHAPE_LINE_CHAIN_BASE(SHAPE_TYPE aType)
Definition: shape.h:243
bool m_closed
is the line chain closed?
std::vector< VECTOR2I > m_points
array of vertices
std::vector< std::pair< ssize_t, ssize_t > > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
int m_width
Width of the segments (for BBox calculations in RTree) TODO Adjust usage of SHAPE_LINE_CHAIN to accou...
line chain (polyline)
Definition: shape.h:45
static const std::pair< ssize_t, ssize_t > SHAPES_ARE_PT

References m_points, m_shapes, and SHAPES_ARE_PT.

◆ SHAPE_LINE_CHAIN() [6/7]

SHAPE_LINE_CHAIN::SHAPE_LINE_CHAIN ( const SHAPE_ARC aArc,
bool  aClosed = false 
)
inline

Definition at line 183 of file shape_line_chain.h.

183  :
185  m_closed( aClosed ),
186  m_width( 0 )
187  {
189  m_arcs.emplace_back( aArc );
190  m_shapes = std::vector<std::pair<ssize_t, ssize_t>>( m_points.size(), SHAPES_ARE_PT );
191  }
SHAPE_LINE_CHAIN_BASE(SHAPE_TYPE aType)
Definition: shape.h:243
std::vector< SHAPE_ARC > m_arcs
bool m_closed
is the line chain closed?
const std::vector< VECTOR2I > & CPoints() const
std::vector< VECTOR2I > m_points
array of vertices
std::vector< std::pair< ssize_t, ssize_t > > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
const SHAPE_LINE_CHAIN ConvertToPolyline(double aAccuracy=DefaultAccuracyForPCB(), double *aEffectiveAccuracy=nullptr) const
Construct a SHAPE_LINE_CHAIN of segments from a given arc.
Definition: shape_arc.cpp:498
int m_width
Width of the segments (for BBox calculations in RTree) TODO Adjust usage of SHAPE_LINE_CHAIN to accou...
line chain (polyline)
Definition: shape.h:45
static const std::pair< ssize_t, ssize_t > SHAPES_ARE_PT

References SHAPE_ARC::ConvertToPolyline(), CPoints(), m_arcs, m_points, m_shapes, and SHAPES_ARE_PT.

◆ SHAPE_LINE_CHAIN() [7/7]

SHAPE_LINE_CHAIN::SHAPE_LINE_CHAIN ( const ClipperLib::Path &  aPath,
const std::vector< CLIPPER_Z_VALUE > &  aZValueBuffer,
const std::vector< SHAPE_ARC > &  aArcBuffer 
)

Definition at line 57 of file shape_line_chain.cpp.

59  :
61  m_closed( true ), m_width( 0 )
62 {
63  std::map<ssize_t, ssize_t> loadedArcs;
64  m_points.reserve( aPath.size() );
65  m_shapes.reserve( aPath.size() );
66 
67  auto loadArc =
68  [&]( ssize_t aArcIndex ) -> ssize_t
69  {
70  if( aArcIndex == SHAPE_IS_PT )
71  {
72  return SHAPE_IS_PT;
73  }
74  else if( loadedArcs.count( aArcIndex ) == 0 )
75  {
76  loadedArcs.insert( { aArcIndex, m_arcs.size() } );
77  m_arcs.push_back( aArcBuffer.at( aArcIndex ) );
78  }
79 
80  return loadedArcs.at(aArcIndex);
81  };
82 
83  for( size_t ii = 0; ii < aPath.size(); ++ii )
84  {
85  Append( aPath[ii].X, aPath[ii].Y );
86 
87  m_shapes[ii].first = loadArc( aZValueBuffer[aPath[ii].Z].m_FirstArcIdx );
88  m_shapes[ii].second = loadArc( aZValueBuffer[aPath[ii].Z].m_SecondArcIdx );
89  }
90 }
SHAPE_LINE_CHAIN_BASE(SHAPE_TYPE aType)
Definition: shape.h:243
static const ssize_t SHAPE_IS_PT
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
std::vector< SHAPE_ARC > m_arcs
bool m_closed
is the line chain closed?
std::vector< VECTOR2I > m_points
array of vertices
std::vector< std::pair< ssize_t, ssize_t > > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
int m_width
Width of the segments (for BBox calculations in RTree) TODO Adjust usage of SHAPE_LINE_CHAIN to accou...
line chain (polyline)
Definition: shape.h:45

References Append(), m_arcs, m_points, m_shapes, and SHAPE_IS_PT.

◆ ~SHAPE_LINE_CHAIN()

virtual SHAPE_LINE_CHAIN::~SHAPE_LINE_CHAIN ( )
inlinevirtual

Definition at line 197 of file shape_line_chain.h.

198  {}

Member Function Documentation

◆ amendArc()

void SHAPE_LINE_CHAIN::amendArc ( size_t  aArcIndex,
const VECTOR2I aNewStart,
const VECTOR2I aNewEnd 
)
protected

Definition at line 152 of file shape_line_chain.cpp.

154 {
155  wxCHECK_MSG( aArcIndex < m_arcs.size(), /* void */,
156  "Invalid arc index requested." );
157 
158  SHAPE_ARC& theArc = m_arcs[aArcIndex];
159 
160  // Try to preseve the centre of the original arc
161  SHAPE_ARC newArc;
162  newArc.ConstructFromStartEndCenter( aNewStart, aNewEnd, theArc.GetCenter(),
163  theArc.IsClockwise() );
164 
165  m_arcs[aArcIndex] = newArc;
166 }
std::vector< SHAPE_ARC > m_arcs
SHAPE_ARC & ConstructFromStartEndCenter(const VECTOR2I &aStart, const VECTOR2I &aEnd, const VECTOR2I &aCenter, bool aClockwise=false, double aWidth=0)
Constructs this arc from the given start, end and center.
Definition: shape_arc.cpp:201

References SHAPE_ARC::ConstructFromStartEndCenter(), and m_arcs.

Referenced by amendArcEnd(), amendArcStart(), and splitArc().

◆ amendArcEnd()

void SHAPE_LINE_CHAIN::amendArcEnd ( size_t  aArcIndex,
const VECTOR2I aNewEnd 
)
inlineprotected

Definition at line 857 of file shape_line_chain.h.

858  {
859  amendArc( aArcIndex, m_arcs[aArcIndex].GetP0(), aNewEnd );
860  }
std::vector< SHAPE_ARC > m_arcs
void amendArc(size_t aArcIndex, const VECTOR2I &aNewStart, const VECTOR2I &aNewEnd)

References amendArc(), and m_arcs.

◆ amendArcStart()

void SHAPE_LINE_CHAIN::amendArcStart ( size_t  aArcIndex,
const VECTOR2I aNewStart 
)
inlineprotected

Definition at line 852 of file shape_line_chain.h.

853  {
854  amendArc( aArcIndex, aNewStart, m_arcs[aArcIndex].GetP1() );
855  }
std::vector< SHAPE_ARC > m_arcs
void amendArc(size_t aArcIndex, const VECTOR2I &aNewStart, const VECTOR2I &aNewEnd)

References amendArc(), and m_arcs.

◆ Append() [1/4]

void SHAPE_LINE_CHAIN::Append ( int  aX,
int  aY,
bool  aAllowDuplication = false 
)
inline

Append a new point at the end of the line chain.

Parameters
aXis X coordinate of the new point.
aYis Y coordinate of the new point.
aAllowDuplicationset to true to append the new point even if it is the same as the last entered point, false (default) to skip it if it is the same as the last entered point.

Definition at line 459 of file shape_line_chain.h.

460  {
461  VECTOR2I v( aX, aY );
462  Append( v, aAllowDuplication );
463  }
Define a general 2D-vector/point.
Definition: vector2d.h:61
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.

Referenced by PNS_PCBNEW_DEBUG_DECORATOR::AddBox(), ZONE_FILLER::addHatchFillTypeOnZone(), LIB_SHAPE::AddPoint(), POLYGON_GEOM_MANAGER::AddPoint(), PNS_TEST_DEBUG_DECORATOR::AddPoint(), PNS_PCBNEW_DEBUG_DECORATOR::AddPoint(), ZONE::AddPolygon(), PNS_PCBNEW_DEBUG_DECORATOR::AddSegment(), PNS::MOUSE_TRAIL_TRACER::AddTrailPoint(), SHAPE_SIMPLE::Append(), PNS::DIFF_PAIR::Append(), Append(), PNS::ArcHull(), PNS::NODE::AssembleLine(), EDA_SHAPE::beginEdit(), BOOST_AUTO_TEST_CASE(), buildBoardBoundingBoxPoly(), PAD::BuildEffectiveShapes(), BuildFootprintPolygonOutlines(), PNS::DIFF_PAIR::BuildInitial(), DIRECTION_45::BuildInitialTrace(), ZONE_FILLER::buildThermalSpokes(), SHAPE_POLY_SET::chamferFilletPolygon(), PNS::KEEP_TOPOLOGY_CONSTRAINT::Check(), PNS::OPTIMIZER::circleBreakouts(), KI_TEST::CommonTestData::CommonTestData(), PCB_GRID_HELPER::computeAnchors(), SCH_SHEET_PIN::ConstrainOnEdge(), EDA_SHAPE::continueEdit(), ConvertArcToPolyline(), SHAPE_ARC::ConvertToPolyline(), PNS::ConvexHull(), CONVERT_TOOL::CreateLines(), PLACEFILE_GERBER_WRITER::CreatePlaceFile(), PNS::OPTIMIZER::customBreakouts(), PNS::MEANDER_PLACER::doMove(), PNS::LINE::dragSegment45(), PNS::MEANDER_SHAPE::forward(), SHAPE_POLY_SET::fractureSingle(), PNS::MEANDER_SHAPE::genMeanderShape(), CADSTAR_PCB_ARCHIVE_LOADER::getLineChainFromShapes(), PNS::MOUSE_TRAIL_TRACER::GetPosture(), HelperShapeLineChainFromAltiumVertices(), Insert(), PNS::ROUTER::isStartingPointRoutable(), IteratorFixture::IteratorFixture(), PNS::TOPOLOGY::LeadingRatLine(), CADSTAR_SCH_ARCHIVE_LOADER::loadBusses(), FABMASTER::loadFootprints(), CADSTAR_SCH_ARCHIVE_LOADER::loadNets(), FABMASTER::loadShapePolySet(), FABMASTER::loadZone(), PNS::MEANDER_SHAPE::MakeArc(), PNS::MEANDER_SHAPE::MakeCorner(), PNS::MEANDER_SHAPE::makeMiterShape(), CONVERT_TOOL::makePolysFromRects(), CONVERT_TOOL::makePolysFromSegs(), GEOM_TEST::MakeSquarePolyLine(), PNS::LINE_PLACER::mergeHead(), PNS::OPTIMIZER::mergeObtuse(), PNS::MEANDER_SHAPE::miter(), PNS::DP_MEANDER_PLACER::Move(), PNS::OctagonalHull(), ZONE_CREATE_HELPER::OnComplete(), PNS::LINE_PLACER::optimizeTailHeadTransition(), SHAPE_RECT::Outline(), SHAPE_POLY_SET::Parse(), PCB_PARSER::parseOutlinePoints(), ALTIUM_PCB::ParseRegions6Data(), partitionPolyIntoRegularCellGrid(), BRDITEMS_PLOTTER::PlotFootprintGraphicItem(), BRDITEMS_PLOTTER::PlotPcbShape(), PNS::LINE_PLACER::rhShoveOnly(), PNS::SegmentHull(), SHAPE_LINE_CHAIN(), MARKER_BASE::ShapeToPolygon(), Slice(), PNS::OPTIMIZER::smartPadsSingle(), PNS::MEANDER_SHAPE::start(), TestConcaveSquareFillet(), PNS::tightenSegment(), PNS::LINE_PLACER::Trace(), TransformCircleToPolygon(), unfracture(), SHAPE_POLY_SET::unfractureSingle(), POLYGON_GEOM_MANAGER::updateLeaderPoints(), and PNS::LINE::Walkaround().

◆ Append() [2/4]

void SHAPE_LINE_CHAIN::Append ( const VECTOR2I aP,
bool  aAllowDuplication = false 
)
inline

Append a new point at the end of the line chain.

Parameters
aPis the new point.
aAllowDuplicationset to true to append the new point even it is the same as the last entered point or false (default) to skip it if it is the same as the last entered point.

Definition at line 473 of file shape_line_chain.h.

474  {
475  if( m_points.size() == 0 )
476  m_bbox = BOX2I( aP, VECTOR2I( 0, 0 ) );
477 
478  if( m_points.size() == 0 || aAllowDuplication || CPoint( -1 ) != aP )
479  {
480  m_points.push_back( aP );
481  m_shapes.push_back( SHAPES_ARE_PT );
482  m_bbox.Merge( aP );
483  }
484  }
BOX2I m_bbox
cached bounding box
BOX2< VECTOR2I > BOX2I
Definition: box2.h:506
VECTOR2< int > VECTOR2I
Definition: vector2d.h:623
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
std::vector< VECTOR2I > m_points
array of vertices
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: box2.h:363
std::vector< std::pair< ssize_t, ssize_t > > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
static const std::pair< ssize_t, ssize_t > SHAPES_ARE_PT

References CPoint(), m_bbox, m_points, m_shapes, BOX2< Vec >::Merge(), and SHAPES_ARE_PT.

◆ Append() [3/4]

void SHAPE_LINE_CHAIN::Append ( const SHAPE_LINE_CHAIN aOtherLine)

Append another line chain at the end.

Parameters
aOtherLineis the line chain to be appended.

Definition at line 989 of file shape_line_chain.cpp.

990 {
991  assert( m_shapes.size() == m_points.size() );
992 
993  if( aOtherLine.PointCount() == 0 )
994  {
995  return;
996  }
997 
998  size_t num_arcs = m_arcs.size();
999  m_arcs.insert( m_arcs.end(), aOtherLine.m_arcs.begin(), aOtherLine.m_arcs.end() );
1000 
1001  auto fixShapeIndices =
1002  [&]( const std::pair<ssize_t, ssize_t>& aShapeIndices ) -> std::pair<ssize_t, ssize_t>
1003  {
1004  std::pair<ssize_t, ssize_t> retval = aShapeIndices;
1005 
1006  alg::run_on_pair( retval, [&]( ssize_t& aIndex )
1007  {
1008  if( aIndex != SHAPE_IS_PT )
1009  aIndex = aIndex + num_arcs;
1010  } );
1011 
1012  return retval;
1013  };
1014 
1015  if( PointCount() == 0 || aOtherLine.CPoint( 0 ) != CPoint( -1 ) )
1016  {
1017  const VECTOR2I p = aOtherLine.CPoint( 0 );
1018  m_points.push_back( p );
1019  m_shapes.push_back( fixShapeIndices( aOtherLine.CShapes()[0] ) );
1020  m_bbox.Merge( p );
1021  }
1022  else if( aOtherLine.IsArcSegment( 0 ) )
1023  {
1024  // Associate the new arc shape with the last point of this chain
1025  if( m_shapes.back() == SHAPES_ARE_PT )
1026  m_shapes.back().first = aOtherLine.CShapes()[0].first + num_arcs;
1027  else
1028  m_shapes.back().second = aOtherLine.CShapes()[0].first + num_arcs;
1029  }
1030 
1031 
1032  for( int i = 1; i < aOtherLine.PointCount(); i++ )
1033  {
1034  const VECTOR2I p = aOtherLine.CPoint( i );
1035  m_points.push_back( p );
1036 
1037  ssize_t arcIndex = aOtherLine.ArcIndex( i );
1038 
1039  if( arcIndex != ssize_t( SHAPE_IS_PT ) )
1040  {
1041  m_shapes.push_back( fixShapeIndices( aOtherLine.m_shapes[i] ) );
1042  }
1043  else
1044  m_shapes.push_back( SHAPES_ARE_PT );
1045 
1046  m_bbox.Merge( p );
1047  }
1048 
1049  assert( m_shapes.size() == m_points.size() );
1050 }
const std::vector< std::pair< ssize_t, ssize_t > > & CShapes() const
BOX2I m_bbox
cached bounding box
static const ssize_t SHAPE_IS_PT
Define a general 2D-vector/point.
Definition: vector2d.h:61
int PointCount() const
Return the number of points (vertices) in this line chain.
std::vector< SHAPE_ARC > m_arcs
ssize_t ArcIndex(size_t aSegment) const
Return the arc index for the given segment index.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
bool IsArcSegment(size_t aSegment) const
std::vector< VECTOR2I > m_points
array of vertices
void run_on_pair(std::pair< _Type, _Type > &__pair, _Function __f)
Apply a function to the first and second element of a std::pair.
Definition: kicad_algo.h:44
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: box2.h:363
std::vector< std::pair< ssize_t, ssize_t > > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
static const std::pair< ssize_t, ssize_t > SHAPES_ARE_PT

References ArcIndex(), CPoint(), CShapes(), IsArcSegment(), m_arcs, m_bbox, m_points, m_shapes, BOX2< Vec >::Merge(), PointCount(), alg::run_on_pair(), SHAPE_IS_PT, and SHAPES_ARE_PT.

◆ Append() [4/4]

void SHAPE_LINE_CHAIN::Append ( const SHAPE_ARC aArc)

Definition at line 1053 of file shape_line_chain.cpp.

1054 {
1055  SEG startToEnd( aArc.GetP0(), aArc.GetP1() );
1056 
1057  if( startToEnd.Distance( aArc.GetArcMid() ) < 1 )
1058  {
1059  // Not really a valid arc. Add as a straight line segment instead
1060  Append( aArc.GetP0() );
1061  Append( aArc.GetP1() );
1062  }
1063  else
1064  {
1065  SHAPE_LINE_CHAIN chain = aArc.ConvertToPolyline();
1066 
1067  // @todo should the below 4 LOC be moved to SHAPE_ARC::ConvertToPolyline ?
1068  chain.m_arcs.push_back( aArc );
1069 
1070  for( auto& sh : chain.m_shapes )
1071  sh.first = 0;
1072 
1073  Append( chain );
1074  }
1075 
1076  assert( m_shapes.size() == m_points.size() );
1077 }
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
std::vector< SHAPE_ARC > m_arcs
std::vector< VECTOR2I > m_points
array of vertices
const VECTOR2I & GetP0() const
Definition: shape_arc.h:111
const VECTOR2I & GetArcMid() const
Definition: shape_arc.h:113
Definition: seg.h:40
std::vector< std::pair< ssize_t, ssize_t > > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
const SHAPE_LINE_CHAIN ConvertToPolyline(double aAccuracy=DefaultAccuracyForPCB(), double *aEffectiveAccuracy=nullptr) const
Construct a SHAPE_LINE_CHAIN of segments from a given arc.
Definition: shape_arc.cpp:498
Represent a polyline (an zero-thickness chain of connected line segments).
const VECTOR2I & GetP1() const
Definition: shape_arc.h:112

References Append(), SHAPE_ARC::ConvertToPolyline(), SHAPE_ARC::GetArcMid(), SHAPE_ARC::GetP0(), SHAPE_ARC::GetP1(), m_arcs, m_points, and m_shapes.

◆ Arc()

const SHAPE_ARC& SHAPE_LINE_CHAIN::Arc ( size_t  aArc) const
inline

Definition at line 762 of file shape_line_chain.h.

763  {
764  return m_arcs[aArc];
765  }
std::vector< SHAPE_ARC > m_arcs

References m_arcs.

Referenced by PNS::NODE::Add(), BOOST_AUTO_TEST_CASE(), PNS::LINE_PLACER::FixRoute(), PCB_IO::format(), GEOM_TEST::IsOutlineValid(), NearestPoint(), GERBER_PLOTTER::PlotPoly(), and Slice().

◆ ArcCount()

size_t SHAPE_LINE_CHAIN::ArcCount ( ) const
inline

Definition at line 746 of file shape_line_chain.h.

747  {
748  return m_arcs.size();
749  }
std::vector< SHAPE_ARC > m_arcs

References m_arcs.

Referenced by PNS::LINE::ArcCount(), BOOST_AUTO_TEST_CASE(), ROUTER_PREVIEW_ITEM::drawLineChain(), PNS::LINE_PLACER::FixRoute(), and Length().

◆ ArcIndex()

ssize_t SHAPE_LINE_CHAIN::ArcIndex ( size_t  aSegment) const
inline

Return the arc index for the given segment index.

Definition at line 754 of file shape_line_chain.h.

755  {
756  if( IsSharedPt( aSegment ) )
757  return m_shapes[aSegment].second;
758  else
759  return m_shapes[aSegment].first;
760  }
bool IsSharedPt(size_t aIndex) const
Test if a point is shared between multiple shapes.
std::vector< std::pair< ssize_t, ssize_t > > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...

References IsSharedPt(), and m_shapes.

Referenced by Append(), PNS::NODE::AssembleLine(), PNS::LINE_PLACER::FixRoute(), PCB_IO::format(), PNS::LINE_PLACER::handlePullback(), GEOM_TEST::IsOutlineValid(), PNS::LINE_PLACER::mergeHead(), NearestPoint(), NextShape(), GERBER_PLOTTER::PlotPoly(), RemoveShape(), Slice(), Split(), and splitArc().

◆ Area()

double SHAPE_LINE_CHAIN::Area ( bool  aAbsolute = true) const

Return the area of this chain.

Parameters
aAbsoluteIf true, returns a positive value. Otherwise the value depends on the orientation of the chain

Definition at line 1825 of file shape_line_chain.cpp.

1826 {
1827  // see https://www.mathopenref.com/coordpolygonarea2.html
1828 
1829  if( !m_closed )
1830  return 0.0;
1831 
1832  double area = 0.0;
1833  int size = m_points.size();
1834 
1835  for( int i = 0, j = size - 1; i < size; ++i )
1836  {
1837  area += ( (double) m_points[j].x + m_points[i].x ) *
1838  ( (double) m_points[j].y - m_points[i].y );
1839  j = i;
1840  }
1841 
1842  if( aAbsolute )
1843  return std::fabs( area * 0.5 ); // The result would be negative if points are anti-clockwise
1844  else
1845  return -area * 0.5; // The result would be negative if points are anti-clockwise
1846 }
bool m_closed
is the line chain closed?
std::vector< VECTOR2I > m_points
array of vertices

References m_closed, and m_points.

Referenced by ZONE_FILLER::addHatchFillTypeOnZone(), SHAPE_POLY_SET::Area(), ZONE::CalculateFilledArea(), convertToClipper(), ZONE_FILLER::Fill(), FOOTPRINT::GetCoverageArea(), DIALOG_BOARD_STATISTICS::getDataFromPCB(), PNS::MOUSE_TRAIL_TRACER::GetPosture(), unfracture(), and SHAPE_POLY_SET::unfractureSingle().

◆ BBox()

const BOX2I SHAPE_LINE_CHAIN::BBox ( int  aClearance = 0) const
inlineoverridevirtual

Compute a bounding box of the shape, with a margin of aClearance a collision.

Parameters
aClearancehow much the bounding box is expanded wrs to the minimum enclosing rectangle for the shape.
Returns
the bounding box.

Implements SHAPE.

Definition at line 397 of file shape_line_chain.h.

398  {
399  BOX2I bbox;
400  bbox.Compute( m_points );
401 
402  if( aClearance != 0 || m_width != 0 )
403  bbox.Inflate( aClearance + m_width );
404 
405  return bbox;
406  }
void Compute(const Container &aPointList)
Compute the bounding box from a given list of points.
Definition: box2.h:75
A 2D bounding box built on top of an origin point and size vector.
Definition: box2.h:41
std::vector< VECTOR2I > m_points
array of vertices
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:281
int m_width
Width of the segments (for BBox calculations in RTree) TODO Adjust usage of SHAPE_LINE_CHAIN to accou...

References BOX2< Vec >::Compute(), BOX2< Vec >::Inflate(), m_points, and m_width.

Referenced by SHAPE_SIMPLE::BBox(), POLY_GRID_PARTITION::build(), PNS::KEEP_TOPOLOGY_CONSTRAINT::Check(), AR_AUTOPLACER::fillMatrix(), DIALOG_BOARD_STATISTICS::getDataFromPCB(), Intersect(), FABMASTER::loadZones(), and PolygonTriangulation::TesselatePolygon().

◆ CalcShape()

SGNODE * SHAPE::CalcShape ( SGNODE aParent,
SGNODE aColor,
WRL1_ORDER  aVertexOrder,
float  aCreaseLimit = 0.74317,
bool  isVRML2 = false 
)
inherited

Definition at line 703 of file wrlfacet.cpp.

705 {
706  if( facets.empty() || !facets.front()->HasMinPoints() )
707  return nullptr;
708 
709  std::vector< std::list< FACET* > > flist;
710 
711  // determine the max. index and size flist as appropriate
712  std::list< FACET* >::iterator sF = facets.begin();
713  std::list< FACET* >::iterator eF = facets.end();
714 
715  int maxIdx = 0;
716  int tmi;
717  float maxV = 0.0;
718  float tV = 0.0;
719 
720  while( sF != eF )
721  {
722  tV = ( *sF )->CalcFaceNormal();
723  tmi = ( *sF )->GetMaxIndex();
724 
725  if( tmi > maxIdx )
726  maxIdx = tmi;
727 
728  if( tV > maxV )
729  maxV = tV;
730 
731  ++sF;
732  }
733 
734  ++maxIdx;
735 
736  if( maxIdx < 3 )
737  return nullptr;
738 
739  flist.resize( maxIdx );
740 
741  // create the lists of facets common to indices
742  sF = facets.begin();
743 
744  while( sF != eF )
745  {
746  ( *sF )->Renormalize( tV );
747  ( *sF )->CollectVertices( flist );
748  ++sF;
749  }
750 
751  // calculate the normals
752  size_t vs = flist.size();
753 
754  for( size_t i = 0; i < vs; ++i )
755  {
756  sF = flist[i].begin();
757  eF = flist[i].end();
758 
759  while( sF != eF )
760  {
761  ( *sF )->CalcVertexNormal( static_cast<int>( i ), flist[i], aCreaseLimit );
762  ++sF;
763  }
764  }
765 
766  std::vector< WRLVEC3F > vertices;
767  std::vector< WRLVEC3F > normals;
768  std::vector< SGCOLOR > colors;
769 
770  // push the facet data to the final output list
771  sF = facets.begin();
772  eF = facets.end();
773 
774  while( sF != eF )
775  {
776  ( *sF )->GetData( vertices, normals, colors, aVertexOrder );
777  ++sF;
778  }
779 
780  flist.clear();
781 
782  if( vertices.size() < 3 )
783  return nullptr;
784 
785  IFSG_SHAPE shapeNode( false );
786 
787  if( !isVRML2 )
788  {
789  shapeNode.NewNode( aParent );
790 
791  if( aColor )
792  {
793  if( nullptr == S3D::GetSGNodeParent( aColor ) )
794  shapeNode.AddChildNode( aColor );
795  else
796  shapeNode.AddRefNode( aColor );
797  }
798  }
799 
800  std::vector< SGPOINT > lCPts; // vertex points in SGPOINT (double) format
801  std::vector< SGVECTOR > lCNorm; // per-vertex normals
802  vs = vertices.size();
803 
804  for( size_t i = 0; i < vs; ++i )
805  {
806  SGPOINT pt;
807  pt.x = vertices[i].x;
808  pt.y = vertices[i].y;
809  pt.z = vertices[i].z;
810  lCPts.push_back( pt );
811  lCNorm.emplace_back( normals[i].x, normals[i].y, normals[i].z );
812  }
813 
814  vertices.clear();
815  normals.clear();
816 
817  IFSG_FACESET fsNode( false );
818 
819  if( !isVRML2 )
820  fsNode.NewNode( shapeNode );
821  else
822  fsNode.NewNode( aParent );
823 
824  IFSG_COORDS cpNode( fsNode );
825  cpNode.SetCoordsList( lCPts.size(), &lCPts[0] );
826  IFSG_COORDINDEX ciNode( fsNode );
827 
828  for( int i = 0; i < (int)lCPts.size(); ++i )
829  ciNode.AddIndex( i );
830 
831  IFSG_NORMALS nmNode( fsNode );
832  nmNode.SetNormalList( lCNorm.size(), &lCNorm[0] );
833 
834  if( !colors.empty() )
835  {
836  IFSG_COLORS nmColor( fsNode );
837  nmColor.SetColorList( colors.size(), &colors[0] );
838  colors.clear();
839  }
840 
841  if( !isVRML2 )
842  return shapeNode.GetRawPtr();
843 
844  return fsNode.GetRawPtr();
845 }
double x
Definition: sg_base.h:70
IFSG_COORDS is the wrapper for SGCOORDS.
Definition: ifsg_coords.h:40
IFSG_COORDINDEX is the wrapper for SGCOORDINDEX.
IFSG_COLORS is the wrapper for SGCOLORS.
Definition: ifsg_colors.h:41
SGLIB_API SGNODE * GetSGNodeParent(SGNODE *aNode)
Definition: ifsg_api.cpp:492
double y
Definition: sg_base.h:71
IFSG_NORMALS is the wrapper for the SGNORMALS class.
Definition: ifsg_normals.h:40
std::list< FACET * > facets
Definition: wrlfacet.h:143
IFSG_FACESET is the wrapper for the SGFACESET class.
Definition: ifsg_faceset.h:40
double z
Definition: sg_base.h:72
IFSG_SHAPE is the wrapper for the SGSHAPE class.
Definition: ifsg_shape.h:40

References IFSG_NODE::AddChildNode(), IFSG_INDEX::AddIndex(), IFSG_NODE::AddRefNode(), SHAPE::facets, IFSG_NODE::GetRawPtr(), S3D::GetSGNodeParent(), IFSG_SHAPE::NewNode(), IFSG_FACESET::NewNode(), IFSG_COLORS::SetColorList(), IFSG_COORDS::SetCoordsList(), IFSG_NORMALS::SetNormalList(), SGPOINT::x, SGPOINT::y, and SGPOINT::z.

Referenced by WRL1FACESET::TranslateToSG(), X3DIFACESET::TranslateToSG(), and WRL2FACESET::TranslateToSG().

◆ CArcs()

const std::vector<SHAPE_ARC>& SHAPE_LINE_CHAIN::CArcs ( ) const
inline
Returns
the vector of stored arcs.

Definition at line 383 of file shape_line_chain.h.

384  {
385  return m_arcs;
386  }
std::vector< SHAPE_ARC > m_arcs

References m_arcs.

Referenced by ROUTER_PREVIEW_ITEM::drawLineChain(), PNS::LINE_PLACER::handlePullback(), Length(), and PNS::LINE_PLACER::mergeHead().

◆ Centre()

virtual VECTOR2I SHAPE::Centre ( ) const
inlinevirtualinherited

Compute a center-of-mass of the shape.

Returns
the center-of-mass point

Definition at line 216 of file shape.h.

217  {
218  return BBox( 0 ).Centre(); // if nothing better is available....
219  }
virtual const BOX2I BBox(int aClearance=0) const =0
Compute a bounding box of the shape, with a margin of aClearance a collision.
Vec Centre() const
Definition: box2.h:63

References SHAPE::BBox(), and BOX2< Vec >::Centre().

Referenced by Collide().

◆ CheckClearance()

bool SHAPE_LINE_CHAIN::CheckClearance ( const VECTOR2I aP,
const int  aDist 
) const

Check if point aP is closer to (or on) an edge or vertex of the line chain.

Parameters
aPis the point to check.
aDistis the distance in internal units.
Returns
true if the point is equal to or closer than aDist to the line chain.

Definition at line 1426 of file shape_line_chain.cpp.

1427 {
1428  if( !PointCount() )
1429  return false;
1430  else if( PointCount() == 1 )
1431  return m_points[0] == aP;
1432 
1433  for( int i = 0; i < SegmentCount(); i++ )
1434  {
1435  const SEG s = CSegment( i );
1436 
1437  if( s.A == aP || s.B == aP )
1438  return true;
1439 
1440  if( s.Distance( aP ) <= aDist )
1441  return true;
1442  }
1443 
1444  return false;
1445 }
int Distance(const SEG &aSeg) const
Compute minimum Euclidean distance to segment aSeg.
Definition: seg.cpp:285
int PointCount() const
Return the number of points (vertices) in this line chain.
std::vector< VECTOR2I > m_points
array of vertices
int SegmentCount() const
Return the number of segments in this line chain.
Definition: seg.h:40
const SEG CSegment(int aIndex) const
Return a constant copy of the aIndex segment in the line chain.
VECTOR2I A
Definition: seg.h:48
VECTOR2I B
Definition: seg.h:49

References SEG::A, SEG::B, CSegment(), SEG::Distance(), m_points, PointCount(), and SegmentCount().

◆ CLastPoint()

const VECTOR2I& SHAPE_LINE_CHAIN::CLastPoint ( ) const
inline

Return the last point in the line chain.

Definition at line 375 of file shape_line_chain.h.

376  {
377  return m_points[static_cast<size_t>( PointCount() ) - 1];
378  }
int PointCount() const
Return the number of points (vertices) in this line chain.
std::vector< VECTOR2I > m_points
array of vertices

References m_points, and PointCount().

Referenced by BOOST_AUTO_TEST_CASE(), EDA_SHAPE::continueEdit(), POLYGON_GEOM_MANAGER::DeleteLastCorner(), EDA_SHAPE::endEdit(), and POLYGON_GEOM_MANAGER::updateLeaderPoints().

◆ Clear()

void SHAPE_LINE_CHAIN::Clear ( )
inline

Remove all points from the line chain.

Definition at line 207 of file shape_line_chain.h.

208  {
209  m_points.clear();
210  m_arcs.clear();
211  m_shapes.clear();
212  m_closed = false;
213  }
std::vector< SHAPE_ARC > m_arcs
bool m_closed
is the line chain closed?
std::vector< VECTOR2I > m_points
array of vertices
std::vector< std::pair< ssize_t, ssize_t > > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...

References m_arcs, m_closed, m_points, and m_shapes.

Referenced by PNS_PCBNEW_DEBUG_DECORATOR::AddPoint(), PNS::LINE_PLACER::buildInitialLine(), PNS::MOUSE_TRAIL_TRACER::Clear(), SHAPE_SIMPLE::Clear(), PNS::LINE::Clear(), PNS::DIFF_PAIR::Clear(), PNS::LINE::ClipToNearestObstacle(), KI_TEST::CommonTestData::CommonTestData(), PNS::MEANDER_PLACER::doMove(), PNS::LINE_PLACER::FixRoute(), PNS::MOUSE_TRAIL_TRACER::GetPosture(), PNS::LINE_PLACER::handlePullback(), PNS::LINE_PLACER::handleSelfIntersections(), PNS::LINE_PLACER::initPlacement(), IteratorFixture::IteratorFixture(), PNS::TOPOLOGY::LeadingRatLine(), PNS::MEANDER_SHAPE::MakeArc(), PNS::MEANDER_SHAPE::MakeCorner(), DSN::SPECCTRA_DB::makeIMAGE(), PNS::DP_MEANDER_PLACER::Move(), PNS::SHOVE::onReverseCollidingVia(), PNS::LINE_PLACER::optimizeTailHeadTransition(), PNS::LINE_PLACER::reduceTail(), POLYGON_GEOM_MANAGER::Reset(), PNS::LINE_PLACER::SetLayer(), PNS::MEANDER_SHAPE::start(), PNS::tightenSegment(), and PNS::LINE_PLACER::UnfixRoute().

◆ ClearArcs()

void SHAPE_LINE_CHAIN::ClearArcs ( )

Remove all arc references in the line chain, resulting in a chain formed only of straight segments.

Any arcs in the chain are removed and only the piecewise linear approximation remains.

Definition at line 410 of file shape_line_chain.cpp.

411 {
412  for( ssize_t arcIndex = m_arcs.size() - 1; arcIndex >= 0; --arcIndex )
413  convertArc( arcIndex );
414 }
void convertArc(ssize_t aArcIndex)
Convert an arc to only a point chain by removing the arc and references.
std::vector< SHAPE_ARC > m_arcs

References convertArc(), and m_arcs.

◆ Clone()

SHAPE * SHAPE_LINE_CHAIN::Clone ( ) const
overridevirtual

Return a dynamically allocated copy of the shape.

Return values
copyof the shape

Reimplemented from SHAPE.

Definition at line 1746 of file shape_line_chain.cpp.

1747 {
1748  return new SHAPE_LINE_CHAIN( *this );
1749 }
SHAPE_LINE_CHAIN()
Initialize an empty line chain.

References SHAPE_LINE_CHAIN().

Referenced by ROUTER_PREVIEW_ITEM::Line().

◆ Collide() [1/4]

bool SHAPE::Collide ( const SHAPE aShape,
int  aClearance,
VECTOR2I aMTV 
) const
virtualinherited

Check if the boundary of shape (this) lies closer to the shape aShape than aClearance, indicating a collision.

Parameters
aShapeshape to check collision against
aClearanceminimum clearance
aMTVminimum translation vector
aActual[out] an optional pointer to an int to store the actual distance in the event of a collision.
aLocation[out] an option pointer to a point to store a nearby location in the event of a collision.
Returns
true, if there is a collision.

Reimplemented in SHAPE_RECT, SHAPE_SEGMENT, and SHAPE_COMPOUND.

Definition at line 1024 of file shape_collisions.cpp.

1025 {
1026  return collideShapes( this, aShape, aClearance, nullptr, nullptr, aMTV );
1027 }
static bool collideShapes(const SHAPE *aA, const SHAPE *aB, int aClearance, int *aActual, VECTOR2I *aLocation, VECTOR2I *aMTV)

References collideShapes().

◆ Collide() [2/4]

bool SHAPE::Collide ( const SHAPE aShape,
int  aClearance = 0,
int *  aActual = nullptr,
VECTOR2I aLocation = nullptr 
) const
virtualinherited

Reimplemented in SHAPE_POLY_SET, SHAPE_ARC, SHAPE_RECT, SHAPE_SEGMENT, and SHAPE_COMPOUND.

Definition at line 1030 of file shape_collisions.cpp.

1031 {
1032  return collideShapes( this, aShape, aClearance, aActual, aLocation, nullptr );
1033 }
static bool collideShapes(const SHAPE *aA, const SHAPE *aB, int aClearance, int *aActual, VECTOR2I *aLocation, VECTOR2I *aMTV)

References collideShapes().

◆ Collide() [3/4]

bool SHAPE_LINE_CHAIN_BASE::Collide ( const VECTOR2I aP,
int  aClearance = 0,
int *  aActual = nullptr,
VECTOR2I aLocation = nullptr 
) const
overridevirtualinherited

Check if point aP lies closer to us than aClearance.

Parameters
aPthe point to check for collisions with
aClearanceminimum distance that does not qualify as a collision.
aActualan optional pointer to an int to store the actual distance in the event of a collision.
Returns
true, when a collision has been found

Reimplemented from SHAPE.

Definition at line 250 of file shape_line_chain.cpp.

252 {
253  if( IsClosed() && PointInside( aP, aClearance ) )
254  {
255  if( aLocation )
256  *aLocation = aP;
257 
258  if( aActual )
259  *aActual = 0;
260 
261  return true;
262  }
263 
264  SEG::ecoord closest_dist_sq = VECTOR2I::ECOORD_MAX;
265  SEG::ecoord clearance_sq = SEG::Square( aClearance );
266  VECTOR2I nearest;
267 
268  for( size_t i = 0; i < GetSegmentCount(); i++ )
269  {
270  const SEG& s = GetSegment( i );
271  VECTOR2I pn = s.NearestPoint( aP );
272  SEG::ecoord dist_sq = ( pn - aP ).SquaredEuclideanNorm();
273 
274  if( dist_sq < closest_dist_sq )
275  {
276  nearest = pn;
277  closest_dist_sq = dist_sq;
278 
279  if( closest_dist_sq == 0 )
280  break;
281 
282  // If we're not looking for aActual then any collision will do
283  if( closest_dist_sq < clearance_sq && !aActual )
284  break;
285  }
286  }
287 
288  if( closest_dist_sq == 0 || closest_dist_sq < clearance_sq )
289  {
290  if( aLocation )
291  *aLocation = nearest;
292 
293  if( aActual )
294  *aActual = sqrt( closest_dist_sq );
295 
296  return true;
297  }
298 
299  return false;
300 }
virtual bool IsClosed() const =0
VECTOR2I::extended_type ecoord
Definition: seg.h:43
Define a general 2D-vector/point.
Definition: vector2d.h:61
virtual size_t GetSegmentCount() const =0
static SEG::ecoord Square(int a)
Definition: seg.h:122
static constexpr extended_type ECOORD_MAX
Definition: vector2d.h:79
bool PointInside(const VECTOR2I &aPt, int aAccuracy=0, bool aUseBBoxCache=false) const
Check if point aP lies inside a polygon (any type) defined by the line chain.
const VECTOR2I NearestPoint(const VECTOR2I &aP) const
Compute a point on the segment (this) that is closest to point aP.
Definition: seg.cpp:227
Definition: seg.h:40
virtual const SEG GetSegment(int aIndex) const =0

References VECTOR2< T >::ECOORD_MAX, SHAPE_LINE_CHAIN_BASE::GetSegment(), SHAPE_LINE_CHAIN_BASE::GetSegmentCount(), SHAPE_LINE_CHAIN_BASE::IsClosed(), SEG::NearestPoint(), SHAPE_LINE_CHAIN_BASE::PointInside(), and SEG::Square().

Referenced by PNS::MEANDERED_LINE::CheckSelfIntersections(), SHAPE_SIMPLE::Collide(), Collide(), and PCB_SELECTION_TOOL::hitTestDistance().

◆ Collide() [4/4]

bool SHAPE_LINE_CHAIN_BASE::Collide ( const SEG aSeg,
int  aClearance = 0,
int *  aActual = nullptr,
VECTOR2I aLocation = nullptr 
) const
overridevirtualinherited

Check if segment aSeg lies closer to us than aClearance.

Parameters
aSegthe segment to check for collisions with
aClearanceminimum distance that does not qualify as a collision.
aActualan optional pointer to an int to store the actual distance in the event of a collision.
Returns
true, when a collision has been found

Implements SHAPE.

Reimplemented in SHAPE_SIMPLE.

Definition at line 317 of file shape_line_chain.cpp.

319 {
320  if( IsClosed() && PointInside( aSeg.A ) )
321  {
322  if( aLocation )
323  *aLocation = aSeg.A;
324 
325  if( aActual )
326  *aActual = 0;
327 
328  return true;
329  }
330 
331  SEG::ecoord closest_dist_sq = VECTOR2I::ECOORD_MAX;
332  SEG::ecoord clearance_sq = SEG::Square( aClearance );
333  VECTOR2I nearest;
334 
335  for( size_t i = 0; i < GetSegmentCount(); i++ )
336  {
337  const SEG& s = GetSegment( i );
338  SEG::ecoord dist_sq = s.SquaredDistance( aSeg );
339 
340  if( dist_sq < closest_dist_sq )
341  {
342  if( aLocation )
343  nearest = s.NearestPoint( aSeg );
344 
345  closest_dist_sq = dist_sq;
346 
347  if( closest_dist_sq == 0)
348  break;
349 
350  // If we're not looking for aActual then any collision will do
351  if( closest_dist_sq < clearance_sq && !aActual )
352  break;
353  }
354  }
355 
356  if( closest_dist_sq == 0 || closest_dist_sq < clearance_sq )
357  {
358  if( aLocation )
359  *aLocation = nearest;
360 
361  if( aActual )
362  *aActual = sqrt( closest_dist_sq );
363 
364  return true;
365  }
366 
367  return false;
368 }
virtual bool IsClosed() const =0
VECTOR2I::extended_type ecoord
Definition: seg.h:43
Define a general 2D-vector/point.
Definition: vector2d.h:61
ecoord SquaredDistance(const SEG &aSeg) const
Definition: seg.cpp:39
virtual size_t GetSegmentCount() const =0
static SEG::ecoord Square(int a)
Definition: seg.h:122
static constexpr extended_type ECOORD_MAX
Definition: vector2d.h:79
bool PointInside(const VECTOR2I &aPt, int aAccuracy=0, bool aUseBBoxCache=false) const
Check if point aP lies inside a polygon (any type) defined by the line chain.
const VECTOR2I NearestPoint(const VECTOR2I &aP) const
Compute a point on the segment (this) that is closest to point aP.
Definition: seg.cpp:227
Definition: seg.h:40
virtual const SEG GetSegment(int aIndex) const =0
VECTOR2I A
Definition: seg.h:48

References SEG::A, VECTOR2< T >::ECOORD_MAX, SHAPE_LINE_CHAIN_BASE::GetSegment(), SHAPE_LINE_CHAIN_BASE::GetSegmentCount(), SHAPE_LINE_CHAIN_BASE::IsClosed(), SEG::NearestPoint(), SHAPE_LINE_CHAIN_BASE::PointInside(), SEG::Square(), and SEG::SquaredDistance().

◆ CompareGeometry()

bool SHAPE_LINE_CHAIN::CompareGeometry ( const SHAPE_LINE_CHAIN aOther) const

Definition at line 1720 of file shape_line_chain.cpp.

1721 {
1722  SHAPE_LINE_CHAIN a(*this), b( aOther );
1723  a.Simplify();
1724  b.Simplify();
1725 
1726  if( a.m_points.size() != b.m_points.size() )
1727  return false;
1728 
1729  for( int i = 0; i < a.PointCount(); i++ )
1730  {
1731  if( a.CPoint( i ) != b.CPoint( i ) )
1732  return false;
1733  }
1734 
1735  return true;
1736 }
Represent a polyline (an zero-thickness chain of connected line segments).

References CPoint(), m_points, and Simplify().

Referenced by PNS::LINE::CompareGeometry().

◆ convertArc()

void SHAPE_LINE_CHAIN::convertArc ( ssize_t  aArcIndex)
protected

Convert an arc to only a point chain by removing the arc and references.

Parameters
aArcIndexindex of the arc to convert to points

Definition at line 123 of file shape_line_chain.cpp.

124 {
125  if( aArcIndex < 0 )
126  aArcIndex += m_arcs.size();
127 
128  if( aArcIndex >= static_cast<ssize_t>( m_arcs.size() ) )
129  return;
130 
131  // Clear the shapes references
132  for( auto& sh : m_shapes )
133  {
134  alg::run_on_pair( sh,
135  [&]( ssize_t& aShapeIndex )
136  {
137  if( aShapeIndex == aArcIndex )
138  aShapeIndex = SHAPE_IS_PT;
139 
140  if( aShapeIndex > aArcIndex )
141  --aShapeIndex;
142  } );
143 
144  if( sh.second != SHAPE_IS_PT && sh.first == SHAPE_IS_PT )
145  std::swap( sh.first, sh.second );
146  }
147 
148  m_arcs.erase( m_arcs.begin() + aArcIndex );
149 }
static const ssize_t SHAPE_IS_PT
std::vector< SHAPE_ARC > m_arcs
void run_on_pair(std::pair< _Type, _Type > &__pair, _Function __f)
Apply a function to the first and second element of a std::pair.
Definition: kicad_algo.h:44
std::vector< std::pair< ssize_t, ssize_t > > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...

References m_arcs, m_shapes, alg::run_on_pair(), and SHAPE_IS_PT.

Referenced by ClearArcs(), Remove(), and SetPoint().

◆ convertToClipper()

ClipperLib::Path SHAPE_LINE_CHAIN::convertToClipper ( bool  aRequiredOrientation,
std::vector< CLIPPER_Z_VALUE > &  aZValueBuffer,
std::vector< SHAPE_ARC > &  aArcBuffer 
) const
protected

Create a new Clipper path from the SHAPE_LINE_CHAIN in a given orientation.

Definition at line 92 of file shape_line_chain.cpp.

95 {
96  ClipperLib::Path c_path;
97  SHAPE_LINE_CHAIN input;
98  bool orientation = Area( false ) >= 0;
99  ssize_t shape_offset = aArcBuffer.size();
100 
101  if( orientation != aRequiredOrientation )
102  input = Reverse();
103  else
104  input = *this;
105 
106  for( int i = 0; i < input.PointCount(); i++ )
107  {
108  const VECTOR2I& vertex = input.CPoint( i );
109 
110  CLIPPER_Z_VALUE z_value( input.m_shapes[i], shape_offset );
111  size_t z_value_ptr = aZValueBuffer.size();
112  aZValueBuffer.push_back( z_value );
113 
114  c_path.push_back( ClipperLib::IntPoint( vertex.x, vertex.y, z_value_ptr ) );
115  }
116 
117  aArcBuffer.insert( aArcBuffer.end(), input.m_arcs.begin(), input.m_arcs.end() );
118 
119  return c_path;
120 }
Define a general 2D-vector/point.
Definition: vector2d.h:61
double Area(bool aAbsolute=true) const
Return the area of this chain.
const SHAPE_LINE_CHAIN Reverse() const
Reverse point order in the line chain.
int PointCount() const
Return the number of points (vertices) in this line chain.
std::vector< SHAPE_ARC > m_arcs
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
std::vector< std::pair< ssize_t, ssize_t > > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
Represent a polyline (an zero-thickness chain of connected line segments).
Holds information on each point of a SHAPE_LINE_CHAIN that is retrievable after an operation with Cli...

References Area(), CPoint(), m_arcs, m_shapes, PointCount(), Reverse(), VECTOR2< T >::x, and VECTOR2< T >::y.

◆ CPoint()

const VECTOR2I& SHAPE_LINE_CHAIN::CPoint ( int  aIndex) const
inline

Return a reference to a given point in the line chain.

Parameters
aIndexis the index of the point.
Returns
a const reference to the point.

Definition at line 357 of file shape_line_chain.h.

358  {
359  if( aIndex < 0 )
360  aIndex += PointCount();
361  else if( aIndex >= PointCount() )
362  aIndex -= PointCount();
363 
364  return m_points[aIndex];
365  }
int PointCount() const
Return the number of points (vertices) in this line chain.
std::vector< VECTOR2I > m_points
array of vertices

References m_points, and PointCount().

Referenced by LABEL_MANAGER::Add(), POLYGON_GEOM_MANAGER::AddPoint(), SHAPE_LINE_CHAIN::POINT_INSIDE_TRACKER::AddPolyline(), BOARD_ADAPTER::addSolidAreasShapes(), TRIANGLE_DISPLAY_LIST::AddToMiddleContourns(), PNS::MOUSE_TRAIL_TRACER::AddTrailPoint(), Append(), PNS::LINE::AppendVia(), ArePolylineEndPointsNearCircle(), ArePolylineMidPointsNearCircle(), PNS::NODE::AssembleLine(), PNS::TOPOLOGY::AssembleTuningPath(), BOOST_AUTO_TEST_CASE(), BuildConvexHull(), PAD::BuildEffectivePolygon(), PAD::BuildEffectiveShapes(), PNS::LINE_PLACER::buildInitialLine(), SHAPE_POLY_SET::chamferFilletPolygon(), PNS::LINE::ChangedArea(), PNS::KEEP_TOPOLOGY_CONSTRAINT::Check(), CN_VISITOR::checkZoneZoneConnection(), CompareGeometry(), EDA_SHAPE::continueEdit(), convertToClipper(), PNS::coupledBypass(), SHAPE_SIMPLE::CPoint(), PNS::LINE::CPoint(), PolygonTriangulation::createList(), CreatePadsShapesSection(), PNS::cursorDistMinimum(), PNS::LINE::dragCorner45(), PNS::dragCornerInternal(), APERTURE_MACRO::DrawApertureMacroShape(), KIGFX::CAIRO_GAL_BASE::drawPoly(), KIGFX::OPENGL_GAL::DrawPolygon(), KIGFX::OPENGL_GAL::DrawPolyline(), EDA_SHAPE::endEdit(), EXPORTER_PCB_VRML::ExportVrmlBoard(), EXPORTER_PCB_VRML::ExportVrmlPolygonSet(), DSN::SPECCTRA_DB::fillBOUNDARY(), AR_AUTOPLACER::fillMatrix(), Find(), PNS::LINE_PLACER::FixRoute(), CADSTAR_SCH_ARCHIVE_LOADER::fixUpLibraryPins(), GERBER_PLOTTER::FlashPadChamferRoundRect(), PSLIKE_PLOTTER::FlashPadCustom(), GERBER_PLOTTER::FlashPadCustom(), HPGL_PLOTTER::FlashPadCustom(), DXF_PLOTTER::FlashPadCustom(), PSLIKE_PLOTTER::FlashPadRoundRect(), GERBER_PLOTTER::FlashPadRoundRect(), HPGL_PLOTTER::FlashPadRoundRect(), DXF_PLOTTER::FlashPadRoundRect(), PNS::TOPOLOGY::followTrivialPath(), PCB_IO::format(), CN_ZONE_LAYER::GetAnchor(), PCB_SHAPE::GetFocusPosition(), SHAPE_SIMPLE::GetPoint(), GetPoint(), PNS::MOUSE_TRAIL_TRACER::GetPosture(), CADSTAR_SCH_ARCHIVE_LOADER::getScaledLibPart(), PNS::MOUSE_TRAIL_TRACER::GetTrailLeadVector(), PNS::LINE_PLACER::handlePullback(), PNS::LINE_PLACER::handleSelfIntersections(), DS_DRAW_ITEM_POLYPOLYGONS::HitTest(), GEOM_TEST::IsOutlineValid(), POLYGON_GEOM_MANAGER::IsSelfIntersecting(), DSN::SPECCTRA_DB::makeIMAGE(), DSN::SPECCTRA_DB::makePADSTACK(), PNS::LINE_PLACER::mergeHead(), PNS::MEANDER_SHAPE::miter(), PNS::LINE_PLACER::Move(), NearestPoint(), POLYGON_GEOM_MANAGER::NewPointClosesOutline(), operator!=(), BOOST_TEST_PRINT_NAMESPACE_OPEN::print_log_value< SHAPE_LINE_CHAIN >::operator()(), PNS::LINE_PLACER::optimizeTailHeadTransition(), BITMAPCONV_INFO::outputOnePolygon(), PlotDrawingSheet(), BRDITEMS_PLOTTER::PlotFilledAreas(), GERBER_PLOTTER::PlotPoly(), PLOTTER::PlotPoly(), PointAlong(), PNS::pointInside2(), polygon_Convert(), LIB_SHAPE::print(), GERBER_DRAW_ITEM::PrintGerberPoly(), DS_DRAW_ITEM_POLYPOLYGONS::PrintWsItem(), PNS::LINE_PLACER::removeLoops(), PNS::DIFF_PAIR_PLACER::routeHead(), PNS::OPTIMIZER::runSmartPads(), KIGFX::PREVIEW::POLYGON_ITEM::SetPoints(), PNS::shovedArea(), PNS::SHOVE::shoveLineFromLoneVia(), PNS::SHOVE::shoveLineToHullSet(), Simplify(), PNS::COMPONENT_DRAGGER::Start(), unfracture(), SHAPE_POLY_SET::unfractureSingle(), PNS::MEANDER_SHAPE::updateBaseSegment(), POLYGON_GEOM_MANAGER::updateLeaderPoints(), PNS::LINE::Walkaround(), HYPERLYNX_EXPORTER::writeNetObjects(), GBR_TO_PCB_EXPORTER::writePcbPolygon(), and GBR_TO_PCB_EXPORTER::writePcbZoneItem().

◆ CPoints()

◆ CSegment()

const SEG SHAPE_LINE_CHAIN::CSegment ( int  aIndex) const
inline

Return a constant copy of the aIndex segment in the line chain.

Parameters
aIndexis the index of the segment in the line chain. Negative values are counted from the end (i.e. -1 means the last segment in the line chain).
Returns
a segment at aIndex in the line chain.

Definition at line 312 of file shape_line_chain.h.

313  {
314  if( aIndex < 0 )
315  aIndex += SegmentCount();
316 
317  if( aIndex == (int)( m_points.size() - 1 ) && m_closed )
318  return SEG( m_points[aIndex], m_points[0], aIndex );
319  else
320  return SEG( m_points[aIndex], m_points[aIndex + 1], aIndex );
321  }
bool m_closed
is the line chain closed?
std::vector< VECTOR2I > m_points
array of vertices
int SegmentCount() const
Return the number of segments in this line chain.
Definition: seg.h:40

References m_closed, m_points, and SegmentCount().

Referenced by PNS::MOUSE_TRAIL_TRACER::AddTrailPoint(), PNS::ArcHull(), PNS::LINE_PLACER::buildInitialLine(), PNS::PRESERVE_VERTEX_CONSTRAINT::Check(), CheckClearance(), PNS::NODE::CheckColliding(), PNS::DIFF_PAIR::CheckConnectionAngle(), PNS::checkGap(), PNS::MEANDERED_LINE::CheckSelfIntersections(), PNS::closestProjectedPoint(), PCB_GRID_HELPER::computeAnchors(), PNS::COST_ESTIMATOR::CornerCost(), PNS::LINE::CountCorners(), PNS::coupledBypass(), PNS::DIFF_PAIR::CoupledLength(), PNS::LINE::CSegment(), PNS::cursorDistMinimum(), PNS::MEANDER_PLACER_BASE::cutTunedLine(), PNS::dragCornerInternal(), PNS::findCoupledVertices(), FindSegment(), PNS::DIFF_PAIR_PLACER::FixRoute(), PNS::LINE_PLACER::FixRoute(), EDA_SHAPE::GetLength(), PNS::MOUSE_TRAIL_TRACER::GetPosture(), SHAPE_SIMPLE::GetSegment(), GetSegment(), PNS::LINE_PLACER::handlePullback(), PNS::LINE_PLACER::handleSelfIntersections(), PNS::HullIntersection(), Intersect(), PNS::LINE::Is45Degree(), Length(), PNS::OPTIMIZER::mergeColinear(), PNS::OPTIMIZER::mergeDpStep(), PNS::LINE_PLACER::mergeHead(), PNS::OPTIMIZER::mergeObtuse(), PNS::OPTIMIZER::mergeStep(), PNS::NODE::NearestObstacle(), NearestPoint(), NearestSegment(), PathLength(), PointAlong(), KIGFX::VIEW_OVERLAY::Polyline(), PNS::LINE_PLACER::reduceTail(), DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run(), POLY_GRID_PARTITION::scanCell(), PNS::SegmentHull(), SelfIntersecting(), PNS::OPTIMIZER::smartPadsSingle(), PNS::LINE::snapDraggedCorner(), PNS::LINE::snapToNeighbourSegments(), Split(), PNS::tightenSegment(), SHAPE_POLY_SET::unfractureSingle(), and HYPERLYNX_EXPORTER::writeBoardInfo().

◆ CShapes()

const std::vector<std::pair<ssize_t, ssize_t> >& SHAPE_LINE_CHAIN::CShapes ( ) const
inline
Returns
the vector of values indicating shape type and location.

Definition at line 391 of file shape_line_chain.h.

392  {
393  return m_shapes;
394  }
std::vector< std::pair< ssize_t, ssize_t > > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...

References m_shapes.

Referenced by Append(), and BOOST_AUTO_TEST_CASE().

◆ Distance()

int SHAPE_LINE_CHAIN::Distance ( const VECTOR2I aP,
bool  aOutlineOnly = false 
) const

Compute the minimum distance between the line chain and a point aP.

Parameters
aPthe point.
Returns
minimum distance.

Definition at line 608 of file shape_line_chain.cpp.

609 {
610  return sqrt( SquaredDistance( aP, aOutlineOnly ) );
611 }
SEG::ecoord SquaredDistance(const VECTOR2I &aP, bool aOutlineOnly=false) const

References SHAPE_LINE_CHAIN_BASE::SquaredDistance().

Referenced by PAD::GetBestAnchorPosition().

◆ EdgeContainingPoint()

int SHAPE_LINE_CHAIN_BASE::EdgeContainingPoint ( const VECTOR2I aP,
int  aAccuracy = 0 
) const
inherited

Check if point aP lies on an edge or vertex of the line chain.

Parameters
aPpoint to check
Returns
index of the first edge containing the point, otherwise negative

Definition at line 1399 of file shape_line_chain.cpp.

1400 {
1401  if( !GetPointCount() )
1402  {
1403  return -1;
1404  }
1405  else if( GetPointCount() == 1 )
1406  {
1407  VECTOR2I dist = GetPoint(0) - aPt;
1408  return ( hypot( dist.x, dist.y ) <= aAccuracy + 1 ) ? 0 : -1;
1409  }
1410 
1411  for( size_t i = 0; i < GetSegmentCount(); i++ )
1412  {
1413  const SEG s = GetSegment( i );
1414 
1415  if( s.A == aPt || s.B == aPt )
1416  return i;
1417 
1418  if( s.Distance( aPt ) <= aAccuracy + 1 )
1419  return i;
1420  }
1421 
1422  return -1;
1423 }
int Distance(const SEG &aSeg) const
Compute minimum Euclidean distance to segment aSeg.
Definition: seg.cpp:285
Define a general 2D-vector/point.
Definition: vector2d.h:61
virtual size_t GetPointCount() const =0
virtual size_t GetSegmentCount() const =0
Definition: seg.h:40
virtual const SEG GetSegment(int aIndex) const =0
VECTOR2I A
Definition: seg.h:48
virtual const VECTOR2I GetPoint(int aIndex) const =0
VECTOR2I B
Definition: seg.h:49

References SEG::A, SEG::B, SEG::Distance(), SHAPE_LINE_CHAIN_BASE::GetPoint(), SHAPE_LINE_CHAIN_BASE::GetPointCount(), SHAPE_LINE_CHAIN_BASE::GetSegment(), SHAPE_LINE_CHAIN_BASE::GetSegmentCount(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by SHAPE_LINE_CHAIN_BASE::PointOnEdge().

◆ Find()

int SHAPE_LINE_CHAIN::Find ( const VECTOR2I aP,
int  aThreshold = 0 
) const

Search for point aP.

Parameters
aPis the point to be looked for.
Returns
the index of the corresponding point in the line chain or negative when not found.

Definition at line 681 of file shape_line_chain.cpp.

682 {
683  for( int s = 0; s < PointCount(); s++ )
684  {
685  if( aThreshold == 0 )
686  {
687  if( CPoint( s ) == aP )
688  return s;
689  }
690  else
691  {
692  if( (CPoint( s ) - aP).EuclideanNorm() <= aThreshold )
693  return s;
694  }
695  }
696 
697  return -1;
698 }
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 CPoint(), and PointCount().

Referenced by PNS::MEANDER_PLACER_BASE::cutTunedLine(), PNS::DRAGGER::dragViaMarkObstacles(), PNS::DRAGGER::dragViaWalkaround(), PNS::NODE::FindLinesBetweenJoints(), PNS::DRAGGER::optimizeAndUpdateDraggedLine(), Split(), and PNS::LINE::Walkaround().

◆ FindSegment()

int SHAPE_LINE_CHAIN::FindSegment ( const VECTOR2I aP,
int  aThreshold = 1 
) const

Search for segment containing point aP.

Parameters
aPis the point to be looked for.
Returns
index of the corresponding segment in the line chain or negative when not found.

Definition at line 701 of file shape_line_chain.cpp.

702 {
703  for( int s = 0; s < SegmentCount(); s++ )
704  {
705  if( CSegment( s ).Distance( aP ) <= aThreshold )
706  return s;
707  }
708 
709  return -1;
710 }
int Distance(const SEG &aSeg) const
Compute minimum Euclidean distance to segment aSeg.
Definition: seg.cpp:285
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 CSegment(), SEG::Distance(), and SegmentCount().

Referenced by PNS::MEANDER_PLACER_BASE::cutTunedLine(), and CADSTAR_SCH_ARCHIVE_LOADER::loadNets().

◆ Format()

const std::string SHAPE_LINE_CHAIN::Format ( ) const
overridevirtual

Reimplemented from SHAPE.

Definition at line 1691 of file shape_line_chain.cpp.

1692 {
1693  std::stringstream ss;
1694 
1695  ss << "SHAPE_LINE_CHAIN( { ";
1696 
1697  for( int i = 0; i < PointCount(); i++ )
1698  {
1699  ss << "VECTOR2I( " << m_points[i].x << ", " << m_points[i].y << ")";
1700 
1701  if( i != PointCount() -1 )
1702  ss << ", ";
1703  }
1704 
1705  ss << "}, " << ( m_closed ? "true" : "false" );
1706  ss << " );";
1707 
1708  return ss.str();
1709 
1710  /* fixme: arcs
1711  for( size_t i = 0; i < m_arcs.size(); i++ )
1712  ss << m_arcs[i].GetCenter().x << " " << m_arcs[i].GetCenter().y << " "
1713  << m_arcs[i].GetP0().x << " " << m_arcs[i].GetP0().y << " "
1714  << m_arcs[i].GetCentralAngle();
1715 
1716  return ss.str();*/
1717 }
int PointCount() const
Return the number of points (vertices) in this line chain.
bool m_closed
is the line chain closed?
std::vector< VECTOR2I > m_points
array of vertices

References m_closed, m_points, and PointCount().

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

◆ GenerateBBoxCache()

void SHAPE_LINE_CHAIN::GenerateBBoxCache ( ) const
inline

Definition at line 408 of file shape_line_chain.h.

409  {
411 
412  if( m_width != 0 )
414  }
BOX2I m_bbox
cached bounding box
void Compute(const Container &aPointList)
Compute the bounding box from a given list of points.
Definition: box2.h:75
std::vector< VECTOR2I > m_points
array of vertices
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:281
int m_width
Width of the segments (for BBox calculations in RTree) TODO Adjust usage of SHAPE_LINE_CHAIN to accou...

References BOX2< Vec >::Compute(), BOX2< Vec >::Inflate(), m_bbox, m_points, and m_width.

Referenced by SHAPE_POLY_SET::BuildBBoxCaches(), and ZONE_FILLER::buildThermalSpokes().

◆ GetCachedBBox()

BOX2I* SHAPE_LINE_CHAIN::GetCachedBBox ( ) const
inlineoverridevirtual

Reimplemented from SHAPE_LINE_CHAIN_BASE.

Definition at line 416 of file shape_line_chain.h.

417  {
418  return &m_bbox;
419  }
BOX2I m_bbox
cached bounding box

References m_bbox.

◆ GetIndexableSubshapeCount()

virtual size_t SHAPE_BASE::GetIndexableSubshapeCount ( ) const
inlinevirtualinherited

Reimplemented in SHAPE_POLY_SET, and SHAPE_COMPOUND.

Definition at line 104 of file shape.h.

104 { return 0; }

◆ GetIndexableSubshapes()

virtual void SHAPE_BASE::GetIndexableSubshapes ( std::vector< SHAPE * > &  aSubshapes)
inlinevirtualinherited

Reimplemented in SHAPE_POLY_SET, and SHAPE_COMPOUND.

Definition at line 106 of file shape.h.

106 { }

Referenced by SHAPE_COMPOUND::AddShape(), and ROUTER_PREVIEW_ITEM::ViewDraw().

◆ GetPoint()

virtual const VECTOR2I SHAPE_LINE_CHAIN::GetPoint ( int  aIndex) const
inlineoverridevirtual

Implements SHAPE_LINE_CHAIN_BASE.

Definition at line 821 of file shape_line_chain.h.

821 { return CPoint(aIndex); }
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.

References CPoint().

Referenced by PNS::TOPOLOGY::AssembleTuningPath(), BOOST_AUTO_TEST_CASE(), BuildFootprintPolygonOutlines(), PNS::LINE::dragCornerFree(), CADSTAR_PCB_ARCHIVE_LOADER::getLineChainFromShapes(), EDA_SHAPE::hitTest(), Split(), and TransformArcToPolygon().

◆ GetPointCount()

virtual size_t SHAPE_LINE_CHAIN::GetPointCount ( ) const
inlineoverridevirtual

◆ GetSegment()

virtual const SEG SHAPE_LINE_CHAIN::GetSegment ( int  aIndex) const
inlineoverridevirtual

Implements SHAPE_LINE_CHAIN_BASE.

Definition at line 822 of file shape_line_chain.h.

822 { return CSegment(aIndex); }
const SEG CSegment(int aIndex) const
Return a constant copy of the aIndex segment in the line chain.

References CSegment().

◆ GetSegmentCount()

virtual size_t SHAPE_LINE_CHAIN::GetSegmentCount ( ) const
inlineoverridevirtual

Implements SHAPE_LINE_CHAIN_BASE.

Definition at line 824 of file shape_line_chain.h.

824 { return SegmentCount(); }
int SegmentCount() const
Return the number of segments in this line chain.

References SegmentCount().

Referenced by DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run(), and TransformArcToPolygon().

◆ HasIndexableSubshapes()

virtual bool SHAPE_BASE::HasIndexableSubshapes ( ) const
inlinevirtualinherited

Reimplemented in SHAPE_POLY_SET, and SHAPE_COMPOUND.

Definition at line 99 of file shape.h.

100  {
101  return false;
102  }

Referenced by SHAPE_COMPOUND::AddShape(), and ROUTER_PREVIEW_ITEM::ViewDraw().

◆ Insert() [1/2]

void SHAPE_LINE_CHAIN::Insert ( size_t  aVertex,
const VECTOR2I aP 
)

Definition at line 1080 of file shape_line_chain.cpp.

1081 {
1082  if( aVertex == m_points.size() )
1083  {
1084  Append( aP );
1085  return;
1086  }
1087 
1088  wxCHECK( aVertex < m_points.size(), /* void */ );
1089 
1090  if( aVertex > 0 && IsPtOnArc( aVertex ) )
1091  splitArc( aVertex );
1092 
1093  //@todo need to check we aren't creating duplicate points
1094  m_points.insert( m_points.begin() + aVertex, aP );
1095  m_shapes.insert( m_shapes.begin() + aVertex, SHAPES_ARE_PT );
1096 
1097  assert( m_shapes.size() == m_points.size() );
1098 }
void splitArc(ssize_t aPtIndex, bool aCoincident=false)
Splits an arc into two arcs at aPtIndex.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
std::vector< VECTOR2I > m_points
array of vertices
bool IsPtOnArc(size_t aPtIndex) const
std::vector< std::pair< ssize_t, ssize_t > > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
static const std::pair< ssize_t, ssize_t > SHAPES_ARE_PT

References Append(), IsPtOnArc(), m_points, m_shapes, SHAPES_ARE_PT, and splitArc().

Referenced by PNS::TOPOLOGY::AssembleTuningPath(), PNS::LINE::dragCorner45(), PNS::LINE::dragCornerFree(), CONVERT_TOOL::makePolysFromSegs(), Replace(), and Split().

◆ Insert() [2/2]

void SHAPE_LINE_CHAIN::Insert ( size_t  aVertex,
const SHAPE_ARC aArc 
)

Step 1: Find the position for the new arc in the existing arc vector

Step 2: Add the arc polyline points to the chain

Step 3: Add the vector of indices to the shape vector

Definition at line 1101 of file shape_line_chain.cpp.

1102 {
1103  wxCHECK( aVertex < m_points.size(), /* void */ );
1104 
1105  if( aVertex > 0 && IsPtOnArc( aVertex ) )
1106  splitArc( aVertex );
1107 
1109  ssize_t arc_pos = m_arcs.size();
1110 
1111  for( auto arc_it = m_shapes.rbegin() ;
1112  arc_it != m_shapes.rend() + aVertex;
1113  arc_it++ )
1114  {
1115  if( *arc_it != SHAPES_ARE_PT )
1116  {
1117  arc_pos = std::max( ( *arc_it ).first, ( *arc_it ).second );
1118  arc_pos++;
1119  }
1120  }
1121 
1122  //Increment all arc indices before inserting the new arc
1123  for( auto& sh : m_shapes )
1124  {
1125  alg::run_on_pair( sh,
1126  [&]( ssize_t& aIndex )
1127  {
1128  if( aIndex >= arc_pos )
1129  aIndex++;
1130  } );
1131  }
1132 
1133  m_arcs.insert( m_arcs.begin() + arc_pos, aArc );
1134 
1136  //@todo need to check we aren't creating duplicate points at start or end
1137  auto& chain = aArc.ConvertToPolyline();
1138  m_points.insert( m_points.begin() + aVertex, chain.CPoints().begin(), chain.CPoints().end() );
1139 
1141  //@todo need to check we aren't creating duplicate points at start or end
1142  std::vector<std::pair<ssize_t, ssize_t>> new_points( chain.PointCount(),
1143  { arc_pos, SHAPE_IS_PT } );
1144 
1145  m_shapes.insert( m_shapes.begin() + aVertex, new_points.begin(), new_points.end() );
1146  assert( m_shapes.size() == m_points.size() );
1147 }
static const ssize_t SHAPE_IS_PT
void splitArc(ssize_t aPtIndex, bool aCoincident=false)
Splits an arc into two arcs at aPtIndex.
std::vector< SHAPE_ARC > m_arcs
std::vector< VECTOR2I > m_points
array of vertices
void run_on_pair(std::pair< _Type, _Type > &__pair, _Function __f)
Apply a function to the first and second element of a std::pair.
Definition: kicad_algo.h:44
bool IsPtOnArc(size_t aPtIndex) const
std::vector< std::pair< ssize_t, ssize_t > > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
const SHAPE_LINE_CHAIN ConvertToPolyline(double aAccuracy=DefaultAccuracyForPCB(), double *aEffectiveAccuracy=nullptr) const
Construct a SHAPE_LINE_CHAIN of segments from a given arc.
Definition: shape_arc.cpp:498
static const std::pair< ssize_t, ssize_t > SHAPES_ARE_PT

References SHAPE_ARC::ConvertToPolyline(), IsPtOnArc(), m_arcs, m_points, m_shapes, alg::run_on_pair(), SHAPE_IS_PT, SHAPES_ARE_PT, and splitArc().

◆ Intersect() [1/2]

int SHAPE_LINE_CHAIN::Intersect ( const SEG aSeg,
INTERSECTIONS aIp 
) const

Find all intersection points between our line chain and the segment aSeg.

Parameters
aSegis the segment chain to find intersections with.
aIpis the reference to a vector to store found intersections. Intersection points are sorted with increasing distances from point aSeg.a.
Returns
the number of intersections found.

Definition at line 1165 of file shape_line_chain.cpp.

1166 {
1167  for( int s = 0; s < SegmentCount(); s++ )
1168  {
1169  OPT_VECTOR2I p = CSegment( s ).Intersect( aSeg );
1170 
1171  if( p )
1172  {
1173  INTERSECTION is;
1174  is.valid = true;
1175  is.index_our = s;
1176  is.index_their = -1;
1177  is.is_corner_our = is.is_corner_their = false;
1178  is.p = *p;
1179  aIp.push_back( is );
1180  }
1181  }
1182 
1183  compareOriginDistance comp( aSeg.A );
1184  sort( aIp.begin(), aIp.end(), comp );
1185 
1186  return aIp.size();
1187 }
OPT_VECTOR2I Intersect(const SEG &aSeg, bool aIgnoreEndpoints=false, bool aLines=false) const
Compute intersection point of segment (this) with segment aSeg.
Definition: seg.cpp:154
OPT< VECTOR2I > OPT_VECTOR2I
Definition: seg.h:38
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.
VECTOR2I A
Definition: seg.h:48

References SEG::A, CSegment(), SHAPE_LINE_CHAIN::INTERSECTION::index_our, SHAPE_LINE_CHAIN::INTERSECTION::index_their, SEG::Intersect(), SHAPE_LINE_CHAIN::INTERSECTION::is_corner_our, SHAPE_LINE_CHAIN::INTERSECTION::is_corner_their, SHAPE_LINE_CHAIN::INTERSECTION::p, SegmentCount(), and SHAPE_LINE_CHAIN::INTERSECTION::valid.

Referenced by PNS::OPTIMIZER::customBreakouts(), CN_ITEM::GetAnchor(), PNS::LINE_PLACER::handleSelfIntersections(), PNS::HullIntersection(), Intersects(), CADSTAR_SCH_ARCHIVE_LOADER::loadNets(), and POLYGON_GEOM_MANAGER::updateLeaderPoints().

◆ Intersect() [2/2]

int SHAPE_LINE_CHAIN::Intersect ( const SHAPE_LINE_CHAIN aChain,
INTERSECTIONS aIp,
bool  aExcludeColinearAndTouching = false 
) const

Find all intersection points between our line chain and the line chain aChain.

Parameters
aChainis the line chain to find intersections with.
aIpis reference to a vector to store found intersections. Intersection points are sorted with increasing path lengths from the starting point of aChain.
Returns
the number of intersections found.

Definition at line 1205 of file shape_line_chain.cpp.

1207 {
1208  BOX2I bb_other = aChain.BBox();
1209 
1210  for( int s1 = 0; s1 < SegmentCount(); s1++ )
1211  {
1212  const SEG& a = CSegment( s1 );
1213  const BOX2I bb_cur( a.A, a.B - a.A );
1214 
1215  if( !bb_other.Intersects( bb_cur ) )
1216  continue;
1217 
1218  for( int s2 = 0; s2 < aChain.SegmentCount(); s2++ )
1219  {
1220  const SEG& b = aChain.CSegment( s2 );
1221  INTERSECTION is;
1222 
1223  is.index_our = s1;
1224  is.index_their = s2;
1225  is.is_corner_our = false;
1226  is.is_corner_their = false;
1227  is.valid = true;
1228 
1229  OPT_VECTOR2I p = a.Intersect( b );
1230 
1231  bool coll = a.Collinear( b );
1232 
1233  if( coll && ! aExcludeColinearAndTouching )
1234  {
1235  if( a.Contains( b.A ) )
1236  {
1237  is.p = b.A;
1238  is.is_corner_their = true;
1239  addIntersection(aIp, PointCount(), is);
1240  }
1241 
1242  if( a.Contains( b.B ) )
1243  {
1244  is.p = b.B;
1245  is.index_their++;
1246  is.is_corner_their = true;
1247  addIntersection( aIp, PointCount(), is );
1248  }
1249 
1250  if( b.Contains( a.A ) )
1251  {
1252  is.p = a.A;
1253  is.is_corner_our = true;
1254  addIntersection( aIp, PointCount(), is );
1255  }
1256 
1257  if( b.Contains( a.B ) )
1258  {
1259  is.p = a.B;
1260  is.index_our++;
1261  is.is_corner_our = true;
1262  addIntersection( aIp, PointCount(), is );
1263  }
1264  }
1265  else if( p )
1266  {
1267  is.p = *p;
1268  is.is_corner_our = false;
1269  is.is_corner_their = false;
1270 
1271  int distA = ( b.A - *p ).EuclideanNorm();
1272  int distB = ( b.B - *p ).EuclideanNorm();
1273 
1274  if( p == a.A )
1275  {
1276  is.is_corner_our = true;
1277  }
1278 
1279  if( p == a.B )
1280  {
1281  is.is_corner_our = true;
1282  is.index_our++;
1283  }
1284 
1285  if( p == b.A )
1286  {
1287  is.is_corner_their = true;
1288  }
1289 
1290  if( p == b.B )
1291  {
1292  is.is_corner_their = true;
1293  is.index_their++;
1294  }
1295 
1296  addIntersection( aIp, PointCount(), is );
1297  }
1298  }
1299  }
1300 
1301  return aIp.size();
1302 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:146
OPT_VECTOR2I Intersect(const SEG &aSeg, bool aIgnoreEndpoints=false, bool aLines=false) const
Compute intersection point of segment (this) with segment aSeg.
Definition: seg.cpp:154
int PointCount() const
Return the number of points (vertices) in this line chain.
A 2D bounding box built on top of an origin point and size vector.
Definition: box2.h:41
bool Intersects(const BOX2< Vec > &aRect) const
Definition: box2.h:217
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
OPT< VECTOR2I > OPT_VECTOR2I
Definition: seg.h:38
int SegmentCount() const
Return the number of segments in this line chain.
bool Collinear(const SEG &aSeg) const
Check if segment aSeg lies on the same line as (this).
Definition: seg.h:268
Definition: seg.h:40
const SEG CSegment(int aIndex) const
Return a constant copy of the aIndex segment in the line chain.
VECTOR2I A
Definition: seg.h:48
static void addIntersection(SHAPE_LINE_CHAIN::INTERSECTIONS &aIps, int aPc, const SHAPE_LINE_CHAIN::INTERSECTION &aP)
bool Contains(const SEG &aSeg) const
Definition: seg.h:331
VECTOR2I B
Definition: seg.h:49

References SEG::A, addIntersection(), SEG::B, BBox(), SEG::Collinear(), SEG::Contains(), CSegment(), EuclideanNorm(), SHAPE_LINE_CHAIN::INTERSECTION::index_our, SHAPE_LINE_CHAIN::INTERSECTION::index_their, SEG::Intersect(), BOX2< Vec >::Intersects(), SHAPE_LINE_CHAIN::INTERSECTION::is_corner_our, SHAPE_LINE_CHAIN::INTERSECTION::is_corner_their, SHAPE_LINE_CHAIN::INTERSECTION::p, PointCount(), SegmentCount(), and SHAPE_LINE_CHAIN::INTERSECTION::valid.

◆ Intersects()

bool SHAPE_LINE_CHAIN::Intersects ( const SHAPE_LINE_CHAIN aChain) const

Definition at line 1739 of file shape_line_chain.cpp.

1740 {
1742  return Intersect( aChain, dummy ) != 0;
1743 }
int Intersect(const SEG &aSeg, INTERSECTIONS &aIp) const
Find all intersection points between our line chain and the segment aSeg.
std::vector< INTERSECTION > INTERSECTIONS
static LIB_SYMBOL * dummy()
Used to draw a dummy shape when a LIB_SYMBOL is not found in library.
Definition: sch_symbol.cpp:72

References dummy(), and Intersect().

Referenced by PNS::DIFF_PAIR::BuildInitial().

◆ IsArcEnd()

bool SHAPE_LINE_CHAIN::IsArcEnd ( size_t  aIndex) const
inline

Definition at line 813 of file shape_line_chain.h.

814  {
815  if( aIndex == static_cast<size_t>( PointCount() ) - 1 )
816  return IsPtOnArc( aIndex );
817 
818  return ( IsSharedPt( aIndex ) || ( IsPtOnArc( aIndex ) && !IsArcSegment( aIndex ) ) );
819  }
bool IsSharedPt(size_t aIndex) const
Test if a point is shared between multiple shapes.
int PointCount() const
Return the number of points (vertices) in this line chain.
bool IsArcSegment(size_t aSegment) const
bool IsPtOnArc(size_t aPtIndex) const

References IsArcSegment(), IsPtOnArc(), IsSharedPt(), and PointCount().

Referenced by BOOST_AUTO_TEST_CASE(), GEOM_TEST::IsOutlineValid(), NearestPoint(), and splitArc().

◆ IsArcSegment()

bool SHAPE_LINE_CHAIN::IsArcSegment ( size_t  aSegment) const
inline

Definition at line 786 of file shape_line_chain.h.

787  {
788  /*
789  * A segment is part of an arc except in the special case of two arcs next to each other
790  * but without a shared vertex. Here there is a segment between the end of the first arc
791  * and the start of the second arc.
792  */
793  size_t nextIdx = aSegment + 1;
794 
795  if( nextIdx > m_shapes.size() - 1 )
796  return false; // Always false, even if the shape is closed
797 
798  return ( IsPtOnArc( aSegment )
799  && ( IsSharedPt( aSegment )
800  || m_shapes[aSegment].first == m_shapes[nextIdx].first ) );
801  }
bool IsSharedPt(size_t aIndex) const
Test if a point is shared between multiple shapes.
bool IsPtOnArc(size_t aPtIndex) const
std::vector< std::pair< ssize_t, ssize_t > > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...

References IsPtOnArc(), IsSharedPt(), and m_shapes.

Referenced by Append(), PNS::LINE::dragCornerFree(), PNS::LINE::Is45Degree(), IsArcEnd(), IsArcStart(), Length(), PNS::LINE_PLACER::mergeHead(), PNS::OPTIMIZER::mergeStep(), NearestPoint(), Slice(), and Split().

◆ IsArcStart()

bool SHAPE_LINE_CHAIN::IsArcStart ( size_t  aIndex) const
inline

Definition at line 804 of file shape_line_chain.h.

805  {
806  if( aIndex == 0 )
807  return IsPtOnArc( aIndex );
808 
809  return ( IsSharedPt( aIndex ) || ( IsPtOnArc( aIndex ) && !IsArcSegment( aIndex - 1 ) ) );
810  }
bool IsSharedPt(size_t aIndex) const
Test if a point is shared between multiple shapes.
bool IsArcSegment(size_t aSegment) const
bool IsPtOnArc(size_t aPtIndex) const

References IsArcSegment(), IsPtOnArc(), and IsSharedPt().

Referenced by BOOST_AUTO_TEST_CASE(), GEOM_TEST::IsOutlineValid(), NearestPoint(), Slice(), and splitArc().

◆ IsClosed()

bool SHAPE_LINE_CHAIN::IsClosed ( ) const
inlineoverridevirtual

◆ IsNull()

bool SHAPE::IsNull ( ) const
inlineinherited

Return true if the shape is a null shape.

Return values
trueif null :-)

Definition at line 150 of file shape.h.

151  {
152  return m_type == SH_NULL;
153  }
SHAPE_TYPE m_type
< type of our shape
Definition: shape.h:110
empty shape (no shape...),
Definition: shape.h:51

References SHAPE_BASE::m_type, and SH_NULL.

◆ IsPtOnArc()

bool SHAPE_LINE_CHAIN::IsPtOnArc ( size_t  aPtIndex) const
inline

Definition at line 780 of file shape_line_chain.h.

781  {
782  return aPtIndex < m_shapes.size() && m_shapes[aPtIndex] != SHAPES_ARE_PT;
783  }
std::vector< std::pair< ssize_t, ssize_t > > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
static const std::pair< ssize_t, ssize_t > SHAPES_ARE_PT

References m_shapes, and SHAPES_ARE_PT.

Referenced by PNS::LINE::dragCorner45(), PNS::LINE::dragCornerFree(), PNS::LINE_PLACER::FixRoute(), PNS::LINE_PLACER::handlePullback(), Insert(), IsArcEnd(), IsArcSegment(), IsArcStart(), PNS::OPTIMIZER::mergeColinear(), PNS::LINE_PLACER::mergeHead(), Remove(), splitArc(), and PNS::DRAGGER::startDragSegment().

◆ IsSharedPt()

bool SHAPE_LINE_CHAIN::IsSharedPt ( size_t  aIndex) const
inline

Test if a point is shared between multiple shapes.

Parameters
aIndex
Returns

Definition at line 772 of file shape_line_chain.h.

773  {
774  return aIndex < m_shapes.size() - 1
775  && m_shapes[aIndex].first != SHAPE_IS_PT
776  && m_shapes[aIndex].second != SHAPE_IS_PT;
777  }
static const ssize_t SHAPE_IS_PT
std::vector< std::pair< ssize_t, ssize_t > > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...

References m_shapes, and SHAPE_IS_PT.

Referenced by ArcIndex(), BOOST_AUTO_TEST_CASE(), IsArcEnd(), IsArcSegment(), IsArcStart(), GEOM_TEST::IsOutlineValid(), Remove(), RemoveShape(), reversedArcIndex(), and splitArc().

◆ IsSolid()

bool SHAPE_LINE_CHAIN::IsSolid ( ) const
inlineoverridevirtual

Implements SHAPE.

Definition at line 732 of file shape_line_chain.h.

733  {
734  return false;
735  }

◆ Length()

long long int SHAPE_LINE_CHAIN::Length ( ) const

Return length of the line chain in Euclidean metric.

Returns
the length of the line chain.

Definition at line 417 of file shape_line_chain.cpp.

418 {
419  long long int l = 0;
420 
421  for( int i = 0; i < SegmentCount(); i++ )
422  {
423  // Only include segments that aren't part of arc shapes
424  if( !IsArcSegment(i) )
425  l += CSegment( i ).Length();
426  }
427 
428  for( int i = 0; i < ArcCount(); i++ )
429  l += CArcs()[i].GetLength();
430 
431  return l;
432 }
int Length() const
Return the length (this).
Definition: seg.h:350
size_t ArcCount() const
const std::vector< SHAPE_ARC > & CArcs() const
bool IsArcSegment(size_t aSegment) const
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 ArcCount(), CArcs(), CSegment(), IsArcSegment(), SEG::Length(), and SegmentCount().

Referenced by PNS::COST_ESTIMATOR::Add(), PNS::LINE::dragSegment45(), PNS::OPTIMIZER::fanoutCleanup(), PNS::MEANDER_SHAPE::MaxTunableLength(), PNS::SHOVE::onCollidingArc(), PNS::SHOVE::onCollidingSegment(), PNS::COST_ESTIMATOR::Remove(), PNS::COST_ESTIMATOR::Replace(), PNS::LINE_PLACER::rhWalkOnly(), PNS::WALKAROUND::Route(), PNS::SHOVE::shoveLineFromLoneVia(), PNS::DIFF_PAIR::Skew(), PNS::DIFF_PAIR::TotalLength(), and PNS::DRAGGER::tryWalkaround().

◆ Mirror() [1/2]

void SHAPE_LINE_CHAIN::Mirror ( bool  aX = true,
bool  aY = false,
const VECTOR2I aRef = { 0, 0 } 
)

Mirror the line points about y or x (or both).

Parameters
aXIf true, mirror about the y axis (flip X coordinate).
aYIf true, mirror about the x axis (flip Y coordinate).
aRefsets the reference point about which to mirror.

Definition at line 435 of file shape_line_chain.cpp.

436 {
437  for( auto& pt : m_points )
438  {
439  if( aX )
440  pt.x = -pt.x + 2 * aRef.x;
441 
442  if( aY )
443  pt.y = -pt.y + 2 * aRef.y;
444  }
445 
446  for( auto& arc : m_arcs )
447  arc.Mirror( aX, aY, aRef );
448 }
std::vector< SHAPE_ARC > m_arcs
std::vector< VECTOR2I > m_points
array of vertices

References m_arcs, m_points, VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by PNS::MEANDER_SHAPE::genMeanderShape().

◆ Mirror() [2/2]

void SHAPE_LINE_CHAIN::Mirror ( const SEG axis)

Mirror the line points using an given axis.

Parameters
axisis the axis on which to mirror.

Definition at line 451 of file shape_line_chain.cpp.

452 {
453  for( auto& pt : m_points )
454  pt = axis.ReflectPoint( pt );
455 
456  for( auto& arc : m_arcs )
457  arc.Mirror( axis );
458 }
const VECTOR2I ReflectPoint(const VECTOR2I &aP) const
Reflect a point using this segment as axis.
Definition: seg.cpp:249
std::vector< SHAPE_ARC > m_arcs
std::vector< VECTOR2I > m_points
array of vertices

References m_arcs, m_points, and SEG::ReflectPoint().

◆ Move()

void SHAPE_LINE_CHAIN::Move ( const VECTOR2I aVector)
inlineoverridevirtual

Implements SHAPE.

Definition at line 699 of file shape_line_chain.h.

700  {
701  for( auto& pt : m_points )
702  pt += aVector;
703 
704  for( auto& arc : m_arcs )
705  arc.Move( aVector );
706  }
std::vector< SHAPE_ARC > m_arcs
std::vector< VECTOR2I > m_points
array of vertices

References m_arcs, and m_points.

Referenced by ZONE_FILLER::addHatchFillTypeOnZone(), PAD::BuildEffectiveShapes(), ZONE_FILLER::buildThermalSpokes(), PLACEFILE_GERBER_WRITER::CreatePlaceFile(), EDA_SHAPE::hitTest(), PCB_SELECTION_TOOL::hitTestDistance(), EDA_SHAPE::MakeEffectiveShapes(), and SHAPE_SIMPLE::Move().

◆ NearestPoint() [1/2]

const VECTOR2I SHAPE_LINE_CHAIN::NearestPoint ( const VECTOR2I aP,
bool  aAllowInternalShapePoints = true 
) const

Find a point on the line chain that is closest to point aP.

Parameters
aPis the point to find.
aAllowInternalShapePointsif false will not return points internal to an arc (i.e. only the arc endpoints are possible candidates)
Returns
the nearest point.

Definition at line 1598 of file shape_line_chain.cpp.

1600 {
1601  int min_d = INT_MAX;
1602  int nearest = 0;
1603 
1604  for( int i = 0; i < SegmentCount(); i++ )
1605  {
1606  int d = CSegment( i ).Distance( aP );
1607 
1608  if( d < min_d )
1609  {
1610  min_d = d;
1611  nearest = i;
1612  }
1613  }
1614 
1615  if( !aAllowInternalShapePoints )
1616  {
1617  //Snap to arc end points if the closest found segment is part of an arc segment
1618  if( nearest > 0 && nearest < PointCount() && IsArcSegment( nearest ) )
1619  {
1620  VECTOR2I ptToSegStart = CSegment( nearest ).A - aP;
1621  VECTOR2I ptToSegEnd = CSegment( nearest ).B - aP;
1622 
1623  if( ptToSegStart.EuclideanNorm() > ptToSegEnd.EuclideanNorm() )
1624  nearest++;
1625 
1626  // Is this the start or end of an arc? If so, return it directly
1627  if( IsArcStart( nearest ) || IsArcEnd( nearest ) )
1628  {
1629  return m_points[nearest];
1630  }
1631  else
1632  {
1633  const SHAPE_ARC& nearestArc = Arc( ArcIndex( nearest ) );
1634  VECTOR2I ptToArcStart = nearestArc.GetP0() - aP;
1635  VECTOR2I ptToArcEnd = nearestArc.GetP1() - aP;
1636 
1637  if( ptToArcStart.EuclideanNorm() > ptToArcEnd.EuclideanNorm() )
1638  return nearestArc.GetP1();
1639  else
1640  return nearestArc.GetP0();
1641  }
1642 
1643  }
1644  }
1645 
1646  return CSegment( nearest ).NearestPoint( aP );
1647 }
const SHAPE_ARC & Arc(size_t aArc) const
int Distance(const SEG &aSeg) const
Compute minimum Euclidean distance to segment aSeg.
Definition: seg.cpp:285
Define a general 2D-vector/point.
Definition: vector2d.h:61
int PointCount() const
Return the number of points (vertices) in this line chain.
ssize_t ArcIndex(size_t aSegment) const
Return the arc index for the given segment index.
bool IsArcStart(size_t aIndex) const
bool IsArcSegment(size_t aSegment) const
std::vector< VECTOR2I > m_points
array of vertices
const VECTOR2I & GetP0() const
Definition: shape_arc.h:111
const VECTOR2I NearestPoint(const VECTOR2I &aP) const
Compute a point on the segment (this) that is closest to point aP.
Definition: seg.cpp:227
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.
VECTOR2I A
Definition: seg.h:48
bool IsArcEnd(size_t aIndex) const
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
Definition: vector2d.h:293
const VECTOR2I & GetP1() const
Definition: shape_arc.h:112
VECTOR2I B
Definition: seg.h:49

References SEG::A, Arc(), ArcIndex(), SEG::B, CSegment(), SEG::Distance(), VECTOR2< T >::EuclideanNorm(), SHAPE_ARC::GetP0(), SHAPE_ARC::GetP1(), IsArcEnd(), IsArcSegment(), IsArcStart(), m_points, SEG::NearestPoint(), PointCount(), and SegmentCount().

Referenced by PCB_GRID_HELPER::computeAnchors(), PNS::MEANDER_PLACER_BASE::cutTunedLine(), CADSTAR_SCH_ARCHIVE_LOADER::loadBusses(), PNS::MoveDiagonal(), and PNS::DRAGGER::optimizeAndUpdateDraggedLine().

◆ NearestPoint() [2/2]

const VECTOR2I SHAPE_LINE_CHAIN::NearestPoint ( const SEG aSeg,
int &  dist 
) const

Find a point on the line chain that is closest to the line defined by the points of segment aSeg, also returns the distance.

Parameters
aSegis the segment defining the line.
distis the reference receiving the distance to the nearest point.
Returns
the nearest point.

Definition at line 1650 of file shape_line_chain.cpp.

1651 {
1652  int nearest = 0;
1653 
1654  dist = INT_MAX;
1655 
1656  for( int i = 0; i < PointCount(); i++ )
1657  {
1658  int d = aSeg.LineDistance( CPoint( i ) );
1659 
1660  if( d < dist )
1661  {
1662  dist = d;
1663  nearest = i;
1664  }
1665  }
1666 
1667  return CPoint( nearest );
1668 }
int LineDistance(const VECTOR2I &aP, bool aDetermineSide=false) const
Return the closest Euclidean distance between point aP and the line defined by the ends of segment (t...
Definition: seg.cpp:297
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 CPoint(), SEG::LineDistance(), and PointCount().

◆ NearestSegment()

int SHAPE_LINE_CHAIN::NearestSegment ( const VECTOR2I aP) const

Find the segment nearest the given point.

Parameters
aPis the point to compare with.
Returns
the index of the segment closest to the point.

Definition at line 1671 of file shape_line_chain.cpp.

1672 {
1673  int min_d = INT_MAX;
1674  int nearest = 0;
1675 
1676  for( int i = 0; i < SegmentCount(); i++ )
1677  {
1678  int d = CSegment( i ).Distance( aP );
1679 
1680  if( d < min_d )
1681  {
1682  min_d = d;
1683  nearest = i;
1684  }
1685  }
1686 
1687  return nearest;
1688 }
int Distance(const SEG &aSeg) const
Compute minimum Euclidean distance to segment aSeg.
Definition: seg.cpp:285
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 CSegment(), SEG::Distance(), and SegmentCount().

Referenced by SCH_SHEET_PIN::ConstrainOnEdge().

◆ NewFacet()

FACET * SHAPE::NewFacet ( )
inherited

Definition at line 695 of file wrlfacet.cpp.

696 {
697  FACET* fp = new FACET;
698  facets.push_back( fp );
699  return fp;
700 }
Definition: wrlfacet.h:42
std::list< FACET * > facets
Definition: wrlfacet.h:143

References SHAPE::facets.

Referenced by WRL1FACESET::TranslateToSG(), X3DIFACESET::TranslateToSG(), and WRL2FACESET::TranslateToSG().

◆ NextShape()

int SHAPE_LINE_CHAIN::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.

If aPointIndex is the start of a segment, this will be ( aPointIndex + 1 ). If aPointIndex is part of an arc, this will be the index of the start of the next shape after the arc, in other words, the last point of the arc.

Parameters
aPointIndexis a vertex in the chain.
aForwardsis true if the next shape is desired, false for previous shape.
Returns
the vertex index of the start of the next shape after aPoint's shape or -1 if the end was reached.

Definition at line 763 of file shape_line_chain.cpp.

764 {
765  if( aPointIndex < 0 )
766  aPointIndex += PointCount();
767 
768  int lastIndex = PointCount() - 1;
769 
770  // First or last point?
771  if( ( aForwards && aPointIndex == lastIndex ) ||
772  ( !aForwards && aPointIndex == 0 ) )
773  {
774  return -1; // we don't want to wrap around
775  }
776 
777  int delta = aForwards ? 1 : -1;
778 
779  if( m_shapes[aPointIndex] == SHAPES_ARE_PT )
780  return aPointIndex + delta;
781 
782  int arcStart = aPointIndex;
783 
784  // The second element should only get populated when the point is shared between two shapes.
785  // If not a shared point, then the index should always go on the first element.
786  assert( m_shapes[aPointIndex].first != SHAPE_IS_PT );
787 
788  // Start with the assumption the point is shared
789  auto arcIndex = [&]( int aIndex ) -> ssize_t
790  {
791  if( aForwards )
792  return ArcIndex( aIndex );
793  else
794  return reversedArcIndex( aIndex );
795  };
796 
797  ssize_t currentArcIdx = arcIndex( aPointIndex );
798 
799  // Now skip the rest of the arc
800  while( aPointIndex < lastIndex && aPointIndex >= 0 && arcIndex( aPointIndex ) == currentArcIdx )
801  aPointIndex += delta;
802 
803  if( aPointIndex == lastIndex )
804  {
805  if( !m_closed )
806  return -1;
807  else
808  return lastIndex; // Segment between last point and the start
809  }
810 
811  bool indexStillOnArc = alg::pair_contains( m_shapes[aPointIndex], currentArcIdx );
812 
813  // We want the last vertex of the arc if the initial point was the start of one
814  // Well-formed arcs should generate more than one point to travel above
815  if( aPointIndex - arcStart > 1 && !indexStillOnArc )
816  aPointIndex -= delta;
817 
818  return aPointIndex;
819 }
static const ssize_t SHAPE_IS_PT
int PointCount() const
Return the number of points (vertices) in this line chain.
ssize_t ArcIndex(size_t aSegment) const
Return the arc index for the given segment index.
bool m_closed
is the line chain closed?
std::vector< std::pair< ssize_t, ssize_t > > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
ssize_t reversedArcIndex(size_t aSegment) const
Return the arc index for the given segment index, looking backwards.
bool pair_contains(const std::pair< _Type, _Type > __pair, _Value __value)
Returns true if either of the elements in an std::pair contains the given value.
Definition: kicad_algo.h:112
constexpr int delta
static const std::pair< ssize_t, ssize_t > SHAPES_ARE_PT

References ArcIndex(), delta, m_closed, m_shapes, alg::pair_contains(), PointCount(), reversedArcIndex(), SHAPE_IS_PT, and SHAPES_ARE_PT.

Referenced by PNS::LINE::ClipVertexRange(), PrevShape(), and Slice().

◆ operator!=()

bool SHAPE_LINE_CHAIN::operator!= ( const SHAPE_LINE_CHAIN aRhs) const
inline

Definition at line 683 of file shape_line_chain.h.

684  {
685  if( PointCount() != aRhs.PointCount() )
686  return true;
687 
688  for( int i = 0; i < PointCount(); i++ )
689  {
690  if( CPoint( i ) != aRhs.CPoint( i ) )
691  return true;
692  }
693 
694  return false;
695  }
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 CPoint(), and PointCount().

◆ operator=()

SHAPE_LINE_CHAIN& SHAPE_LINE_CHAIN::operator= ( const SHAPE_LINE_CHAIN )
default

◆ Parse()

bool SHAPE_LINE_CHAIN::Parse ( std::stringstream &  aStream)
overridevirtual

Reimplemented from SHAPE.

Definition at line 1752 of file shape_line_chain.cpp.

1753 {
1754  size_t n_pts;
1755  size_t n_arcs;
1756 
1757  m_points.clear();
1758  aStream >> n_pts;
1759 
1760  // Rough sanity check, just make sure the loop bounds aren't absolutely outlandish
1761  if( n_pts > aStream.str().size() )
1762  return false;
1763 
1764  aStream >> m_closed;
1765  aStream >> n_arcs;
1766 
1767  if( n_arcs > aStream.str().size() )
1768  return false;
1769 
1770  for( size_t i = 0; i < n_pts; i++ )
1771  {
1772  int x, y;
1773  ssize_t ind;
1774  aStream >> x;
1775  aStream >> y;
1776  m_points.emplace_back( x, y );
1777 
1778  aStream >> ind;
1779  m_shapes.emplace_back( std::make_pair( ind, SHAPE_IS_PT ) );
1780  }
1781 
1782  for( size_t i = 0; i < n_arcs; i++ )
1783  {
1784  VECTOR2I p0, pc;
1785  double angle;
1786 
1787  aStream >> pc.x;
1788  aStream >> pc.y;
1789  aStream >> p0.x;
1790  aStream >> p0.y;
1791  aStream >> angle;
1792 
1793  m_arcs.emplace_back( pc, p0, angle );
1794  }
1795 
1796  return true;
1797 }
static const ssize_t SHAPE_IS_PT
Define a general 2D-vector/point.
Definition: vector2d.h:61
std::vector< SHAPE_ARC > m_arcs
bool m_closed
is the line chain closed?
std::vector< VECTOR2I > m_points
array of vertices
std::vector< std::pair< ssize_t, ssize_t > > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)

References PNS::angle(), m_arcs, m_closed, m_points, m_shapes, SHAPE_IS_PT, VECTOR2< T >::x, and VECTOR2< T >::y.

◆ PathLength()

int SHAPE_LINE_CHAIN::PathLength ( const VECTOR2I aP,
int  aIndex = -1 
) const

Compute the walk path length from the beginning of the line chain and the point aP belonging to our line.

Returns
the path length in Euclidean metric or -1 if aP does not belong to the line chain.

Definition at line 1305 of file shape_line_chain.cpp.

1306 {
1307  int sum = 0;
1308 
1309  for( int i = 0; i < SegmentCount(); i++ )
1310  {
1311  const SEG seg = CSegment( i );
1312  int d = seg.Distance( aP );
1313 
1314  bool indexMatch = true;
1315 
1316  if( aIndex >= 0 )
1317  {
1318  if( aIndex == SegmentCount() )
1319  {
1320  indexMatch = ( i == SegmentCount() - 1 );
1321  }
1322  else
1323  {
1324  indexMatch = ( i == aIndex );
1325  }
1326  }
1327 
1328  if( indexMatch )
1329  {
1330  sum += ( aP - seg.A ).EuclideanNorm();
1331  return sum;
1332  }
1333  else
1334  sum += seg.Length();
1335  }
1336 
1337  return -1;
1338 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:146
int Length() const
Return the length (this).
Definition: seg.h:350
int Distance(const SEG &aSeg) const
Compute minimum Euclidean distance to segment aSeg.
Definition: seg.cpp:285
int SegmentCount() const
Return the number of segments in this line chain.
Definition: seg.h:40
const SEG CSegment(int aIndex) const
Return a constant copy of the aIndex segment in the line chain.
VECTOR2I A
Definition: seg.h:48

References SEG::A, CSegment(), SEG::Distance(), EuclideanNorm(), SEG::Length(), and SegmentCount().

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

◆ PointAlong()

const VECTOR2I SHAPE_LINE_CHAIN::PointAlong ( int  aPathLength) const

Definition at line 1800 of file shape_line_chain.cpp.

1801 {
1802  int total = 0;
1803 
1804  if( aPathLength == 0 )
1805  return CPoint( 0 );
1806 
1807  for( int i = 0; i < SegmentCount(); i++ )
1808  {
1809  const SEG& s = CSegment( i );
1810  int l = s.Length();
1811 
1812  if( total + l >= aPathLength )
1813  {
1814  VECTOR2I d( s.B - s.A );
1815  return s.A + d.Resize( aPathLength - total );
1816  }
1817 
1818  total += l;
1819  }
1820 
1821  return CPoint( -1 );
1822 }
int Length() const
Return the length (this).
Definition: seg.h:350
Define a general 2D-vector/point.
Definition: vector2d.h:61
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
int SegmentCount() const
Return the number of segments in this line chain.
Definition: seg.h:40
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
Definition: vector2d.h:404
const SEG CSegment(int aIndex) const
Return a constant copy of the aIndex segment in the line chain.
VECTOR2I A
Definition: seg.h:48
VECTOR2I B
Definition: seg.h:49

References SEG::A, SEG::B, CPoint(), CSegment(), SEG::Length(), VECTOR2< T >::Resize(), and SegmentCount().

◆ PointCount()

int SHAPE_LINE_CHAIN::PointCount ( ) const
inline

Return the number of points (vertices) in this line chain.

Returns
the number of points.

Definition at line 282 of file shape_line_chain.h.

283  {
284  return m_points.size();
285  }
std::vector< VECTOR2I > m_points
array of vertices

References m_points.

Referenced by LABEL_MANAGER::Add(), POLYGON_GEOM_MANAGER::AddPoint(), SHAPE_LINE_CHAIN::POINT_INSIDE_TRACKER::AddPolyline(), BOARD_ADAPTER::addSolidAreasShapes(), TRIANGLE_DISPLAY_LIST::AddToMiddleContourns(), CN_ZONE_LAYER::AnchorCount(), Append(), PNS::LINE::AppendVia(), ArePolylineEndPointsNearCircle(), ArePolylineMidPointsNearCircle(), PNS::NODE::AssembleLine(), PNS::TOPOLOGY::AssembleTuningPath(), BOOST_AUTO_TEST_CASE(), BuildConvexHull(), PAD::BuildEffectivePolygon(), PAD::BuildEffectiveShapes(), PNS::LINE::ChangedArea(), PNS::KEEP_TOPOLOGY_CONSTRAINT::Check(), CheckClearance(), CN_VISITOR::checkZoneZoneConnection(), CLastPoint(), PNS::LINE::ClipVertexRange(), convertToClipper(), PNS::coupledBypass(), CPoint(), PolygonTriangulation::createList(), CreatePadsShapesSection(), PLACEFILE_GERBER_WRITER::CreatePlaceFile(), PNS::cursorDistMinimum(), POLYGON_GEOM_MANAGER::DeleteLastCorner(), DIALOG_PAD_PRIMITIVE_POLY_PROPS::doValidate(), PNS::LINE::dragCornerFree(), PNS::dragCornerInternal(), PNS::LINE::dragSegment45(), KIGFX::GERBVIEW_PAINTER::draw(), APERTURE_MACRO::DrawApertureMacroShape(), KIGFX::CAIRO_GAL_BASE::drawPoly(), KIGFX::OPENGL_GAL::DrawPolygon(), KIGFX::OPENGL_GAL::DrawPolyline(), KIGFX::PREVIEW::POLYGON_ITEM::drawPreviewShape(), EDA_SHAPE::DupPolyPointsList(), EXPORTER_PCB_VRML::ExportVrmlBoard(), EXPORTER_PCB_VRML::ExportVrmlPolygonSet(), DSN::SPECCTRA_DB::fillBOUNDARY(), AR_AUTOPLACER::fillMatrix(), Find(), PNS::LINE_PLACER::FixRoute(), GERBER_PLOTTER::FlashPadChamferRoundRect(), PSLIKE_PLOTTER::FlashPadCustom(), GERBER_PLOTTER::FlashPadCustom(), HPGL_PLOTTER::FlashPadCustom(), DXF_PLOTTER::FlashPadCustom(), PSLIKE_PLOTTER::FlashPadRoundRect(), GERBER_PLOTTER::FlashPadRoundRect(), HPGL_PLOTTER::FlashPadRoundRect(), DXF_PLOTTER::FlashPadRoundRect(), PCB_IO::format(), Format(), CADSTAR_PCB_ARCHIVE_LOADER::getLineChainFromShapes(), SHAPE_SIMPLE::GetPointCount(), GetPointCount(), CADSTAR_PCB_ARCHIVE_LOADER::getPolySetFromCadstarShape(), PNS::MOUSE_TRAIL_TRACER::GetPosture(), SHAPE_POLY_SET::GetRelativeIndices(), PNS::MOUSE_TRAIL_TRACER::GetTrailLeadVector(), PNS::LINE_PLACER::handlePullback(), PNS::LINE_PLACER::handleSelfIntersections(), DS_DRAW_ITEM_POLYPOLYGONS::HitTest(), PNS::HullIntersection(), Intersect(), IsArcEnd(), GEOM_TEST::IsOutlineValid(), POLYGON_GEOM_MANAGER::IsPolygonInProgress(), EDA_SHAPE::IsPolyShapeValid(), POLYGON_GEOM_MANAGER::IsSelfIntersecting(), FABMASTER::loadFootprints(), FABMASTER::loadGraphics(), FABMASTER::loadPolygon(), FABMASTER::loadZone(), DSN::SPECCTRA_DB::makeIMAGE(), DSN::SPECCTRA_DB::makePADSTACK(), CONVERT_TOOL::makePolysFromSegs(), PNS::LINE_PLACER::mergeHead(), PNS::OPTIMIZER::mergeObtuse(), NearestPoint(), POLYGON_GEOM_MANAGER::NewPointClosesOutline(), NextShape(), operator!=(), BOOST_TEST_PRINT_NAMESPACE_OPEN::print_log_value< SHAPE_LINE_CHAIN >::operator()(), PNS::LINE_PLACER::optimizeTailHeadTransition(), BITMAPCONV_INFO::outputOnePolygon(), ALTIUM_PCB::ParsePolygons6Data(), ALTIUM_PCB::ParseShapeBasedRegions6Data(), PlotDrawingSheet(), BRDITEMS_PLOTTER::PlotFilledAreas(), GERBER_PLOTTER::PlotGerberRegion(), GERBER_PLOTTER::PlotPoly(), PLOTTER::PlotPoly(), SHAPE_SIMPLE::PointCount(), PNS::LINE::PointCount(), PNS::pointInside2(), polygon_Convert(), GERBER_DRAW_ITEM::PrintGerberPoly(), DS_DRAW_ITEM_POLYPOLYGONS::PrintWsItem(), Remove(), RemoveShape(), Replace(), PNS::OPTIMIZER::runSmartPads(), SetPoint(), KIGFX::PREVIEW::POLYGON_ITEM::SetPoints(), PNS::shovedArea(), PNS::SHOVE::shoveLineFromLoneVia(), PNS::SHOVE::shoveLineToHullSet(), Simplify(), Slice(), splitArc(), POLYGON_GEOM_MANAGER::updateLeaderPoints(), PNS::LINE::Walkaround(), HYPERLYNX_EXPORTER::writeNetObjects(), GBR_TO_PCB_EXPORTER::writePcbPolygon(), and GBR_TO_PCB_EXPORTER::writePcbZoneItem().

◆ PointInside()

bool SHAPE_LINE_CHAIN_BASE::PointInside ( const VECTOR2I aPt,
int  aAccuracy = 0,
bool  aUseBBoxCache = false 
) const
inherited

Check if point aP lies inside a polygon (any type) defined by the line chain.

For closed shapes only.

Parameters
aPtpoint to check
aUseBBoxCachegives better performance if the bounding box caches have been generated.
Returns
true if the point is inside the shape (edge is not treated as being inside).

Definition at line 1341 of file shape_line_chain.cpp.

1343 {
1344  /*
1345  * Don't check the bounding box unless it's cached. Building it is about the same speed as
1346  * the rigorous test below and so just slows things down by doing potentially two tests.
1347  */
1348  if( aUseBBoxCache && GetCachedBBox() && !GetCachedBBox()->Contains( aPt ) )
1349  return false;
1350 
1351  if( !IsClosed() || GetPointCount() < 3 )
1352  return false;
1353 
1354  bool inside = false;
1355 
1356  /*
1357  * To check for interior points, we draw a line in the positive x direction from
1358  * the point. If it intersects an even number of segments, the point is outside the
1359  * line chain (it had to first enter and then exit). Otherwise, it is inside the chain.
1360  *
1361  * Note: slope might be denormal here in the case of a horizontal line but we require our
1362  * y to move from above to below the point (or vice versa)
1363  *
1364  * Note: we open-code CPoint() here so that we don't end up calculating the size of the
1365  * vector number-of-points times. This has a non-trivial impact on zone fill times.
1366  */
1367  int pointCount = GetPointCount();
1368 
1369  for( int i = 0; i < pointCount; )
1370  {
1371  const auto p1 = GetPoint( i++ );
1372  const auto p2 = GetPoint( i == pointCount ? 0 : i );
1373  const auto diff = p2 - p1;
1374 
1375  if( diff.y != 0 )
1376  {
1377  const int d = rescale( diff.x, ( aPt.y - p1.y ), diff.y );
1378 
1379  if( ( ( p1.y > aPt.y ) != ( p2.y > aPt.y ) ) && ( aPt.x - p1.x < d ) )
1380  inside = !inside;
1381  }
1382  }
1383 
1384  // If accuracy is <= 1 (nm) then we skip the accuracy test for performance. Otherwise
1385  // we use "OnEdge(accuracy)" as a proxy for "Inside(accuracy)".
1386  if( aAccuracy <= 1 )
1387  return inside;
1388  else
1389  return inside || PointOnEdge( aPt, aAccuracy );
1390 }
virtual BOX2I * GetCachedBBox() const
Definition: shape.h:312
virtual bool IsClosed() const =0
virtual size_t GetPointCount() const =0
bool PointOnEdge(const VECTOR2I &aP, int aAccuracy=0) const
Check if point aP lies on an edge or vertex of the line chain.
T rescale(T aNumerator, T aValue, T aDenominator)
Scale a number (value) by rational (numerator/denominator).
Definition: util.h:98
virtual const VECTOR2I GetPoint(int aIndex) const =0

References SHAPE_LINE_CHAIN_BASE::GetCachedBBox(), SHAPE_LINE_CHAIN_BASE::GetPoint(), SHAPE_LINE_CHAIN_BASE::GetPointCount(), SHAPE_LINE_CHAIN_BASE::IsClosed(), SHAPE_LINE_CHAIN_BASE::PointOnEdge(), rescale(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by Collide(), SHAPE_LINE_CHAIN_BASE::Collide(), POLY_GRID_PARTITION::containsPoint(), SHAPE_POLY_SET::containsSingle(), ZONE::HitTestCutout(), MARKER_BASE::HitTestMarker(), SHAPE_LINE_CHAIN_BASE::SquaredDistance(), and PNS::LINE::Walkaround().

◆ PointOnEdge()

bool SHAPE_LINE_CHAIN_BASE::PointOnEdge ( const VECTOR2I aP,
int  aAccuracy = 0 
) const
inherited

Check if point aP lies on an edge or vertex of the line chain.

Parameters
aPpoint to check
Returns
true if the point lies on the edge.

Definition at line 1393 of file shape_line_chain.cpp.

1394 {
1395  return EdgeContainingPoint( aPt, aAccuracy ) >= 0;
1396 }
int EdgeContainingPoint(const VECTOR2I &aP, int aAccuracy=0) const
Check if point aP lies on an edge or vertex of the line chain.

References SHAPE_LINE_CHAIN_BASE::EdgeContainingPoint().

Referenced by FABMASTER::loadZones(), SHAPE_LINE_CHAIN_BASE::PointInside(), and PNS::LINE::Walkaround().

◆ PrevShape()

int SHAPE_LINE_CHAIN::PrevShape ( int  aPointIndex) const
inline

Definition at line 338 of file shape_line_chain.h.

339  {
340  return NextShape( aPointIndex, false );
341  }
int NextShape(int aPointIndex, bool aForwards=true) const
Return the vertex index of the next shape in the chain, or -1 if aPointIndex is the last shape.

References NextShape().

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

◆ Remove() [1/2]

void SHAPE_LINE_CHAIN::Remove ( int  aStartIndex,
int  aEndIndex 
)

Remove the range of points [start_index, end_index] from the line chain.

Parameters
aStartIndexis the start of the point range to be replaced (inclusive).
aEndIndexis the end of the point range to be replaced (inclusive).

Definition at line 539 of file shape_line_chain.cpp.

540 {
541  assert( m_shapes.size() == m_points.size() );
542 
543  if( aEndIndex < 0 )
544  aEndIndex += PointCount();
545 
546  if( aStartIndex < 0 )
547  aStartIndex += PointCount();
548 
549  if( aStartIndex >= PointCount() )
550  return;
551 
552  aEndIndex = std::min( aEndIndex, PointCount() - 1 );
553 
554  // Split arcs at start index and end just after the end index
555  if( IsPtOnArc( aStartIndex ) )
556  splitArc( aStartIndex );
557 
558  size_t nextIndex = static_cast<size_t>( aEndIndex ) + 1;
559 
560  if( IsPtOnArc( nextIndex ) )
561  splitArc( nextIndex );
562 
563  std::set<size_t> extra_arcs;
564  auto logArcIdxRemoval = [&]( ssize_t& aShapeIndex )
565  {
566  if( aShapeIndex != SHAPE_IS_PT )
567  extra_arcs.insert( aShapeIndex );
568  };
569 
570  // Remove any overlapping arcs in the point range
571  for( int i = aStartIndex; i <= aEndIndex; i++ )
572  {
573  if( IsSharedPt( i ) )
574  {
575  if( i == aStartIndex )
576  {
577  logArcIdxRemoval( m_shapes[i].second ); // Only remove the arc on the second index
578 
579  // Ensure that m_shapes has been built correctly.
580  assert( i < aEndIndex || m_shapes[i + 1].first == m_shapes[i].second );
581 
582  continue;
583  }
584  else if( i == aEndIndex )
585  {
586  logArcIdxRemoval( m_shapes[i].first ); // Only remove the arc on the first index
587 
588  // Ensure that m_shapes has been built correctly.
589  assert( i > aStartIndex || IsSharedPt( i - 1 )
590  ? m_shapes[i - 1].second == m_shapes[i].first
591  : m_shapes[i - 1].first == m_shapes[i].first );
592  continue;
593  }
594  }
595 
596  alg::run_on_pair( m_shapes[i], logArcIdxRemoval );
597  }
598 
599  for( auto arc : extra_arcs )
600  convertArc( arc );
601 
602  m_shapes.erase( m_shapes.begin() + aStartIndex, m_shapes.begin() + aEndIndex + 1 );
603  m_points.erase( m_points.begin() + aStartIndex, m_points.begin() + aEndIndex + 1 );
604  assert( m_shapes.size() == m_points.size() );
605 }
bool IsSharedPt(size_t aIndex) const
Test if a point is shared between multiple shapes.
static const ssize_t SHAPE_IS_PT
void convertArc(ssize_t aArcIndex)
Convert an arc to only a point chain by removing the arc and references.
int PointCount() const
Return the number of points (vertices) in this line chain.
void splitArc(ssize_t aPtIndex, bool aCoincident=false)
Splits an arc into two arcs at aPtIndex.
std::vector< VECTOR2I > m_points
array of vertices
void run_on_pair(std::pair< _Type, _Type > &__pair, _Function __f)
Apply a function to the first and second element of a std::pair.
Definition: kicad_algo.h:44
bool IsPtOnArc(size_t aPtIndex) const
std::vector< std::pair< ssize_t, ssize_t > > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...

References convertArc(), IsPtOnArc(), IsSharedPt(), m_points, m_shapes, PointCount(), alg::run_on_pair(), SHAPE_IS_PT, and splitArc().

Referenced by POLYGON_GEOM_MANAGER::AddPoint(), PNS::TOPOLOGY::AssembleTuningPath(), PNS::LINE_PLACER::buildInitialLine(), PNS::LINE::ClipToNearestObstacle(), POLYGON_GEOM_MANAGER::DeleteLastCorner(), EDA_SHAPE::endEdit(), PNS::DIFF_PAIR_PLACER::FixRoute(), PNS::LINE_PLACER::handleSelfIntersections(), PNS::OPTIMIZER::mergeColinear(), PNS::LINE_PLACER::mergeHead(), PNS::LINE_PLACER::reduceTail(), Remove(), EE_POINT_EDITOR::removeCorner(), RemoveShape(), and Replace().

◆ Remove() [2/2]

void SHAPE_LINE_CHAIN::Remove ( int  aIndex)
inline

Remove the aIndex-th point from the line chain.

Parameters
aIndexis the index of the point to be removed.

Definition at line 531 of file shape_line_chain.h.

532  {
533  Remove( aIndex, aIndex );
534  }
void Remove(int aStartIndex, int aEndIndex)
Remove the range of points [start_index, end_index] from the line chain.

References Remove().

◆ RemoveShape()

void SHAPE_LINE_CHAIN::RemoveShape ( int  aPointIndex)

Remove the shape at the given index from the line chain.

If the given index is inside an arc, the entire arc will be removed. Otherwise this is equivalent to Remove( aPointIndex ).

Parameters
aPointIndexis the index of the point to remove.

Definition at line 840 of file shape_line_chain.cpp.

841 {
842  if( aPointIndex < 0 )
843  aPointIndex += PointCount();
844 
845  if( m_shapes[aPointIndex] == SHAPES_ARE_PT )
846  {
847  Remove( aPointIndex );
848  return;
849  }
850 
851  //@todo should this be replaced to use NextShape() / PrevShape()?
852  int start = aPointIndex;
853  int end = aPointIndex;
854  int arcIdx = ArcIndex( aPointIndex );
855 
856  if( !IsSharedPt( aPointIndex ) )
857  {
858  // aPointIndex is not a shared point, so iterate backwards to find the start of the arc
859  while( start >= 0 && m_shapes[start].first == arcIdx )
860  start--;
861 
862  // Check if the previous point might be a shared point and decrement 'start' if so
863  if( start >= 1 && m_shapes[static_cast<ssize_t>( start ) - 1].second == arcIdx )
864  start--;
865  }
866 
867  // For the end point we only need to check the first element in m_shapes (the second one is only
868  // populated if there is an arc after the current one sharing the same point).
869  while( end < static_cast<int>( m_shapes.size() ) - 1 && m_shapes[end].first == arcIdx )
870  end++;
871 
872  Remove( start, end );
873 }
bool IsSharedPt(size_t aIndex) const
Test if a point is shared between multiple shapes.
int PointCount() const
Return the number of points (vertices) in this line chain.
ssize_t ArcIndex(size_t aSegment) const
Return the arc index for the given segment index.
void Remove(int aStartIndex, int aEndIndex)
Remove the range of points [start_index, end_index] from the line chain.
std::vector< std::pair< ssize_t, ssize_t > > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
static const std::pair< ssize_t, ssize_t > SHAPES_ARE_PT

References ArcIndex(), IsSharedPt(), m_shapes, PointCount(), Remove(), and SHAPES_ARE_PT.

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

◆ Replace() [1/2]

void SHAPE_LINE_CHAIN::Replace ( int  aStartIndex,
int  aEndIndex,
const VECTOR2I aP 
)

Replace points with indices in range [start_index, end_index] with a single point aP.

Parameters
aStartIndexis the start of the point range to be replaced (inclusive).
aEndIndexis the end of the point range to be replaced (inclusive).
aPis the replacement point.

Definition at line 461 of file shape_line_chain.cpp.

462 {
463  Remove( aStartIndex, aEndIndex );
464  Insert( aStartIndex, aP );
465  assert( m_shapes.size() == m_points.size() );
466 }
void Insert(size_t aVertex, const VECTOR2I &aP)
std::vector< VECTOR2I > m_points
array of vertices
void Remove(int aStartIndex, int aEndIndex)
Remove the range of points [start_index, end_index] from the line chain.
std::vector< std::pair< ssize_t, ssize_t > > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...

References Insert(), m_points, m_shapes, and Remove().

Referenced by PNS::TOPOLOGY::AssembleTuningPath(), BOOST_AUTO_TEST_CASE(), PNS::CORNER_COUNT_LIMIT_CONSTRAINT::Check(), PNS::coupledBypass(), PNS::LINE::dragSegment45(), CADSTAR_SCH_ARCHIVE_LOADER::loadNets(), PNS::OPTIMIZER::mergeDpStep(), PNS::OPTIMIZER::mergeObtuse(), PNS::LINE_PLACER::optimizeTailHeadTransition(), and PNS::Tighten().

◆ Replace() [2/2]

void SHAPE_LINE_CHAIN::Replace ( int  aStartIndex,
int  aEndIndex,
const SHAPE_LINE_CHAIN aLine 
)

Replace points with indices in range [start_index, end_index] with the points from line chain aLine.

Parameters
aStartIndexis the start of the point range to be replaced (inclusive).
aEndIndexis the end of the point range to be replaced (inclusive).
aLineis the replacement line chain.

Definition at line 469 of file shape_line_chain.cpp.

470 {
471  if( aEndIndex < 0 )
472  aEndIndex += PointCount();
473 
474  if( aStartIndex < 0 )
475  aStartIndex += PointCount();
476 
477  // We only process lines in order in this house
478  wxASSERT( aStartIndex <= aEndIndex );
479  wxASSERT( aEndIndex < m_points.size() );
480 
481  SHAPE_LINE_CHAIN newLine = aLine;
482 
483  // Zero points to add?
484  if( newLine.PointCount() == 0 )
485  {
486  Remove( aStartIndex, aEndIndex );
487  return;
488  }
489 
490  // Remove coincident points in the new line
491  if( newLine.m_points.front() == m_points[aStartIndex] )
492  {
493  aStartIndex++;
494  newLine.Remove( 0 );
495 
496  // Zero points to add?
497  if( newLine.PointCount() == 0 )
498  {
499  Remove( aStartIndex, aEndIndex );
500  return;
501  }
502  }
503 
504  if( newLine.m_points.back() == m_points[aEndIndex] && aEndIndex > 0 )
505  {
506  aEndIndex--;
507  newLine.Remove( -1 );
508  }
509 
510  Remove( aStartIndex, aEndIndex );
511 
512  // Zero points to add?
513  if( newLine.PointCount() == 0 )
514  return;
515 
516  // The total new arcs index is added to the new arc indices
517  size_t prev_arc_count = m_arcs.size();
518  std::vector<std::pair<ssize_t, ssize_t>> new_shapes = newLine.m_shapes;
519 
520  for( std::pair<ssize_t, ssize_t>& shape_pair : new_shapes )
521  {
522  alg::run_on_pair( shape_pair,
523  [&]( ssize_t& aShape )
524  {
525  if( aShape != SHAPE_IS_PT )
526  aShape += prev_arc_count;
527  } );
528  }
529 
530  m_shapes.insert( m_shapes.begin() + aStartIndex, new_shapes.begin(), new_shapes.end() );
531  m_points.insert( m_points.begin() + aStartIndex, newLine.m_points.begin(),
532  newLine.m_points.end() );
533  m_arcs.insert( m_arcs.end(), newLine.m_arcs.begin(), newLine.m_arcs.end() );
534 
535  assert( m_shapes.size() == m_points.size() );
536 }
static const ssize_t SHAPE_IS_PT
int PointCount() const
Return the number of points (vertices) in this line chain.
std::vector< SHAPE_ARC > m_arcs
std::vector< VECTOR2I > m_points
array of vertices
void run_on_pair(std::pair< _Type, _Type > &__pair, _Function __f)
Apply a function to the first and second element of a std::pair.
Definition: kicad_algo.h:44
void Remove(int aStartIndex, int aEndIndex)
Remove the range of points [start_index, end_index] from the line chain.
std::vector< std::pair< ssize_t, ssize_t > > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
Represent a polyline (an zero-thickness chain of connected line segments).

References m_arcs, m_points, m_shapes, PointCount(), Remove(), alg::run_on_pair(), and SHAPE_IS_PT.

◆ Reverse()

const SHAPE_LINE_CHAIN SHAPE_LINE_CHAIN::Reverse ( ) const

Reverse point order in the line chain.

Returns
line chain with reversed point order (original A-B-C-D: returned D-C-B-A).

Definition at line 371 of file shape_line_chain.cpp.

372 {
373  SHAPE_LINE_CHAIN a( *this );
374 
375  reverse( a.m_points.begin(), a.m_points.end() );
376  reverse( a.m_shapes.begin(), a.m_shapes.end() );
377  reverse( a.m_arcs.begin(), a.m_arcs.end() );
378 
379  for( auto& sh : a.m_shapes )
380  {
381  if( sh != SHAPES_ARE_PT )
382  {
383  alg::run_on_pair( sh,
384  [&]( ssize_t& aShapeIndex )
385  {
386  if( aShapeIndex != SHAPE_IS_PT )
387  aShapeIndex = a.m_arcs.size() - aShapeIndex - 1;
388  } );
389 
390  if( sh.second != SHAPE_IS_PT )
391  {
392  // If the second element is populated, the first one should be too!
393  assert( sh.first != SHAPE_IS_PT );
394 
395  // Switch round first and second in shared points, as part of reversing the chain
396  std::swap( sh.first, sh.second );
397  }
398  }
399  }
400 
401  for( SHAPE_ARC& arc : a.m_arcs )
402  arc.Reverse();
403 
404  a.m_closed = m_closed;
405 
406  return a;
407 }
static const ssize_t SHAPE_IS_PT
bool m_closed
is the line chain closed?
void run_on_pair(std::pair< _Type, _Type > &__pair, _Function __f)
Apply a function to the first and second element of a std::pair.
Definition: kicad_algo.h:44
void Reverse()
Definition: shape_arc.cpp:618
Represent a polyline (an zero-thickness chain of connected line segments).
static const std::pair< ssize_t, ssize_t > SHAPES_ARE_PT

References m_arcs, m_closed, m_points, m_shapes, SHAPE_ARC::Reverse(), alg::run_on_pair(), SHAPE_IS_PT, and SHAPES_ARE_PT.

Referenced by PNS::ArcHull(), PNS::KEEP_TOPOLOGY_CONSTRAINT::Check(), PNS::SHOVE::checkShoveDirection(), convertToClipper(), PNS::coupledBypass(), PNS::MEANDER_PLACER_BASE::cutTunedLine(), PNS::LINE::dragCorner45(), PNS::MOUSE_TRAIL_TRACER::GetPosture(), CADSTAR_SCH_ARCHIVE_LOADER::loadNets(), PNS::DP_GATEWAY::Reverse(), PNS::LINE::Reverse(), PNS::SegmentHull(), PNS::OPTIMIZER::smartPadsSingle(), and PNS::LINE::Walkaround().

◆ reversedArcIndex()

ssize_t SHAPE_LINE_CHAIN::reversedArcIndex ( size_t  aSegment) const
inlineprotected

Return the arc index for the given segment index, looking backwards.

Definition at line 865 of file shape_line_chain.h.

866  {
867  if( IsSharedPt( aSegment ) )
868  return m_shapes[aSegment].first;
869  else
870  return m_shapes[aSegment].second;
871  }
bool IsSharedPt(size_t aIndex) const
Test if a point is shared between multiple shapes.
std::vector< std::pair< ssize_t, ssize_t > > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...

References IsSharedPt(), and m_shapes.

Referenced by NextShape().

◆ Rotate()

void SHAPE_LINE_CHAIN::Rotate ( double  aAngle,
const VECTOR2I aCenter = VECTOR2I( 0, 0 ) 
)
overridevirtual

Rotate all vertices by a given angle.

Parameters
aCenteris the rotation center.
aAngleis the rotation angle in radians.

Implements SHAPE.

Definition at line 303 of file shape_line_chain.cpp.

304 {
305  for( auto& pt : m_points )
306  {
307  pt -= aCenter;
308  pt = pt.Rotate( aAngle );
309  pt += aCenter;
310  }
311 
312  for( auto& arc : m_arcs )
313  arc.Rotate( aAngle, aCenter );
314 }
std::vector< SHAPE_ARC > m_arcs
std::vector< VECTOR2I > m_points
array of vertices
VECTOR2< T > Rotate(double aAngle) const
Rotate the vector by a given angle.
Definition: vector2d.h:371

References m_arcs, m_points, and VECTOR2< T >::Rotate().

Referenced by PAD::BuildEffectiveShapes(), ZONE_FILLER::buildThermalSpokes(), PLACEFILE_GERBER_WRITER::CreatePlaceFile(), EDA_SHAPE::hitTest(), EDA_SHAPE::MakeEffectiveShapes(), and TransformArcToPolygon().

◆ Segment()

SEG SHAPE_LINE_CHAIN::Segment ( int  aIndex)
inline

Return a copy of the aIndex-th segment in the line chain.

Parameters
aIndexis the index of the segment in the line chain. Negative values are counted from the end (i.e. -1 means the last segment in the line chain).
Returns
a segment at the aIndex in the line chain.

Definition at line 294 of file shape_line_chain.h.

295  {
296  if( aIndex < 0 )
297  aIndex += SegmentCount();
298 
299  if( aIndex == (int)( m_points.size() - 1 ) && m_closed )
300  return SEG( m_points[aIndex], m_points[0], aIndex );
301  else
302  return SEG( m_points[aIndex], m_points[aIndex + 1], aIndex );
303  }
bool m_closed
is the line chain closed?
std::vector< VECTOR2I > m_points
array of vertices
int SegmentCount() const
Return the number of segments in this line chain.
Definition: seg.h:40

References m_closed, m_points, and SegmentCount().

Referenced by POLY_GRID_PARTITION::build(), BuildFootprintPolygonOutlines(), POLY_GRID_PARTITION::checkClearance(), PNS::DIFF_PAIR::CoupledSegmentPairs(), BOARD_ADAPTER::createPadWithClearance(), KIGFX::PCB_PAINTER::draw(), findEndSegments(), CADSTAR_SCH_ARCHIVE_LOADER::loadShapeVertices(), EDA_SHAPE::MakeEffectiveShapes(), and unfracture().

◆ SegmentCount()

int SHAPE_LINE_CHAIN::SegmentCount ( ) const
inline

Return the number of segments in this line chain.

Returns
the number of segments.

Definition at line 259 of file shape_line_chain.h.

260  {
261  int c = m_points.size() - 1;
262  if( m_closed )
263  c++;
264 
265  return std::max( 0, c );
266  }
bool m_closed
is the line chain closed?
std::vector< VECTOR2I > m_points
array of vertices

References m_closed, and m_points.

Referenced by PNS::MOUSE_TRAIL_TRACER::AddTrailPoint(), PNS::NODE::AssembleLine(), POLY_GRID_PARTITION::build(), BuildFootprintPolygonOutlines(), PNS::LINE_PLACER::buildInitialLine(), PNS::PRESERVE_VERTEX_CONSTRAINT::Check(), CheckClearance(), PNS::NODE::CheckColliding(), PNS::DIFF_PAIR::CheckConnectionAngle(), PNS::checkGap(), PNS::MEANDERED_LINE::CheckSelfIntersections(), PNS::closestProjectedPoint(), PCB_GRID_HELPER::computeAnchors(), PNS::COST_ESTIMATOR::CornerCost(), PNS::LINE::CountCorners(), PNS::DIFF_PAIR::CoupledLength(), PNS::DIFF_PAIR::CoupledSegmentPairs(), BOARD_ADAPTER::createPadWithClearance(), CSegment(), PNS::cursorDistMinimum(), PNS::LINE::dragCorner45(), PNS::dragCornerInternal(), PNS::LINE::dragSegment45(), KIGFX::PCB_PAINTER::draw(), KIGFX::OPENGL_GAL::DrawPolygon(), PNS::DIFF_PAIR::Empty(), PNS::findCoupledVertices(), findEndSegments(), FindSegment(), PNS::DIFF_PAIR_PLACER::FixRoute(), PNS::LINE_PLACER::FixRoute(), EDA_SHAPE::GetLength(), SHAPE_SIMPLE::GetSegmentCount(), GetSegmentCount(), PNS::LINE_PLACER::handlePullback(), PNS::DP_MEANDER_PLACER::HasPlacedAnything(), PNS::DIFF_PAIR_PLACER::HasPlacedAnything(), PNS::HullIntersection(), Intersect(), PNS::LINE::Is45Degree(), Length(), CADSTAR_SCH_ARCHIVE_LOADER::loadShapeVertices(), EDA_SHAPE::MakeEffectiveShapes(), PNS::OPTIMIZER::mergeColinear(), PNS::OPTIMIZER::mergeDpSegments(), PNS::OPTIMIZER::mergeDpStep(), PNS::OPTIMIZER::mergeFull(), PNS::OPTIMIZER::mergeObtuse(), PNS::OPTIMIZER::mergeStep(), PNS::NODE::NearestObstacle(), NearestPoint(), NearestSegment(), PathLength(), PointAlong(), PNS::pointInside2(), KIGFX::VIEW_OVERLAY::Polyline(), PNS::LINE_PLACER::reduceTail(), Segment(), PNS::LINE::SegmentCount(), SelfIntersecting(), PNS::OPTIMIZER::smartPadsSingle(), PNS::LINE::snapDraggedCorner(), PNS::LINE::snapToNeighbourSegments(), Split(), SHAPE_POLY_SET::unfractureSingle(), POLYGON_GEOM_MANAGER::updateLeaderPoints(), PNS::LINE::Walkaround(), and HYPERLYNX_EXPORTER::writeBoardInfo().

◆ SelfIntersecting()

const OPT< SHAPE_LINE_CHAIN::INTERSECTION > SHAPE_LINE_CHAIN::SelfIntersecting ( ) const

Check if the line chain is self-intersecting.

Returns
(optional) first found self-intersection point.

Definition at line 1448 of file shape_line_chain.cpp.

1449 {
1450  for( int s1 = 0; s1 < SegmentCount(); s1++ )
1451  {
1452  for( int s2 = s1 + 1; s2 < SegmentCount(); s2++ )
1453  {
1454  const VECTOR2I s2a = CSegment( s2 ).A, s2b = CSegment( s2 ).B;
1455 
1456  if( s1 + 1 != s2 && CSegment( s1 ).Contains( s2a ) )
1457  {
1458  INTERSECTION is;
1459  is.index_our = s1;
1460  is.index_their = s2;
1461  is.p = s2a;
1462  return is;
1463  }
1464  else if( CSegment( s1 ).Contains( s2b ) &&
1465  // for closed polylines, the ending point of the
1466  // last segment == starting point of the first segment
1467  // this is a normal case, not self intersecting case
1468  !( IsClosed() && s1 == 0 && s2 == SegmentCount()-1 ) )
1469  {
1470  INTERSECTION is;
1471  is.index_our = s1;
1472  is.index_their = s2;
1473  is.p = s2b;
1474  return is;
1475  }
1476  else
1477  {
1478  OPT_VECTOR2I p = CSegment( s1 ).Intersect( CSegment( s2 ), true );
1479 
1480  if( p )
1481  {
1482  INTERSECTION is;
1483  is.index_our = s1;
1484  is.index_their = s2;
1485  is.p = *p;
1486  return is;
1487  }
1488  }
1489  }
1490  }
1491 
1493 }
OPT_VECTOR2I Intersect(const SEG &aSeg, bool aIgnoreEndpoints=false, bool aLines=false) const
Compute intersection point of segment (this) with segment aSeg.
Definition: seg.cpp:154
Define a general 2D-vector/point.
Definition: vector2d.h:61
bool IsClosed() const override
OPT< VECTOR2I > OPT_VECTOR2I
Definition: seg.h:38
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.
VECTOR2I A
Definition: seg.h:48
boost::optional< T > OPT
Definition: optional.h:7
VECTOR2I B
Definition: seg.h:49

References SEG::A, SEG::B, CSegment(), SHAPE_LINE_CHAIN::INTERSECTION::index_our, SHAPE_LINE_CHAIN::INTERSECTION::index_their, SEG::Intersect(), IsClosed(), SHAPE_LINE_CHAIN::INTERSECTION::p, and SegmentCount().

Referenced by PNS::DIFF_PAIR::BuildInitial(), and DIALOG_PAD_PRIMITIVE_POLY_PROPS::doValidate().

◆ SetClosed()

void SHAPE_LINE_CHAIN::SetClosed ( bool  aClosed)
inline

Mark the line chain as closed (i.e.

with a segment connecting the last point with the first point).

Parameters
aClosedwhether the line chain is to be closed or not.

Definition at line 221 of file shape_line_chain.h.

222  {
223  m_closed = aClosed;
224  }
bool m_closed
is the line chain closed?

References m_closed.

Referenced by ZONE_FILLER::addHatchFillTypeOnZone(), ZONE::AddPolygon(), PNS::ArcHull(), EDA_SHAPE::beginEdit(), POLY_GRID_PARTITION::build(), buildBoardBoundingBoxPoly(), BuildFootprintPolygonOutlines(), KI_TEST::BuildRectChain(), ZONE_FILLER::buildThermalSpokes(), SHAPE_POLY_SET::chamferFilletPolygon(), PNS::KEEP_TOPOLOGY_CONSTRAINT::Check(), CN_ZONE_LAYER::CN_ZONE_LAYER(), KI_TEST::CommonTestData::CommonTestData(), PCB_GRID_HELPER::computeAnchors(), ConvertPolygonToBlocks(), PNS::ConvexHull(), CONVERT_TOOL::CreateLines(), PLACEFILE_GERBER_WRITER::CreatePlaceFile(), KIGFX::GERBVIEW_PAINTER::draw(), EDA_SHAPE::endEdit(), SHAPE_POLY_SET::fractureSingle(), CADSTAR_PCB_ARCHIVE_LOADER::getLineChainFromShapes(), PNS::MOUSE_TRAIL_TRACER::GetPosture(), HelperShapeLineChainFromAltiumVertices(), IteratorFixture::IteratorFixture(), CONVERT_TOOL::makePolysFromRects(), CONVERT_TOOL::makePolysFromSegs(), GEOM_TEST::MakeSquarePolyLine(), SHAPE_POLY_SET::NewHole(), SHAPE_POLY_SET::NewOutline(), PNS::OctagonalHull(), SHAPE_RECT::Outline(), EAGLE_PLUGIN::packagePolygon(), SHAPE_POLY_SET::Parse(), ALTIUM_PCB::ParseRegions6Data(), PCB_PARSER::parseZONE(), BRDITEMS_PLOTTER::PlotFootprintGraphicItem(), polygonArea(), RENDER_3D_LEGACY::reload(), PNS::SegmentHull(), SHAPE_POLY_SET::SHAPE_POLY_SET(), SHAPE_SIMPLE::SHAPE_SIMPLE(), MARKER_BASE::ShapeToPolygon(), TestConcaveSquareFillet(), TransformCircleToPolygon(), unfracture(), and SHAPE_POLY_SET::unfractureSingle().

◆ SetPoint()

void SHAPE_LINE_CHAIN::SetPoint ( int  aIndex,
const VECTOR2I aPos 
)

Move a point to a specific location.

Parameters
aIndexis the index of the point to move.
aPosis the new absolute location of the point.

Definition at line 822 of file shape_line_chain.cpp.

823 {
824  if( aIndex < 0 )
825  aIndex += PointCount();
826  else if( aIndex >= PointCount() )
827  aIndex -= PointCount();
828 
829  m_points[aIndex] = aPos;
830 
831  alg::run_on_pair( m_shapes[aIndex],
832  [&]( ssize_t& aIdx )
833  {
834  if( aIdx != SHAPE_IS_PT )
835  convertArc( aIdx );
836  } );
837 }
static const ssize_t SHAPE_IS_PT
void convertArc(ssize_t aArcIndex)
Convert an arc to only a point chain by removing the arc and references.
int PointCount() const
Return the number of points (vertices) in this line chain.
std::vector< VECTOR2I > m_points
array of vertices
void run_on_pair(std::pair< _Type, _Type > &__pair, _Function __f)
Apply a function to the first and second element of a std::pair.
Definition: kicad_algo.h:44
std::vector< std::pair< ssize_t, ssize_t > > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...

References convertArc(), m_points, m_shapes, PointCount(), alg::run_on_pair(), and SHAPE_IS_PT.

Referenced by PNS::LINE_PLACER::buildInitialLine(), EDA_SHAPE::calcEdit(), PNS::LINE::dragCornerFree(), and CADSTAR_SCH_ARCHIVE_LOADER::getScaledLibPart().

◆ SetWidth()

void SHAPE_LINE_CHAIN::SetWidth ( int  aWidth)
inline

Set the width of all segments in the chain.

Parameters
aWidthis the width in internal units.

Definition at line 239 of file shape_line_chain.h.

240  {
241  m_width = aWidth;
242  }
int m_width
Width of the segments (for BBox calculations in RTree) TODO Adjust usage of SHAPE_LINE_CHAIN to accou...

References m_width.

Referenced by BOOST_AUTO_TEST_CASE(), ROUTER_PREVIEW_ITEM::Line(), CONVERT_TOOL::makePolysFromRects(), CONVERT_TOOL::makePolysFromSegs(), PNS::LINE::SetShape(), PNS::LINE::SetWidth(), and PNS::DIFF_PAIR::SetWidth().

◆ ShapeCount()

int SHAPE_LINE_CHAIN::ShapeCount ( ) const

Return the number of shapes (line segments or arcs) in this line chain.

This is kind of like SegmentCount() but will only count arcs as 1 segment.

Returns
ArcCount() + the number of non-arc segments.

Definition at line 713 of file shape_line_chain.cpp.

714 {
715  if( m_points.empty() )
716  return 0;
717 
718  int numPoints = static_cast<int>( m_shapes.size() );
719  int numShapes = 0;
720  int arcIdx = -1;
721 
722  for( int i = 0; i < m_points.size() - 1; i++ )
723  {
724  if( m_shapes[i] == SHAPES_ARE_PT )
725  {
726  numShapes++;
727  }
728  else
729  {
730  // Expect that the second index only gets populated when the point is shared between
731  // two shapes. Otherwise, the shape index should always go on the first element of
732  // the pair.
733  assert( m_shapes[i].first != SHAPE_IS_PT );
734 
735  // Start assuming the point is shared with the previous arc
736  // If so, the new/next arc index should be located at the second
737  // element in the pair
738  arcIdx = m_shapes[i].second;
739 
740  if( arcIdx == SHAPE_IS_PT )
741  arcIdx = m_shapes[i].first; // Not a shared point
742 
743  numShapes++;
744 
745  // Now skip the rest of the arc
746  while( i < numPoints && m_shapes[i].first == arcIdx )
747  i++;
748 
749  // Add the "hidden" segment at the end of the arc, if it exists
750  if( i < numPoints && m_points[i] != m_points[i - 1] )
751  {
752  numShapes++;
753  }
754 
755  i--;
756  }
757  }
758 
759  return numShapes;
760 }
static const ssize_t SHAPE_IS_PT
std::vector< VECTOR2I > m_points
array of vertices
std::vector< std::pair< ssize_t, ssize_t > > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
static const std::pair< ssize_t, ssize_t > SHAPES_ARE_PT

References m_points, m_shapes, SHAPE_IS_PT, and SHAPES_ARE_PT.

Referenced by PNS::LINE_PLACER::mergeHead(), PNS::LINE_PLACER::optimizeTailHeadTransition(), and PNS::LINE::ShapeCount().

◆ Simplify()

SHAPE_LINE_CHAIN & SHAPE_LINE_CHAIN::Simplify ( bool  aRemoveColinear = true)

Simplify the line chain by removing colinear adjacent segments and duplicate vertices.

Parameters
aRemoveColinearcontrols the removal of colinear adjacent segments.
Returns
reference to this line chain.

Definition at line 1496 of file shape_line_chain.cpp.

1497 {
1498  std::vector<VECTOR2I> pts_unique;
1499  std::vector<std::pair<ssize_t, ssize_t>> shapes_unique;
1500 
1501  if( PointCount() < 2 )
1502  {
1503  return *this;
1504  }
1505  else if( PointCount() == 2 )
1506  {
1507  if( m_points[0] == m_points[1] )
1508  m_points.pop_back();
1509 
1510  return *this;
1511  }
1512 
1513  int i = 0;
1514  int np = PointCount();
1515 
1516  // stage 1: eliminate duplicate vertices
1517  while( i < np )
1518  {
1519  int j = i + 1;
1520 
1521  // We can eliminate duplicate vertices as long as they are part of the same shape, OR if
1522  // one of them is part of a shape and one is not.
1523  while( j < np && m_points[i] == m_points[j] &&
1524  ( m_shapes[i] == m_shapes[j] ||
1525  m_shapes[i] == SHAPES_ARE_PT ||
1526  m_shapes[j] == SHAPES_ARE_PT ) )
1527  {
1528  j++;
1529  }
1530 
1531  std::pair<ssize_t,ssize_t> shapeToKeep = m_shapes[i];
1532 
1533  if( shapeToKeep == SHAPES_ARE_PT )
1534  shapeToKeep = m_shapes[j - 1];
1535 
1536  assert( shapeToKeep.first < static_cast<int>( m_arcs.size() ) );
1537  assert( shapeToKeep.second < static_cast<int>( m_arcs.size() ) );
1538 
1539  pts_unique.push_back( CPoint( i ) );
1540  shapes_unique.push_back( shapeToKeep );
1541 
1542  i = j;
1543  }
1544 
1545  m_points.clear();
1546  m_shapes.clear();
1547  np = pts_unique.size();
1548 
1549  i = 0;
1550 
1551  // stage 2: eliminate colinear segments
1552  while( i < np - 2 )
1553  {
1554  const VECTOR2I p0 = pts_unique[i];
1555  const VECTOR2I p1 = pts_unique[i + 1];
1556  int n = i;
1557 
1558  if( aRemoveColinear && shapes_unique[i] == SHAPES_ARE_PT
1559  && shapes_unique[i + 1] == SHAPES_ARE_PT )
1560  {
1561  while( n < np - 2
1562  && ( SEG( p0, p1 ).LineDistance( pts_unique[n + 2] ) <= 1
1563  || SEG( p0, p1 ).Collinear( SEG( p1, pts_unique[n + 2] ) ) ) )
1564  n++;
1565  }
1566 
1567  m_points.push_back( p0 );
1568  m_shapes.push_back( shapes_unique[i] );
1569 
1570  if( n > i )
1571  i = n;
1572 
1573  if( n == np - 2 )
1574  {
1575  m_points.push_back( pts_unique[np - 1] );
1576  m_shapes.push_back( shapes_unique[np - 1] );
1577  return *this;
1578  }
1579 
1580  i++;
1581  }
1582 
1583  if( np > 1 )
1584  {
1585  m_points.push_back( pts_unique[np - 2] );
1586  m_shapes.push_back( shapes_unique[np - 2] );
1587  }
1588 
1589  m_points.push_back( pts_unique[np - 1] );
1590  m_shapes.push_back( shapes_unique[np - 1] );
1591 
1592  assert( m_points.size() == m_shapes.size() );
1593 
1594  return *this;
1595 }
Define a general 2D-vector/point.
Definition: vector2d.h:61
int PointCount() const
Return the number of points (vertices) in this line chain.
std::vector< SHAPE_ARC > m_arcs
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
std::vector< VECTOR2I > m_points
array of vertices
Definition: seg.h:40
std::vector< std::pair< ssize_t, ssize_t > > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
static const std::pair< ssize_t, ssize_t > SHAPES_ARE_PT

References CPoint(), m_arcs, m_points, m_shapes, PointCount(), and SHAPES_ARE_PT.

Referenced by PNS::MOUSE_TRAIL_TRACER::AddTrailPoint(), PNS::NODE::AssembleLine(), PNS::DIFF_PAIR_PLACER::attemptWalk(), DIRECTION_45::BuildInitialTrace(), PNS::LINE::ChangedArea(), CN_ZONE_LAYER::CN_ZONE_LAYER(), CompareGeometry(), PNS::DIFF_PAIR::CoupledSegmentPairs(), PNS::MEANDER_PLACER_BASE::cutTunedLine(), PNS::MEANDER_PLACER::doMove(), DIALOG_PAD_PRIMITIVE_POLY_PROPS::doValidate(), PNS::LINE::dragCornerFree(), PNS::LINE::dragSegment45(), PNS::MOUSE_TRAIL_TRACER::GetPosture(), CONVERT_TOOL::makePolysFromSegs(), PNS::OPTIMIZER::mergeDpStep(), PNS::OPTIMIZER::mergeFull(), PNS::LINE_PLACER::mergeHead(), PNS::DP_MEANDER_PLACER::Move(), PNS::SHOVE::onCollidingSolid(), PNS::LINE_PLACER::optimizeTailHeadTransition(), PNS::LINE_PLACER::rhShoveOnly(), PNS::WALKAROUND::Route(), PNS::OPTIMIZER::runSmartPads(), PNS::TOPOLOGY::SimplifyLine(), PNS::LINE_PLACER::simplifyNewLine(), PNS::WALKAROUND::singleStep(), PNS::OPTIMIZER::smartPadsSingle(), PNS::Tighten(), PNS::LINE_PLACER::Trace(), and SHAPE_POLY_SET::unfractureSingle().

◆ Slice()

const SHAPE_LINE_CHAIN 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.

Parameters
aStartIndexis the start of the point range to be returned (inclusive).
aEndIndexis the end of the point range to be returned (inclusive).
Returns
the cut line chain.

Definition at line 876 of file shape_line_chain.cpp.

877 {
878  SHAPE_LINE_CHAIN rv;
879 
880  if( aEndIndex < 0 )
881  aEndIndex += PointCount();
882 
883  if( aStartIndex < 0 )
884  aStartIndex += PointCount();
885 
886  int numPoints = static_cast<int>( m_points.size() );
887 
888 
889  if( IsArcSegment( aStartIndex ) && !IsArcStart( aStartIndex ) )
890  {
891  // Cutting in middle of an arc, lets split it
892  ssize_t arcIndex = ArcIndex( aStartIndex );
893  const SHAPE_ARC& currentArc = Arc( arcIndex );
894 
895  // Copy the points as arc points
896  for( size_t i = aStartIndex; arcIndex == ArcIndex( i ); i++ )
897  {
898  rv.m_points.push_back( m_points[i] );
899  rv.m_shapes.push_back( { rv.m_arcs.size(), SHAPE_IS_PT } );
900  rv.m_bbox.Merge( m_points[i] );
901  }
902 
903  // Create a new arc from the existing one, with different start point.
904  SHAPE_ARC newArc;
905 
906  VECTOR2I newArcStart = m_points[aStartIndex];
907 
908  newArc.ConstructFromStartEndCenter( newArcStart, currentArc.GetP1(),
909  currentArc.GetCenter(),
910  currentArc.IsClockwise() );
911 
912 
913  rv.m_arcs.push_back( newArc );
914 
915  aStartIndex += rv.PointCount();
916  }
917 
918  for( int i = aStartIndex; i <= aEndIndex && i < numPoints; i = NextShape( i ) )
919  {
920  if( i == -1 )
921  return rv; // NextShape reached the end
922 
923  if( IsArcStart( i ) )
924  {
925  const SHAPE_ARC &currentArc = Arc( ArcIndex( i ) );
926  int nextShape = NextShape( i );
927  bool isLastShape = nextShape < 0;
928 
929  if( ( isLastShape && aEndIndex != ( numPoints - 1 ) )
930  || ( nextShape > aEndIndex ) )
931  {
932  if( i == aEndIndex )
933  {
934  // Single point on an arc, just append the single point
935  rv.Append( m_points[i] );
936  return rv;
937  }
938 
939  // Cutting in middle of an arc, lets split it
940  ssize_t arcIndex = ArcIndex( i );
941  const SHAPE_ARC& currentArc = Arc( arcIndex );
942 
943  // Copy the points as arc points
944  for( ; i <= aEndIndex && i < numPoints; i++ )
945  {
946  if( arcIndex != ArcIndex( i ) )
947  break;
948 
949  rv.m_points.push_back( m_points[i] );
950  rv.m_shapes.push_back( { rv.m_arcs.size(), SHAPE_IS_PT } );
951  rv.m_bbox.Merge( m_points[i] );
952  }
953 
954  // Create a new arc from the existing one, with different end point.
955  SHAPE_ARC newArc;
956 
957  VECTOR2I newArcEnd = m_points[aEndIndex];
958 
959  newArc.ConstructFromStartEndCenter( currentArc.GetP0(), newArcEnd,
960  currentArc.GetCenter(),
961  currentArc.IsClockwise() );
962 
963 
964  rv.m_arcs.push_back( newArc );
965 
966  return rv;
967  }
968  else
969  {
970  // append the whole arc
971  rv.Append( currentArc );
972  }
973 
974  if( isLastShape )
975  return rv;
976  }
977  else
978  {
979  wxASSERT_MSG( !IsArcSegment( i ), "Still on an arc segment, we missed something..." );
980 
981  rv.Append( m_points[i] );
982  }
983  }
984 
985  return rv;
986 }
BOX2I m_bbox
cached bounding box
const SHAPE_ARC & Arc(size_t aArc) const
bool IsClockwise() const
Definition: shape_arc.cpp:391
static const ssize_t SHAPE_IS_PT
Define a general 2D-vector/point.
Definition: vector2d.h:61
int PointCount() const
Return the number of points (vertices) in this line chain.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
std::vector< SHAPE_ARC > m_arcs
ssize_t ArcIndex(size_t aSegment) const
Return the arc index for the given segment index.
bool IsArcStart(size_t aIndex) const
bool IsArcSegment(size_t aSegment) const
std::vector< VECTOR2I > m_points
array of vertices
const VECTOR2I & GetP0() const
Definition: shape_arc.h:111
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: box2.h:363
std::vector< std::pair< ssize_t, ssize_t > > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
SHAPE_ARC & ConstructFromStartEndCenter(const VECTOR2I &aStart, const VECTOR2I &aEnd, const VECTOR2I &aCenter, bool aClockwise=false, double aWidth=0)
Constructs this arc from the given start, end and center.
Definition: shape_arc.cpp:201
Represent a polyline (an zero-thickness chain of connected line segments).
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 VECTOR2I & GetP1() const
Definition: shape_arc.h:112
VECTOR2I GetCenter() const
Definition: shape_arc.cpp:464

References Append(), Arc(), ArcIndex(), SHAPE_ARC::ConstructFromStartEndCenter(), SHAPE_ARC::GetCenter(), SHAPE_ARC::GetP0(), SHAPE_ARC::GetP1(), IsArcSegment(), IsArcStart(), SHAPE_ARC::IsClockwise(), m_arcs, m_bbox, m_points, m_shapes, BOX2< Vec >::Merge(), NextShape(), PointCount(), and SHAPE_IS_PT.

Referenced by PNS::MOUSE_TRAIL_TRACER::AddTrailPoint(), BOOST_AUTO_TEST_CASE(), PNS::KEEP_TOPOLOGY_CONSTRAINT::Check(), PNS::LINE::ClipVertexRange(), PNS::MEANDER_PLACER_BASE::cutTunedLine(), PNS::LINE::dragCorner45(), PNS::dragCornerInternal(), PNS::LINE_PLACER::optimizeTailHeadTransition(), PNS::LINE_PLACER::rhWalkOnly(), and PNS::Tighten().

◆ Split()

int SHAPE_LINE_CHAIN::Split ( const VECTOR2I aP)

Insert the point aP belonging to one of the our segments, splitting the adjacent segment in two.

Parameters
aPis the point to be inserted.
Returns
index of the newly inserted point (or a negative value if aP does not lie on our line).

Definition at line 628 of file shape_line_chain.cpp.

629 {
630  int ii = -1;
631  int min_dist = 2;
632 
633  int found_index = Find( aP );
634 
635  for( int s = 0; s < SegmentCount(); s++ )
636  {
637  const SEG seg = CSegment( s );
638  int dist = seg.Distance( aP );
639 
640  // make sure we are not producing a 'slightly concave' primitive. This might happen
641  // if aP lies very close to one of already existing points.
642  if( dist < min_dist && seg.A != aP && seg.B != aP )
643  {
644  min_dist = dist;
645  if( found_index < 0 )
646  ii = s;
647  else if( s < found_index )
648  ii = s;
649  }
650  }
651 
652  if( ii < 0 )
653  ii = found_index;
654 
655  if( ii >= 0 )
656  {
657  // Don't create duplicate points
658  if( GetPoint( ii ) == aP )
659  return ii;
660 
661  size_t newIndex = static_cast<size_t>( ii ) + 1;
662 
663  if( IsArcSegment( ii ) )
664  {
665  m_points.insert( m_points.begin() + newIndex, aP );
666  m_shapes.insert( m_shapes.begin() + newIndex, { ArcIndex( ii ), SHAPE_IS_PT } );
667  splitArc( newIndex, true ); // Make the inserted point a shared point
668  }
669  else
670  {
671  Insert( newIndex, aP );
672  }
673 
674  return newIndex;
675  }
676 
677  return -1;
678 }
int Distance(const SEG &aSeg) const
Compute minimum Euclidean distance to segment aSeg.
Definition: seg.cpp:285
static const ssize_t SHAPE_IS_PT
void splitArc(ssize_t aPtIndex, bool aCoincident=false)
Splits an arc into two arcs at aPtIndex.
void Insert(size_t aVertex, const VECTOR2I &aP)
ssize_t ArcIndex(size_t aSegment) const
Return the arc index for the given segment index.
bool IsArcSegment(size_t aSegment) const
int Find(const VECTOR2I &aP, int aThreshold=0) const
Search for point aP.
std::vector< VECTOR2I > m_points
array of vertices
int SegmentCount() const
Return the number of segments in this line chain.
virtual const VECTOR2I GetPoint(int aIndex) const override
Definition: seg.h:40
std::vector< std::pair< ssize_t, ssize_t > > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
const SEG CSegment(int aIndex) const
Return a constant copy of the aIndex segment in the line chain.
VECTOR2I A
Definition: seg.h:48
VECTOR2I B
Definition: seg.h:49

References SEG::A, ArcIndex(), SEG::B, CSegment(), SEG::Distance(), Find(), GetPoint(), Insert(), IsArcSegment(), m_points, m_shapes, SegmentCount(), SHAPE_IS_PT, and splitArc().

Referenced by BOOST_AUTO_TEST_CASE(), PNS::LINE::ClipToNearestObstacle(), PNS::MEANDER_PLACER_BASE::cutTunedLine(), PNS::LINE_PLACER::rhWalkOnly(), and PNS::LINE::Walkaround().

◆ splitArc()

void SHAPE_LINE_CHAIN::splitArc ( ssize_t  aPtIndex,
bool  aCoincident = false 
)
protected

Splits an arc into two arcs at aPtIndex.

Parameter aCoincident controls whether the two arcs are to be coincident at aPtIndex or whether a short straight segment should be created instead

Parameters
aPtIndexindex of the point in the chain in which to split the arc
aCoincidentIf true, the end point of the first arc will be coincident with the start point of the second arc at aPtIndex. If false, the end point of the first arc will be at aPtIndex-1 and the start point of the second arc will be at aPtIndex, resulting in a short straight line segment between aPtIndex-1 and aPtIndex.

Definition at line 169 of file shape_line_chain.cpp.

170 {
171  if( aPtIndex < 0 )
172  aPtIndex += m_shapes.size();
173 
174  if( !IsSharedPt( aPtIndex ) && IsArcStart( aPtIndex ) )
175  return; // Nothing to do
176 
177  if( !IsPtOnArc( aPtIndex ) )
178  return; // Nothing to do
179 
180  wxCHECK_MSG( aPtIndex < static_cast<ssize_t>( m_shapes.size() ), /* void */,
181  "Invalid point index requested." );
182 
183  if( IsSharedPt( aPtIndex ) || IsArcEnd( aPtIndex ) )
184  {
185  if( aCoincident || aPtIndex == 0 )
186  return; // nothing to do
187 
188  ssize_t firstArcIndex = m_shapes[aPtIndex].first;
189 
190  const VECTOR2I& newStart = m_arcs[firstArcIndex].GetP0(); // don't amend the start
191  const VECTOR2I& newEnd = m_points[aPtIndex - 1];
192  amendArc( firstArcIndex, newStart, newEnd );
193 
194  if( IsSharedPt( aPtIndex ) )
195  {
196  m_shapes[aPtIndex].first = m_shapes[aPtIndex].second;
197  m_shapes[aPtIndex].second = SHAPE_IS_PT;
198  }
199  else
200  {
201  m_shapes[aPtIndex] = SHAPES_ARE_PT;
202  }
203 
204  return;
205  }
206 
207  ssize_t currArcIdx = ArcIndex( aPtIndex );
208  SHAPE_ARC& currentArc = m_arcs[currArcIdx];
209 
210  SHAPE_ARC newArc1;
211  SHAPE_ARC newArc2;
212 
213  VECTOR2I arc1End = ( aCoincident ) ? m_points[aPtIndex] : m_points[aPtIndex - 1];
214  VECTOR2I arc2Start = m_points[aPtIndex];
215 
216  newArc1.ConstructFromStartEndCenter( currentArc.GetP0(), arc1End, currentArc.GetCenter(),
217  currentArc.IsClockwise() );
218 
219  newArc2.ConstructFromStartEndCenter( arc2Start, currentArc.GetP1(), currentArc.GetCenter(),
220  currentArc.IsClockwise() );
221 
222  if( !aCoincident && ArcIndex( aPtIndex - 1 ) != currArcIdx )
223  {
224  //Ignore newArc1 as it has zero points
225  m_arcs[currArcIdx] = newArc2;
226  }
227  else
228  {
229  m_arcs[currArcIdx] = newArc1;
230  m_arcs.insert( m_arcs.begin() + currArcIdx + 1, newArc2 );
231 
232  if( aCoincident )
233  {
234  m_shapes[aPtIndex].second = currArcIdx + 1;
235  aPtIndex++;
236  }
237 
238  // Only change the arc indices for the second half of the point range
239  for( int i = aPtIndex; i < PointCount(); i++ )
240  {
241  alg::run_on_pair( m_shapes[i], [&]( ssize_t& aIndex ) {
242  if( aIndex != SHAPE_IS_PT )
243  aIndex++;
244  } );
245  }
246  }
247 }
bool IsSharedPt(size_t aIndex) const
Test if a point is shared between multiple shapes.
bool IsClockwise() const
Definition: shape_arc.cpp:391
static const ssize_t SHAPE_IS_PT
Define a general 2D-vector/point.
Definition: vector2d.h:61
int PointCount() const
Return the number of points (vertices) in this line chain.
std::vector< SHAPE_ARC > m_arcs
ssize_t ArcIndex(size_t aSegment) const
Return the arc index for the given segment index.
bool IsArcStart(size_t aIndex) const
std::vector< VECTOR2I > m_points
array of vertices
void run_on_pair(std::pair< _Type, _Type > &__pair, _Function __f)
Apply a function to the first and second element of a std::pair.
Definition: kicad_algo.h:44
const VECTOR2I & GetP0() const
Definition: shape_arc.h:111
void amendArc(size_t aArcIndex, const VECTOR2I &aNewStart, const VECTOR2I &aNewEnd)
bool IsPtOnArc(size_t aPtIndex) const
std::vector< std::pair< ssize_t, ssize_t > > m_shapes
Array of indices that refer to the index of the shape if the point is part of a larger shape,...
SHAPE_ARC & ConstructFromStartEndCenter(const VECTOR2I &aStart, const VECTOR2I &aEnd, const VECTOR2I &aCenter, bool aClockwise=false, double aWidth=0)
Constructs this arc from the given start, end and center.
Definition: shape_arc.cpp:201
bool IsArcEnd(size_t aIndex) const
static const std::pair< ssize_t, ssize_t > SHAPES_ARE_PT
const VECTOR2I & GetP1() const
Definition: shape_arc.h:112
VECTOR2I GetCenter() const
Definition: shape_arc.cpp:464

References amendArc(), ArcIndex(), SHAPE_ARC::ConstructFromStartEndCenter(), SHAPE_ARC::GetCenter(), SHAPE_ARC::GetP0(), SHAPE_ARC::GetP1(), IsArcEnd(), IsArcStart(), SHAPE_ARC::IsClockwise(), IsPtOnArc(), IsSharedPt(), m_arcs, m_points, m_shapes, PointCount(), alg::run_on_pair(), SHAPE_IS_PT, and SHAPES_ARE_PT.

Referenced by Insert(), Remove(), and Split().

◆ SquaredDistance()

SEG::ecoord SHAPE_LINE_CHAIN_BASE::SquaredDistance ( const VECTOR2I aP,
bool  aOutlineOnly = false 
) const
inherited

Definition at line 614 of file shape_line_chain.cpp.

615 {
617 
618  if( IsClosed() && PointInside( aP ) && !aOutlineOnly )
619  return 0;
620 
621  for( size_t s = 0; s < GetSegmentCount(); s++ )
622  d = std::min( d, GetSegment( s ).SquaredDistance( aP ) );
623 
624  return d;
625 }
virtual bool IsClosed() const =0
ecoord SquaredDistance(const SEG &aSeg) const
Definition: seg.cpp:39
virtual size_t GetSegmentCount() const =0
static constexpr extended_type ECOORD_MAX
Definition: vector2d.h:79
VECTOR2I::extended_type ecoord
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.
virtual const SEG GetSegment(int aIndex) const =0

References VECTOR2< T >::ECOORD_MAX, SHAPE_LINE_CHAIN_BASE::GetSegment(), SHAPE_LINE_CHAIN_BASE::GetSegmentCount(), SHAPE_LINE_CHAIN_BASE::IsClosed(), SHAPE_LINE_CHAIN_BASE::PointInside(), and SEG::SquaredDistance().

Referenced by Distance().

◆ Type()

SHAPE_TYPE SHAPE_BASE::Type ( ) const
inlineinherited

◆ Width()

int SHAPE_LINE_CHAIN::Width ( ) const
inline

Get the current width of the segments in the chain.

Returns
the width in internal units.

Definition at line 249 of file shape_line_chain.h.

250  {
251  return m_width;
252  }
int m_width
Width of the segments (for BBox calculations in RTree) TODO Adjust usage of SHAPE_LINE_CHAIN to accou...

References m_width.

Referenced by PNS::LINE::dragCorner45(), and ROUTER_PREVIEW_ITEM::drawShape().

Friends And Related Function Documentation

◆ SHAPE_POLY_SET

friend class SHAPE_POLY_SET
friend

Definition at line 827 of file shape_line_chain.h.

Member Data Documentation

◆ m_arcs

◆ m_bbox

BOX2I SHAPE_LINE_CHAIN::m_bbox
mutableprivate

cached bounding box

Definition at line 918 of file shape_line_chain.h.

Referenced by Append(), GenerateBBoxCache(), GetCachedBBox(), and Slice().

◆ m_closed

bool SHAPE_LINE_CHAIN::m_closed
private

is the line chain closed?

Definition at line 908 of file shape_line_chain.h.

Referenced by Area(), Clear(), CSegment(), Format(), IsClosed(), NextShape(), Parse(), Reverse(), Segment(), SegmentCount(), and SetClosed().

◆ m_points

◆ m_shapes

std::vector<std::pair<ssize_t, ssize_t> > SHAPE_LINE_CHAIN::m_shapes
private

Array of indices that refer to the index of the shape if the point is part of a larger shape, e.g.

arc or spline. If the value is -1, the point is just a point.

There can be up to two shapes associated with a single point (e.g. the end point of one arc might be the start point of another).

Generally speaking only the first element of the pair will be populated (i.e. with a value not equal to SHAPE_IS_PT), unless the point is shared between two arc shapes. If the point is shared, then both the first and second element of the pair should be populated.

The second element must always be SHAPE_IS_PT if the first element is SHAPE_IS_PT.

Definition at line 903 of file shape_line_chain.h.

Referenced by Append(), ArcIndex(), Clear(), convertArc(), convertToClipper(), CShapes(), Insert(), IsArcSegment(), IsPtOnArc(), IsSharedPt(), NextShape(), Parse(), Remove(), RemoveShape(), Replace(), Reverse(), reversedArcIndex(), SetPoint(), SHAPE_LINE_CHAIN(), ShapeCount(), Simplify(), Slice(), Split(), and splitArc().

◆ m_type

SHAPE_TYPE SHAPE_BASE::m_type
protectedinherited

< type of our shape

Definition at line 110 of file shape.h.

Referenced by SHAPE::IsNull(), and SHAPE_BASE::Type().

◆ m_width

int SHAPE_LINE_CHAIN::m_width
private

Width of the segments (for BBox calculations in RTree) TODO Adjust usage of SHAPE_LINE_CHAIN to account for where we need a width and where not Alternatively, we could split the class into a LINE_CHAIN (no width) and SHAPE_LINE_CHAIN that derives from SHAPE as well that does have a width.

Not sure yet on the correct path. TODO Note that we also have SHAPE_SIMPLE which is a closed, filled SHAPE_LINE_CHAIN.

Definition at line 915 of file shape_line_chain.h.

Referenced by BBox(), GenerateBBoxCache(), SetWidth(), and Width().

◆ MIN_PRECISION_IU

const int SHAPE::MIN_PRECISION_IU = 4
staticinherited

This is the minimum precision for all the points in a shape.

Definition at line 122 of file shape.h.

Referenced by BOOST_AUTO_TEST_CASE(), DIRECTION_45::BuildInitialTrace(), CompareLength(), CIRCLE::Contains(), EDIT_TOOL::FilletTracks(), and CIRCLE::IntersectLine().

◆ SHAPE_IS_PT

const ssize_t SHAPE_LINE_CHAIN::SHAPE_IS_PT = -1
staticprivate

◆ SHAPES_ARE_PT

const std::pair< ssize_t, ssize_t > SHAPE_LINE_CHAIN::SHAPES_ARE_PT = { SHAPE_IS_PT, SHAPE_IS_PT }
staticprivate

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