KiCad PCB EDA Suite
SHAPE_POLY_SET Class Reference

Represent a set of closed polygons. More...

#include <shape_poly_set.h>

Inheritance diagram for SHAPE_POLY_SET:
SHAPE SHAPE_BASE

Classes

class  ITERATOR_TEMPLATE
 Base class for iterating over all vertices in a given SHAPE_POLY_SET. More...
 
class  SEGMENT_ITERATOR_TEMPLATE
 Base class for iterating over all segments in a given SHAPE_POLY_SET. More...
 
class  TRIANGULATED_POLYGON
 
struct  VERTEX_INDEX
 Structure to hold the necessary information in order to index a vertex on a SHAPE_POLY_SET object: the polygon index, the contour index relative to the polygon and the vertex index relative the contour. More...
 

Public Types

enum  POLYGON_MODE { PM_FAST = true, PM_STRICTLY_SIMPLE = false }
 Operations on polygons use a aFastMode param if aFastMode is PM_FAST (true) the result can be a weak polygon if aFastMode is PM_STRICTLY_SIMPLE (false) (default) the result is (theoretically) a strictly simple polygon, but calculations can be really significantly time consuming Most of time PM_FAST is preferable. More...
 
enum  CORNER_STRATEGY {
  ALLOW_ACUTE_CORNERS, CHAMFER_ACUTE_CORNERS, ROUND_ACUTE_CORNERS, CHAMFER_ALL_CORNERS,
  ROUND_ALL_CORNERS
}
 < define how inflate transform build inflated polygon More...
 
typedef std::vector< SHAPE_LINE_CHAINPOLYGON
 < represents a single polygon outline with holes. More...
 
typedef ITERATOR_TEMPLATE< VECTOR2IITERATOR
 
typedef ITERATOR_TEMPLATE< const VECTOR2ICONST_ITERATOR
 
typedef SEGMENT_ITERATOR_TEMPLATE< SEGSEGMENT_ITERATOR
 
typedef SEGMENT_ITERATOR_TEMPLATE< const SEGCONST_SEGMENT_ITERATOR
 

Public Member Functions

 SHAPE_POLY_SET ()
 
 SHAPE_POLY_SET (const BOX2D &aRect)
 
 SHAPE_POLY_SET (const SHAPE_LINE_CHAIN &aOutline)
 Construct a SHAPE_POLY_SET with the first outline given by aOutline. More...
 
 SHAPE_POLY_SET (const SHAPE_POLY_SET &aOther)
 Copy constructor SHAPE_POLY_SET Performs a deep copy of aOther into this. More...
 
 ~SHAPE_POLY_SET ()
 
SHAPE_POLY_SEToperator= (const SHAPE_POLY_SET &aOther)
 
void CacheTriangulation (bool aPartition=true)
 
bool IsTriangulationUpToDate () const
 
MD5_HASH GetHash () const
 
virtual bool HasIndexableSubshapes () const override
 
virtual size_t GetIndexableSubshapeCount () const override
 
virtual void GetIndexableSubshapes (std::vector< SHAPE * > &aSubshapes) override
 
bool GetRelativeIndices (int aGlobalIdx, VERTEX_INDEX *aRelativeIndices) const
 Convert a global vertex index —i.e., a number that globally identifies a vertex in a concatenated list of all vertices in all contours— and get the index of the vertex relative to the contour relative to the polygon in which it is. More...
 
bool GetGlobalIndex (VERTEX_INDEX aRelativeIndices, int &aGlobalIdx) const
 Compute the global index of a vertex from the relative indices of polygon, contour and vertex. More...
 
SHAPEClone () const override
 Return a dynamically allocated copy of the shape. More...
 
int NewOutline ()
 Creates a new hole in a given outline. More...
 
int NewHole (int aOutline=-1)
 Adds a new outline to the set and returns its index. More...
 
int AddOutline (const SHAPE_LINE_CHAIN &aOutline)
 Adds a new hole to the given outline (default: last) and returns its index. More...
 
int AddHole (const SHAPE_LINE_CHAIN &aHole, int aOutline=-1)
 Return the area of this poly set. More...
 
double Area ()
 Count the number of arc shapes present. More...
 
int ArcCount () const
 Appends all the arcs in this polyset to aArcBuffer. More...
 
void GetArcs (std::vector< SHAPE_ARC > &aArcBuffer) const
 Removes all arc references from all the outlines and holes in the polyset. More...
 
void ClearArcs ()
 Appends a vertex at the end of the given outline/hole (default: the last outline) More...
 
int Append (int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
 Add a new vertex to the contour indexed by aOutline and aHole (defaults to the outline of the last polygon). More...
 
void Append (const SHAPE_POLY_SET &aSet)
 Append a vertex at the end of the given outline/hole (default: the last outline) More...
 
void Append (const VECTOR2I &aP, int aOutline=-1, int aHole=-1)
 
int Append (SHAPE_ARC &aArc, int aOutline=-1, int aHole=-1)
 Append a new arc to the contour indexed by aOutline and aHole (defaults to the outline of the last polygon). More...
 
void InsertVertex (int aGlobalIndex, const VECTOR2I &aNewVertex)
 Adds a vertex in the globally indexed position aGlobalIndex. More...
 
const VECTOR2ICVertex (int aIndex, int aOutline, int aHole) const
 Return the aGlobalIndex-th vertex in the poly set. More...
 
const VECTOR2ICVertex (int aGlobalIndex) const
 Return the index-th vertex in a given hole outline within a given outline. More...
 
const VECTOR2ICVertex (VERTEX_INDEX aIndex) const
 
bool GetNeighbourIndexes (int aGlobalIndex, int *aPrevious, int *aNext)
 Return the global indexes of the previous and the next corner of the aGlobalIndex-th corner of a contour in the polygon set. More...
 
bool IsPolygonSelfIntersecting (int aPolygonIndex) const
 Check whether the aPolygonIndex-th polygon in the set is self intersecting. More...
 
bool IsSelfIntersecting () const
 Check whether any of the polygons in the set is self intersecting. More...
 
unsigned int TriangulatedPolyCount () const
 Return the number of outlines in the set. More...
 
int OutlineCount () const
 Return the number of vertices in a given outline/hole. More...
 
int VertexCount (int aOutline=-1, int aHole=-1) const
 Returns the number of holes in a given outline. More...
 
int HoleCount (int aOutline) const
 Return the reference to aIndex-th outline in the set. More...
 
SHAPE_LINE_CHAINOutline (int aIndex)
 
const SHAPE_LINE_CHAINOutline (int aIndex) const
 
SHAPE_POLY_SET Subset (int aFirstPolygon, int aLastPolygon)
 Return a subset of the polygons in this set, the ones between aFirstPolygon and aLastPolygon. More...
 
SHAPE_POLY_SET UnitSet (int aPolygonIndex)
 Return the reference to aHole-th hole in the aIndex-th outline. More...
 
SHAPE_LINE_CHAINHole (int aOutline, int aHole)
 Return the aIndex-th subpolygon in the set. More...
 
POLYGONPolygon (int aIndex)
 
const POLYGONPolygon (int aIndex) const
 
const TRIANGULATED_POLYGONTriangulatedPolygon (int aIndex) const
 
const SHAPE_LINE_CHAINCOutline (int aIndex) const
 
const SHAPE_LINE_CHAINCHole (int aOutline, int aHole) const
 
const POLYGONCPolygon (int aIndex) const
 
ITERATOR Iterate (int aFirst, int aLast, bool aIterateHoles=false)
 Return an object to iterate through the points of the polygons between aFirst and aLast. More...
 
ITERATOR Iterate (int aOutline)
 
ITERATOR IterateWithHoles (int aOutline)
 
ITERATOR Iterate ()
 
ITERATOR IterateWithHoles ()
 
CONST_ITERATOR CIterate (int aFirst, int aLast, bool aIterateHoles=false) const
 
CONST_ITERATOR CIterate (int aOutline) const
 
CONST_ITERATOR CIterateWithHoles (int aOutline) const
 
CONST_ITERATOR CIterate () const
 
CONST_ITERATOR CIterateWithHoles () const
 
ITERATOR IterateFromVertexWithHoles (int aGlobalIdx)
 Return an iterator object, for iterating between aFirst and aLast outline, with or without holes (default: without) More...
 
SEGMENT_ITERATOR IterateSegments (int aFirst, int aLast, bool aIterateHoles=false)
 Return an iterator object, for iterating between aFirst and aLast outline, with or without holes (default: without) More...
 
CONST_SEGMENT_ITERATOR CIterateSegments (int aFirst, int aLast, bool aIterateHoles=false) const
 Return an iterator object, for iterating aPolygonIdx-th polygon edges. More...
 
SEGMENT_ITERATOR IterateSegments (int aPolygonIdx)
 Return an iterator object, for iterating aPolygonIdx-th polygon edges. More...
 
CONST_SEGMENT_ITERATOR CIterateSegments (int aPolygonIdx) const
 Return an iterator object, for all outlines in the set (no holes). More...
 
SEGMENT_ITERATOR IterateSegments ()
 Returns an iterator object, for all outlines in the set (no holes) More...
 
CONST_SEGMENT_ITERATOR CIterateSegments () const
 Returns an iterator object, for all outlines in the set (with holes) More...
 
SEGMENT_ITERATOR IterateSegmentsWithHoles ()
 Return an iterator object, for the aOutline-th outline in the set (with holes). More...
 
SEGMENT_ITERATOR IterateSegmentsWithHoles (int aOutline)
 Return an iterator object, for the aOutline-th outline in the set (with holes). More...
 
CONST_SEGMENT_ITERATOR CIterateSegmentsWithHoles () const
 Return an iterator object, for the aOutline-th outline in the set (with holes). More...
 
CONST_SEGMENT_ITERATOR CIterateSegmentsWithHoles (int aOutline) const
 
void BooleanAdd (const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
 Perform boolean polyset difference For aFastMode meaning, see function booleanOp. More...
 
void BooleanSubtract (const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
 Perform boolean polyset intersection For aFastMode meaning, see function booleanOp. More...
 
void BooleanIntersection (const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
 Perform boolean polyset union between a and b, store the result in it self For aFastMode meaning, see function booleanOp. More...
 
void BooleanAdd (const SHAPE_POLY_SET &a, const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
 Perform boolean polyset difference between a and b, store the result in it self For aFastMode meaning, see function booleanOp. More...
 
void BooleanSubtract (const SHAPE_POLY_SET &a, const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
 Perform boolean polyset intersection between a and b, store the result in it self For aFastMode meaning, see function booleanOp. More...
 
void BooleanIntersection (const SHAPE_POLY_SET &a, const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
 
void Inflate (int aAmount, int aCircleSegCount, CORNER_STRATEGY aCornerStrategy=ROUND_ALL_CORNERS)
 Perform outline inflation/deflation. More...
 
void Deflate (int aAmount, int aCircleSegmentsCount, CORNER_STRATEGY aCornerStrategy=ROUND_ALL_CORNERS)
 
void InflateWithLinkedHoles (int aFactor, int aCircleSegmentsCount, POLYGON_MODE aFastMode)
 Perform outline inflation/deflation, using round corners. More...
 
void Fracture (POLYGON_MODE aFastMode)
 Convert a single outline slitted ("fractured") polygon into a set ouf outlines with holes. More...
 
void Unfracture (POLYGON_MODE aFastMode)
 Return true if the polygon set has any holes. More...
 
bool HasHoles () const
 Return true if the polygon set has any holes that share a vertex. More...
 
bool HasTouchingHoles () const
 Simplify the polyset (merges overlapping polys, eliminates degeneracy/self-intersections) For aFastMode meaning, see function booleanOp. More...
 
void Simplify (POLYGON_MODE aFastMode)
 
int NormalizeAreaOutlines ()
 Convert a self-intersecting polygon to one (or more) non self-intersecting polygon(s). More...
 
const std::string Format () const override
 
bool Parse (std::stringstream &aStream) override
 
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 Rotate (double aAngle, const VECTOR2I &aCenter={ 0, 0 }) override
 Rotate all vertices by a given angle. More...
 
bool IsSolid () const override
 
const BOX2I BBox (int aClearance=0) const override
 Compute a bounding box of the shape, with a margin of aClearance a collision. More...
 
bool PointOnEdge (const VECTOR2I &aP) const
 Check if point aP lies on an edge or vertex of some of the outlines or holes. More...
 
bool Collide (const SHAPE *aShape, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
 Check if the boundary of shape (this) lies closer to the shape aShape than aClearance, indicating a collision. More...
 
bool Collide (const VECTOR2I &aP, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
 Check whether the point aP is either inside or on the edge of the polygon set. More...
 
bool Collide (const SEG &aSeg, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
 Check whether the segment aSeg collides with the polygon set (or its edge). More...
 
bool CollideVertex (const VECTOR2I &aPoint, VERTEX_INDEX &aClosestVertex, int aClearance=0) const
 Check whether aPoint collides with any vertex of any of the contours of the polygon. More...
 
bool CollideEdge (const VECTOR2I &aPoint, VERTEX_INDEX &aClosestVertex, int aClearance=0) const
 Check whether aPoint collides with any edge of any of the contours of the polygon. More...
 
void BuildBBoxCaches () const
 Construct BBoxCaches for Contains(), below. More...
 
const BOX2I BBoxFromCaches () const
 
bool Contains (const VECTOR2I &aP, int aSubpolyIndex=-1, int aAccuracy=0, bool aUseBBoxCaches=false) const
 Return true if a given subpolygon contains the point aP. More...
 
bool IsEmpty () const
 
void RemoveVertex (int aGlobalIndex)
 Delete the aGlobalIndex-th vertex. More...
 
void RemoveVertex (VERTEX_INDEX aRelativeIndices)
 Delete the vertex indexed by aRelativeIndex (index of polygon, contour and vertex). More...
 
void RemoveAllContours ()
 
void RemoveContour (int aContourIdx, int aPolygonIdx=-1)
 Delete the aContourIdx-th contour of the aPolygonIdx-th polygon in the set. More...
 
int RemoveNullSegments ()
 Look for null segments; ie, segments whose ends are exactly the same and deletes them. More...
 
void SetVertex (const VERTEX_INDEX &aIndex, const VECTOR2I &aPos)
 Accessor function to set the position of a specific point. More...
 
void SetVertex (int aGlobalIndex, const VECTOR2I &aPos)
 Set the vertex based on the global index. More...
 
int TotalVertices () const
 Delete aIdx-th polygon from the set. More...
 
void DeletePolygon (int aIdx)
 
POLYGON ChamferPolygon (unsigned int aDistance, int aIndex)
 Return a chamfered version of the aIndex-th polygon. More...
 
POLYGON FilletPolygon (unsigned int aRadius, int aErrorMax, int aIndex)
 Return a filleted version of the aIndex-th polygon. More...
 
SHAPE_POLY_SET Chamfer (int aDistance)
 Return a chamfered version of the polygon set. More...
 
SHAPE_POLY_SET Fillet (int aRadius, int aErrorMax)
 Return a filleted version of the polygon set. More...
 
SEG::ecoord SquaredDistanceToPolygon (VECTOR2I aPoint, int aIndex, VECTOR2I *aNearest) const
 Compute the minimum distance between the aIndex-th polygon and aPoint. More...
 
SEG::ecoord SquaredDistanceToPolygon (const SEG &aSegment, int aIndex, VECTOR2I *aNearest) const
 Compute the minimum distance between the aIndex-th polygon and aSegment with a possible width. More...
 
SEG::ecoord SquaredDistance (VECTOR2I aPoint, VECTOR2I *aNearest=nullptr) const
 Compute the minimum distance squared between aPoint and all the polygons in the set. More...
 
SEG::ecoord SquaredDistance (const SEG &aSegment, VECTOR2I *aNearest=nullptr) const
 Compute the minimum distance squared between aSegment and all the polygons in the set. More...
 
bool IsVertexInHole (int aGlobalIdx)
 Check whether the aGlobalIndex-th vertex belongs to a hole. More...
 
bool IsNull () const
 Return true if the shape is a null shape. 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 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...
 

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 Attributes

SHAPE_TYPE m_type
 < type of our shape More...
 

Private Types

enum  CORNER_MODE { CHAMFERED, FILLETED }
 Operation ChamferPolygon and FilletPolygon are computed under the private chamferFillet method; this enum is defined to make the necessary distinction when calling this method from the public ChamferPolygon and FilletPolygon methods. More...
 
typedef std::vector< POLYGONPOLYSET
 

Private Member Functions

void fractureSingle (POLYGON &paths)
 
void unfractureSingle (POLYGON &path)
 
void importTree (ClipperLib::PolyTree *tree, const std::vector< CLIPPER_Z_VALUE > &aZValueBuffer, const std::vector< SHAPE_ARC > &aArcBuffe)
 
void booleanOp (ClipperLib::ClipType aType, const SHAPE_POLY_SET &aOtherShape, POLYGON_MODE aFastMode)
 This is the engine to execute all polygon boolean transforms (AND, OR, ... More...
 
void booleanOp (ClipperLib::ClipType aType, const SHAPE_POLY_SET &aShape, const SHAPE_POLY_SET &aOtherShape, POLYGON_MODE aFastMode)
 
bool containsSingle (const VECTOR2I &aP, int aSubpolyIndex, int aAccuracy, bool aUseBBoxCaches=false) const
 Check whether the point aP is inside the aSubpolyIndex-th polygon of the polyset. More...
 
POLYGON chamferFilletPolygon (CORNER_MODE aMode, unsigned int aDistance, int aIndex, int aErrorMax)
 Return the chamfered or filleted version of the aIndex-th polygon in the set, depending on the aMode selected. More...
 
bool hasTouchingHoles (const POLYGON &aPoly) const
 
MD5_HASH checksum () const
 

Private Attributes

POLYSET m_polys
 
std::vector< std::unique_ptr< TRIANGULATED_POLYGON > > m_triangulatedPolys
 
bool m_triangulationValid = false
 
MD5_HASH m_hash
 

Detailed Description

Represent a set of closed polygons.

Polygons may be nonconvex, self-intersecting and have holes. Provides boolean operations (using Clipper library as the backend).

Let us define the terms used on this class to clarify methods names and comments:

  • Polygon: each polygon in the set.
  • Outline: first polyline in each polygon; represents its outer contour.
  • Hole: second and following polylines in the polygon.
  • Contour: each polyline of each polygon in the set, whether or not it is an outline or a hole.
  • Vertex (or corner): each one of the points that define a contour.

TODO: add convex partitioning & spatial index

Definition at line 64 of file shape_poly_set.h.

Member Typedef Documentation

◆ CONST_ITERATOR

◆ CONST_SEGMENT_ITERATOR

◆ ecoord

typedef VECTOR2I::extended_type SHAPE::ecoord
protectedinherited

Definition at line 236 of file shape.h.

◆ ITERATOR

◆ POLYGON

< represents a single polygon outline with holes.

The first entry is the outline, the remaining (if any), are the holes N.B. SWIG only supports typedef, so avoid c++ 'using' keyword

Definition at line 70 of file shape_poly_set.h.

◆ POLYSET

typedef std::vector<POLYGON> SHAPE_POLY_SET::POLYSET
private

Definition at line 1424 of file shape_poly_set.h.

◆ SEGMENT_ITERATOR

Member Enumeration Documentation

◆ CORNER_MODE

Operation ChamferPolygon and FilletPolygon are computed under the private chamferFillet method; this enum is defined to make the necessary distinction when calling this method from the public ChamferPolygon and FilletPolygon methods.

Enumerator
CHAMFERED 
FILLETED 

Definition at line 1396 of file shape_poly_set.h.

◆ CORNER_STRATEGY

< define how inflate transform build inflated polygon

Enumerator
ALLOW_ACUTE_CORNERS 

just inflate the polygon. Acute angles create spikes

CHAMFER_ACUTE_CORNERS 

Acute angles are chamfered.

ROUND_ACUTE_CORNERS 

Acute angles are rounded.

CHAMFER_ALL_CORNERS 

All angles are chamfered.

The distance between new and old polygon edges is not constant, but do not change a lot

ROUND_ALL_CORNERS 

All angles are rounded.

The distance between new and old polygon edges is constant

Definition at line 966 of file shape_poly_set.h.

967  {
975  };
All angles are chamfered.
Acute angles are rounded.
Acute angles are chamfered.
just inflate the polygon. Acute angles create spikes

◆ POLYGON_MODE

Operations on polygons use a aFastMode param if aFastMode is PM_FAST (true) the result can be a weak polygon if aFastMode is PM_STRICTLY_SIMPLE (false) (default) the result is (theoretically) a strictly simple polygon, but calculations can be really significantly time consuming Most of time PM_FAST is preferable.

PM_STRICTLY_SIMPLE can be used in critical cases (Gerber output for instance)

Enumerator
PM_FAST 
PM_STRICTLY_SIMPLE 

Definition at line 933 of file shape_poly_set.h.

Constructor & Destructor Documentation

◆ SHAPE_POLY_SET() [1/4]

SHAPE_POLY_SET::SHAPE_POLY_SET ( )

Definition at line 61 of file shape_poly_set.cpp.

61  :
63 {
64 }
SHAPE(SHAPE_TYPE aType)
Create an empty shape of type aType.
Definition: shape.h:127
set of polygons (with holes, etc.)
Definition: shape.h:48

Referenced by Clone().

◆ SHAPE_POLY_SET() [2/4]

SHAPE_POLY_SET::SHAPE_POLY_SET ( const BOX2D aRect)

Definition at line 67 of file shape_poly_set.cpp.

67  :
69 {
70  NewOutline();
71  Append( VECTOR2I( aRect.GetLeft(), aRect.GetTop() ) );
72  Append( VECTOR2I( aRect.GetRight(), aRect.GetTop() ) );
73  Append( VECTOR2I( aRect.GetRight(), aRect.GetBottom() ) );
74  Append( VECTOR2I( aRect.GetLeft(), aRect.GetBottom() ) );
75  Outline( 0 ).SetClosed( true );
76 }
SHAPE(SHAPE_TYPE aType)
Create an empty shape of type aType.
Definition: shape.h:127
coord_type GetTop() const
Definition: box2.h:187
coord_type GetRight() const
Definition: box2.h:182
coord_type GetBottom() const
Definition: box2.h:183
VECTOR2< int > VECTOR2I
Definition: vector2d.h:623
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
SHAPE_LINE_CHAIN & Outline(int aIndex)
int NewOutline()
Creates a new hole in a given outline.
set of polygons (with holes, etc.)
Definition: shape.h:48
coord_type GetLeft() const
Definition: box2.h:186
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Add a new vertex to the contour indexed by aOutline and aHole (defaults to the outline of the last po...

References Append(), BOX2< Vec >::GetBottom(), BOX2< Vec >::GetLeft(), BOX2< Vec >::GetRight(), BOX2< Vec >::GetTop(), NewOutline(), Outline(), and SHAPE_LINE_CHAIN::SetClosed().

◆ SHAPE_POLY_SET() [3/4]

SHAPE_POLY_SET::SHAPE_POLY_SET ( const SHAPE_LINE_CHAIN aOutline)

Construct a SHAPE_POLY_SET with the first outline given by aOutline.

Parameters
aOutlineis a closed outline

Definition at line 79 of file shape_poly_set.cpp.

79  :
81 {
82  AddOutline( aOutline );
83 }
SHAPE(SHAPE_TYPE aType)
Create an empty shape of type aType.
Definition: shape.h:127
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new hole to the given outline (default: last) and returns its index.
set of polygons (with holes, etc.)
Definition: shape.h:48

References AddOutline().

◆ SHAPE_POLY_SET() [4/4]

SHAPE_POLY_SET::SHAPE_POLY_SET ( const SHAPE_POLY_SET aOther)

Copy constructor SHAPE_POLY_SET Performs a deep copy of aOther into this.

Parameters
aOtheris the SHAPE_POLY_SET object that will be copied.

Definition at line 86 of file shape_poly_set.cpp.

86  :
87  SHAPE( aOther ),
88  m_polys( aOther.m_polys )
89 {
90  if( aOther.IsTriangulationUpToDate() )
91  {
92  for( unsigned i = 0; i < aOther.TriangulatedPolyCount(); i++ )
93  {
94  const TRIANGULATED_POLYGON* poly = aOther.TriangulatedPolygon( i );
95  m_triangulatedPolys.push_back( std::make_unique<TRIANGULATED_POLYGON>( *poly ) );
96  }
97 
98  m_hash = aOther.GetHash();
99  m_triangulationValid = true;
100  }
101  else
102  {
103  m_triangulationValid = false;
104  m_hash = MD5_HASH();
105  m_triangulatedPolys.clear();
106  }
107 }
SHAPE(SHAPE_TYPE aType)
Create an empty shape of type aType.
Definition: shape.h:127
std::vector< std::unique_ptr< TRIANGULATED_POLYGON > > m_triangulatedPolys
bool IsTriangulationUpToDate() const
MD5_HASH GetHash() const
unsigned int TriangulatedPolyCount() const
Return the number of outlines in the set.
const TRIANGULATED_POLYGON * TriangulatedPolygon(int aIndex) const

References GetHash(), IsTriangulationUpToDate(), m_hash, m_triangulatedPolys, m_triangulationValid, TriangulatedPolyCount(), and TriangulatedPolygon().

◆ ~SHAPE_POLY_SET()

SHAPE_POLY_SET::~SHAPE_POLY_SET ( )

Definition at line 110 of file shape_poly_set.cpp.

111 {
112 }

Member Function Documentation

◆ AddHole()

int SHAPE_POLY_SET::AddHole ( const SHAPE_LINE_CHAIN aHole,
int  aOutline = -1 
)

Return the area of this poly set.

Definition at line 472 of file shape_poly_set.cpp.

473 {
474  assert( m_polys.size() );
475 
476  if( aOutline < 0 )
477  aOutline += m_polys.size();
478 
479  assert( aOutline < (int)m_polys.size() );
480 
481  POLYGON& poly = m_polys[aOutline];
482 
483  assert( poly.size() );
484 
485  poly.push_back( aHole );
486 
487  return poly.size() - 2;
488 }
std::vector< SHAPE_LINE_CHAIN > POLYGON
< represents a single polygon outline with holes.

References m_polys.

Referenced by ZONE::AddPolygon(), BuildFootprintPolygonOutlines(), KI_TEST::BuildHollowSquare(), KI_TEST::CommonTestData::CommonTestData(), CADSTAR_PCB_ARCHIVE_LOADER::getPolySetFromCadstarShape(), FABMASTER::loadFootprints(), FABMASTER::loadShapePolySet(), FABMASTER::loadZone(), and ALTIUM_PCB::ParseRegions6Data().

◆ AddOutline()

int SHAPE_POLY_SET::AddOutline ( const SHAPE_LINE_CHAIN aOutline)

Adds a new hole to the given outline (default: last) and returns its index.

Definition at line 458 of file shape_poly_set.cpp.

459 {
460  assert( aOutline.IsClosed() );
461 
462  POLYGON poly;
463 
464  poly.push_back( aOutline );
465 
466  m_polys.push_back( poly );
467 
468  return m_polys.size() - 1;
469 }
std::vector< SHAPE_LINE_CHAIN > POLYGON
< represents a single polygon outline with holes.
bool IsClosed() const override

References SHAPE_LINE_CHAIN::IsClosed(), and m_polys.

Referenced by ZONE_FILLER::addHatchFillTypeOnZone(), ZONE::AddPolygon(), BOOST_AUTO_TEST_CASE(), buildBoardBoundingBoxPoly(), KI_TEST::BuildHollowSquare(), KI_TEST::BuildPolyset(), KI_TEST::CommonTestData::CommonTestData(), ZONE_FILLER::computeRawFilledArea(), ConvertPolygonToBlocks(), FOOTPRINT::CoverageRatio(), CONVERT_TOOL::CreateLines(), BOARD_ADAPTER::createPadWithClearance(), KIGFX::GERBVIEW_PAINTER::draw(), GEOM_TEST::FilletPolySet(), FOOTPRINT::GetBoundingHull(), IteratorFixture::IteratorFixture(), DSN::SPECCTRA_DB::makeIMAGE(), CONVERT_TOOL::makePolysFromCircles(), CONVERT_TOOL::makePolysFromRects(), CONVERT_TOOL::makePolysFromSegs(), PAD::MergePrimitivesAsPolygon(), NormalizeAreaOutlines(), EAGLE_PLUGIN::packagePolygon(), ALTIUM_PCB::ParsePolygons6Data(), ALTIUM_PCB::ParseRegions6Data(), ALTIUM_PCB::ParseShapeBasedRegions6Data(), partitionPolyIntoRegularCellGrid(), ZONE_CREATE_HELPER::performZoneCutout(), PGPartitionFixture::PGPartitionFixture(), BRDITEMS_PLOTTER::PlotFootprintGraphicItem(), PlotStandardLayer(), SHAPE_POLY_SET(), TestConcaveSquareFillet(), and TestSquareFillet().

◆ Append() [1/4]

int SHAPE_POLY_SET::Append ( int  x,
int  y,
int  aOutline = -1,
int  aHole = -1,
bool  aAllowDuplication = false 
)

Add a new vertex to the contour indexed by aOutline and aHole (defaults to the outline of the last polygon).

Parameters
xis the x coordinate of the new vertex.
yis the y coordinate of the new vertex.
aOutlineis the index of the polygon.
aHoleis the index of the hole (-1 for the main outline),
aAllowDuplicationis a flag to indicate whether it is allowed to add this corner even if it is duplicated.
Returns
the number of corners of the selected contour after the addition.Merge polygons from two sets.

Definition at line 229 of file shape_poly_set.cpp.

230 {
231  assert( m_polys.size() );
232 
233  if( aOutline < 0 )
234  aOutline += m_polys.size();
235 
236  int idx;
237 
238  if( aHole < 0 )
239  idx = 0;
240  else
241  idx = aHole + 1;
242 
243  assert( aOutline < (int) m_polys.size() );
244  assert( idx < (int) m_polys[aOutline].size() );
245 
246  m_polys[aOutline][idx].Append( x, y, aAllowDuplication );
247 
248  return m_polys[aOutline][idx].PointCount();
249 }

References m_polys.

Referenced by AR_AUTOPLACER::addFpBody(), addHoleToPolygon(), ZONE_FILLER::addKnockout(), AR_AUTOPLACER::addPad(), PAD::AddPrimitivePoly(), Append(), ZONE::AppendCorner(), BuildBoardPolygonOutlines(), ZONE_FILLER::buildCopperItemClearances(), BuildFootprintPolygonOutlines(), ConvertOutlineToPolygon(), GERBER_DRAW_ITEM::ConvertSegmentToPolygon(), D_CODE::ConvertShapeToPolygon(), CornerListToPolygon(), BITMAPCONV_INFO::createOutputData(), BOARD_ADAPTER::createPadWithClearance(), CONVERT_TOOL::CreatePolys(), KIGFX::PCB_PAINTER::draw(), KIGFX::GERBVIEW_PAINTER::drawPolygon(), GERBER_FILE_IMAGE::Execute_DCODE_Command(), GERBER_FILE_IMAGE::Execute_G_Command(), CONVERT_TOOL::extractPolygons(), fillArcPOLY(), PCB_BASE_FRAME::FocusOnItem(), FOOTPRINT::GetBoundingHull(), getRectangleAlongCentreLine(), EDA_SHAPE::hitTest(), InsertVertex(), FABMASTER::loadFootprints(), EAGLE_PLUGIN::loadPolygon(), FABMASTER::loadShapePolySet(), FABMASTER::loadZone(), LEGACY_PLUGIN::loadZONE_CONTAINER(), DSN::SPECCTRA_DB::makeIMAGE(), DXF_PLOTTER::PlotPoly(), PlotStandardLayer(), RENDER_3D_OPENGL::reload(), EDA_SHAPE::rotate(), KIGFX::PREVIEW::POLYGON_ITEM::SetPoints(), EDA_SHAPE::SetPolyPoints(), SHAPE_POLY_SET(), DS_DATA_ITEM_POLYGONS::SyncDrawItems(), TransformArcToPolygon(), EDA_TEXT::TransformBoundingBoxWithClearanceToPolygon(), TransformCircleToPolygon(), TransformOvalToPolygon(), TransformRingToPolygon(), TransformRoundChamferedRectToPolygon(), FP_TEXT::TransformShapeWithClearanceToPolygon(), EDA_SHAPE::TransformShapeWithClearanceToPolygon(), PAD::TransformShapeWithClearanceToPolygon(), ZONE::TransformSmoothedOutlineToPolygon(), ZONE::TransformSolidAreasShapesToPolygon(), TransformTrapezoidToPolygon(), PCB_DIM_ALIGNED::updateGeometry(), PCB_DIM_ORTHOGONAL::updateGeometry(), PCB_DIM_LEADER::updateGeometry(), and EE_POINT_EDITOR::updateParentItem().

◆ Append() [2/4]

void SHAPE_POLY_SET::Append ( const SHAPE_POLY_SET aSet)

Append a vertex at the end of the given outline/hole (default: the last outline)

Definition at line 1620 of file shape_poly_set.cpp.

1621 {
1622  m_polys.insert( m_polys.end(), aSet.m_polys.begin(), aSet.m_polys.end() );
1623 }

References m_polys.

◆ Append() [3/4]

void SHAPE_POLY_SET::Append ( const VECTOR2I aP,
int  aOutline = -1,
int  aHole = -1 
)

Definition at line 1626 of file shape_poly_set.cpp.

1627 {
1628  Append( aP.x, aP.y, aOutline, aHole );
1629 }
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Add a new vertex to the contour indexed by aOutline and aHole (defaults to the outline of the last po...

References Append(), VECTOR2< T >::x, and VECTOR2< T >::y.

◆ Append() [4/4]

int SHAPE_POLY_SET::Append ( SHAPE_ARC aArc,
int  aOutline = -1,
int  aHole = -1 
)

Append a new arc to the contour indexed by aOutline and aHole (defaults to the outline of the last polygon).

Parameters
aArcThe arc to be inserted
aOutlineIndex of the polygon
aHoleIndex of the hole (-1 for the main outline)
Returns
the number of points in the arc (including the interpolated points from the arc)

Definition at line 252 of file shape_poly_set.cpp.

253 {
254  assert( m_polys.size() );
255 
256  if( aOutline < 0 )
257  aOutline += m_polys.size();
258 
259  int idx;
260 
261  if( aHole < 0 )
262  idx = 0;
263  else
264  idx = aHole + 1;
265 
266  assert( aOutline < (int) m_polys.size() );
267  assert( idx < (int) m_polys[aOutline].size() );
268 
269  m_polys[aOutline][idx].Append( aArc );
270 
271  return m_polys[aOutline][idx].PointCount();
272 }

References m_polys.

◆ ArcCount()

int SHAPE_POLY_SET::ArcCount ( ) const

Appends all the arcs in this polyset to aArcBuffer.

Definition at line 507 of file shape_poly_set.cpp.

508 {
509  int retval = 0;
510 
511  for( const POLYGON& poly : m_polys )
512  {
513  for( size_t i = 0; i < poly.size(); i++ )
514  retval += poly[i].ArcCount();
515  }
516 
517  return retval;
518 }
std::vector< SHAPE_LINE_CHAIN > POLYGON
< represents a single polygon outline with holes.
int ArcCount() const
Appends all the arcs in this polyset to aArcBuffer.

References m_polys.

Referenced by booleanOp().

◆ Area()

double SHAPE_POLY_SET::Area ( )

Count the number of arc shapes present.

Definition at line 491 of file shape_poly_set.cpp.

492 {
493  double area = 0.0;
494 
495  for( int i = 0; i < OutlineCount(); i++ )
496  {
497  area += Outline( i ).Area();
498 
499  for( int j = 0; j < HoleCount( i ); j++ )
500  area -= Hole( i, j ).Area();
501  }
502 
503  return area;
504 }
int OutlineCount() const
Return the number of vertices in a given outline/hole.
SHAPE_LINE_CHAIN & Hole(int aOutline, int aHole)
Return the aIndex-th subpolygon in the set.
double Area(bool aAbsolute=true) const
Return the area of this chain.
SHAPE_LINE_CHAIN & Outline(int aIndex)
int HoleCount(int aOutline) const
Return the reference to aIndex-th outline in the set.

References SHAPE_LINE_CHAIN::Area(), Hole(), HoleCount(), Outline(), and OutlineCount().

Referenced by BOOST_AUTO_TEST_CASE(), CADSTAR_PCB_ARCHIVE_LOADER::calculateZonePriorities(), and polygonArea().

◆ BBox()

const BOX2I SHAPE_POLY_SET::BBox ( int  aClearance = 0) const
overridevirtual

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 1367 of file shape_poly_set.cpp.

1368 {
1369  BOX2I bb;
1370 
1371  for( unsigned i = 0; i < m_polys.size(); i++ )
1372  {
1373  if( i == 0 )
1374  bb = m_polys[i][0].BBox();
1375  else
1376  bb.Merge( m_polys[i][0].BBox() );
1377  }
1378 
1379  bb.Inflate( aClearance );
1380  return bb;
1381 }
A 2D bounding box built on top of an origin point and size vector.
Definition: box2.h:41
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: box2.h:363
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:281
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.

References BOX2< Vec >::Inflate(), m_polys, and BOX2< Vec >::Merge().

Referenced by ZONE_FILLER::addHatchFillTypeOnZone(), PCB_BASE_FRAME::FocusOnItem(), APERTURE_MACRO::GetApertureMacroShape(), PAD::GetBestAnchorPosition(), ZONE::GetBoundingBox(), DS_DRAW_ITEM_POLYPOLYGONS::GetBoundingBox(), GERBER_DRAW_ITEM::GetBoundingBox(), DIALOG_PAD_PROPERTIES::padValuesOK(), partitionPolyIntoRegularCellGrid(), BOARD::TestZoneIntersection(), KIGFX::PREVIEW::POLYGON_ITEM::ViewBBox(), and KIGFX::PREVIEW::CENTRELINE_RECT_ITEM::ViewBBox().

◆ BBoxFromCaches()

const BOX2I SHAPE_POLY_SET::BBoxFromCaches ( ) const

Definition at line 1384 of file shape_poly_set.cpp.

1385 {
1386  BOX2I bb;
1387 
1388  for( unsigned i = 0; i < m_polys.size(); i++ )
1389  {
1390  if( i == 0 )
1391  bb = *m_polys[i][0].GetCachedBBox();
1392  else
1393  bb.Merge( *m_polys[i][0].GetCachedBBox() );
1394  }
1395 
1396  return bb;
1397 }
A 2D bounding box built on top of an origin point and size vector.
Definition: box2.h:41
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: box2.h:363

References m_polys, and BOX2< Vec >::Merge().

Referenced by DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testCourtyardClearances().

◆ BooleanAdd() [1/2]

void SHAPE_POLY_SET::BooleanAdd ( const SHAPE_POLY_SET b,
POLYGON_MODE  aFastMode 
)

Perform boolean polyset difference For aFastMode meaning, see function booleanOp.

Definition at line 656 of file shape_poly_set.cpp.

657 {
658  booleanOp( ClipperLib::ctUnion, b, aFastMode );
659 }
void booleanOp(ClipperLib::ClipType aType, const SHAPE_POLY_SET &aOtherShape, POLYGON_MODE aFastMode)
This is the engine to execute all polygon boolean transforms (AND, OR, ...

References booleanOp().

Referenced by PAD::addPadPrimitivesToPolygon(), BOOST_AUTO_TEST_CASE(), BOOST_FIXTURE_TEST_CASE(), ZONE::BuildSmoothedPoly(), CADSTAR_PCB_ARCHIVE_LOADER::loadCoppers(), ALTIUM_PCB::ParseRegions6Data(), DXF_PLOTTER::PlotPoly(), PlotSolderMaskLayer(), and ZONE::RemoveCutout().

◆ BooleanAdd() [2/2]

void SHAPE_POLY_SET::BooleanAdd ( const SHAPE_POLY_SET a,
const SHAPE_POLY_SET b,
POLYGON_MODE  aFastMode 
)

Perform boolean polyset difference between a and b, store the result in it self For aFastMode meaning, see function booleanOp.

Definition at line 674 of file shape_poly_set.cpp.

676 {
677  booleanOp( ClipperLib::ctUnion, a, b, aFastMode );
678 }
void booleanOp(ClipperLib::ClipType aType, const SHAPE_POLY_SET &aOtherShape, POLYGON_MODE aFastMode)
This is the engine to execute all polygon boolean transforms (AND, OR, ...

References booleanOp().

◆ BooleanIntersection() [1/2]

void SHAPE_POLY_SET::BooleanIntersection ( const SHAPE_POLY_SET b,
POLYGON_MODE  aFastMode 
)

Perform boolean polyset union between a and b, store the result in it self For aFastMode meaning, see function booleanOp.

Definition at line 668 of file shape_poly_set.cpp.

669 {
670  booleanOp( ClipperLib::ctIntersection, b, aFastMode );
671 }
void booleanOp(ClipperLib::ClipType aType, const SHAPE_POLY_SET &aOtherShape, POLYGON_MODE aFastMode)
This is the engine to execute all polygon boolean transforms (AND, OR, ...

References booleanOp().

Referenced by ZONE_FILLER::addHatchFillTypeOnZone(), BOOST_AUTO_TEST_CASE(), ZONE::BuildSmoothedPoly(), ZONE_FILLER::computeRawFilledArea(), ConvertPolygonToBlocks(), PCB_BASE_FRAME::FocusOnItem(), isCopperOutside(), PAD_TOOL::recombinePad(), RENDER_3D_OPENGL::reload(), and TransformOvalToPolygon().

◆ BooleanIntersection() [2/2]

void SHAPE_POLY_SET::BooleanIntersection ( const SHAPE_POLY_SET a,
const SHAPE_POLY_SET b,
POLYGON_MODE  aFastMode 
)

Definition at line 688 of file shape_poly_set.cpp.

690 {
691  booleanOp( ClipperLib::ctIntersection, a, b, aFastMode );
692 }
void booleanOp(ClipperLib::ClipType aType, const SHAPE_POLY_SET &aOtherShape, POLYGON_MODE aFastMode)
This is the engine to execute all polygon boolean transforms (AND, OR, ...

References booleanOp().

◆ booleanOp() [1/2]

void SHAPE_POLY_SET::booleanOp ( ClipperLib::ClipType  aType,
const SHAPE_POLY_SET aOtherShape,
POLYGON_MODE  aFastMode 
)
private

This is the engine to execute all polygon boolean transforms (AND, OR, ...

and polygon simplification (merging overlapping polygons).

Parameters
aTypeis the transform type ( see ClipperLib::ClipType )
aOtherShapeis the SHAPE_LINE_CHAIN to combine with me.
aFastModeis an option to choose if the result can be a weak polygon or a strictly simple polygon. if aFastMode is PM_FAST the result can be a weak polygon if aFastMode is PM_STRICTLY_SIMPLE (default) the result is (theoretically) a strictly simple polygon, but calculations can be really significantly time consuming

Definition at line 544 of file shape_poly_set.cpp.

546 {
547  booleanOp( aType, *this, aOtherShape, aFastMode );
548 }
void booleanOp(ClipperLib::ClipType aType, const SHAPE_POLY_SET &aOtherShape, POLYGON_MODE aFastMode)
This is the engine to execute all polygon boolean transforms (AND, OR, ...

Referenced by BooleanAdd(), BooleanIntersection(), BooleanSubtract(), and Simplify().

◆ booleanOp() [2/2]

void SHAPE_POLY_SET::booleanOp ( ClipperLib::ClipType  aType,
const SHAPE_POLY_SET aShape,
const SHAPE_POLY_SET aOtherShape,
POLYGON_MODE  aFastMode 
)
private

Definition at line 551 of file shape_poly_set.cpp.

553 {
554  if( ( aShape.OutlineCount() > 1 || aOtherShape.OutlineCount() > 0 )
555  && ( aShape.ArcCount() > 0 || aOtherShape.ArcCount() > 0 ) )
556  {
557  wxFAIL_MSG( "Boolean ops on curved polygons are not supported. You should call "
558  "ClearArcs() before carrying out the boolean operation." );
559  }
560 
561  ClipperLib::Clipper c;
562 
563  c.StrictlySimple( aFastMode == PM_STRICTLY_SIMPLE );
564 
565  std::vector<CLIPPER_Z_VALUE> zValues;
566  std::vector<SHAPE_ARC> arcBuffer;
567  std::map<VECTOR2I, CLIPPER_Z_VALUE> newIntersectPoints;
568 
569  for( const POLYGON& poly : aShape.m_polys )
570  {
571  for( size_t i = 0; i < poly.size(); i++ )
572  {
573  c.AddPath( poly[i].convertToClipper( i == 0, zValues, arcBuffer ),
574  ClipperLib::ptSubject, true );
575  }
576  }
577 
578  for( const POLYGON& poly : aOtherShape.m_polys )
579  {
580  for( size_t i = 0; i < poly.size(); i++ )
581  {
582  c.AddPath( poly[i].convertToClipper( i == 0, zValues, arcBuffer ),
583  ClipperLib::ptClip, true );
584  }
585  }
586 
587  ClipperLib::PolyTree solution;
588 
589  ClipperLib::ZFillCallback callback =
590  [&]( ClipperLib::IntPoint & e1bot, ClipperLib::IntPoint & e1top,
591  ClipperLib::IntPoint & e2bot, ClipperLib::IntPoint & e2top,
592  ClipperLib::IntPoint & pt )
593  {
594  auto arcIndex =
595  [&]( const ssize_t& aZvalue, const ssize_t& aCompareVal = -1 ) -> ssize_t
596  {
597  ssize_t retval;
598 
599  retval = zValues.at( aZvalue ).m_SecondArcIdx;
600 
601  if( retval == -1 || ( aCompareVal > 0 && retval != aCompareVal ) )
602  retval = zValues.at( aZvalue ).m_FirstArcIdx;
603 
604  return retval;
605  };
606 
607  auto arcSegment =
608  [&]( const ssize_t& aBottomZ, const ssize_t aTopZ ) -> ssize_t
609  {
610  ssize_t retval = arcIndex( aBottomZ );
611 
612  if( retval != -1 )
613  {
614  if( retval != arcIndex( aTopZ, retval ) )
615  retval = -1; // Not an arc segment as the two indices do not match
616  }
617 
618  return retval;
619  };
620 
621  ssize_t e1ArcSegmentIndex = arcSegment( e1bot.Z, e1top.Z );
622  ssize_t e2ArcSegmentIndex = arcSegment( e2bot.Z, e2top.Z );
623 
624  CLIPPER_Z_VALUE newZval;
625 
626  if( e1ArcSegmentIndex != -1 )
627  {
628  newZval.m_FirstArcIdx = e1ArcSegmentIndex;
629  newZval.m_SecondArcIdx = e2ArcSegmentIndex;
630  }
631  else
632  {
633  newZval.m_FirstArcIdx = e2ArcSegmentIndex;
634  newZval.m_SecondArcIdx = -1;
635  }
636 
637  size_t z_value_ptr = zValues.size();
638  zValues.push_back( newZval );
639 
640  // Only worry about arc segments for later processing
641  if( newZval.m_FirstArcIdx != -1 )
642  newIntersectPoints.insert( { VECTOR2I( pt.X, pt.Y ), newZval } );
643 
644  pt.Z = z_value_ptr;
645  //@todo amend X,Y values to true intersection between arcs or arc and segment
646  };
647 
648  c.ZFillFunction( callback ); // register callback
649 
650  c.Execute( aType, solution, ClipperLib::pftNonZero, ClipperLib::pftNonZero );
651 
652  importTree( &solution, zValues, arcBuffer );
653 }
std::vector< SHAPE_LINE_CHAIN > POLYGON
< represents a single polygon outline with holes.
int OutlineCount() const
Return the number of vertices in a given outline/hole.
VECTOR2< int > VECTOR2I
Definition: vector2d.h:623
int ArcCount() const
Appends all the arcs in this polyset to aArcBuffer.
Holds information on each point of a SHAPE_LINE_CHAIN that is retrievable after an operation with Cli...
void importTree(ClipperLib::PolyTree *tree, const std::vector< CLIPPER_Z_VALUE > &aZValueBuffer, const std::vector< SHAPE_ARC > &aArcBuffe)

References ArcCount(), importTree(), CLIPPER_Z_VALUE::m_FirstArcIdx, m_polys, CLIPPER_Z_VALUE::m_SecondArcIdx, OutlineCount(), and PM_STRICTLY_SIMPLE.

◆ BooleanSubtract() [1/2]

◆ BooleanSubtract() [2/2]

void SHAPE_POLY_SET::BooleanSubtract ( const SHAPE_POLY_SET a,
const SHAPE_POLY_SET b,
POLYGON_MODE  aFastMode 
)

Perform boolean polyset intersection between a and b, store the result in it self For aFastMode meaning, see function booleanOp.

Definition at line 681 of file shape_poly_set.cpp.

683 {
684  booleanOp( ClipperLib::ctDifference, a, b, aFastMode );
685 }
void booleanOp(ClipperLib::ClipType aType, const SHAPE_POLY_SET &aOtherShape, POLYGON_MODE aFastMode)
This is the engine to execute all polygon boolean transforms (AND, OR, ...

References booleanOp().

◆ BuildBBoxCaches()

void SHAPE_POLY_SET::BuildBBoxCaches ( ) const

Construct BBoxCaches for Contains(), below.

Note
These caches must be built before a group of calls to Contains(). They are not kept up-to-date by editing actions.

Definition at line 1700 of file shape_poly_set.cpp.

1701 {
1702  for( int polygonIdx = 0; polygonIdx < OutlineCount(); polygonIdx++ )
1703  {
1704  COutline( polygonIdx ).GenerateBBoxCache();
1705 
1706  for( int holeIdx = 0; holeIdx < HoleCount( polygonIdx ); holeIdx++ )
1707  CHole( polygonIdx, holeIdx ).GenerateBBoxCache();
1708  }
1709 }
int OutlineCount() const
Return the number of vertices in a given outline/hole.
const SHAPE_LINE_CHAIN & CHole(int aOutline, int aHole) const
int HoleCount(int aOutline) const
Return the reference to aIndex-th outline in the set.
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
void GenerateBBoxCache() const

References CHole(), COutline(), SHAPE_LINE_CHAIN::GenerateBBoxCache(), HoleCount(), and OutlineCount().

Referenced by ZONE_FILLER::computeRawFilledArea().

◆ CacheTriangulation()

void SHAPE_POLY_SET::CacheTriangulation ( bool  aPartition = true)

Definition at line 2297 of file shape_poly_set.cpp.

2298 {
2299  bool recalculate = !m_hash.IsValid();
2300  MD5_HASH hash;
2301 
2302  if( !m_triangulationValid )
2303  recalculate = true;
2304 
2305  if( !recalculate )
2306  {
2307  hash = checksum();
2308 
2309  if( m_hash != hash )
2310  {
2311  m_hash = hash;
2312  recalculate = true;
2313  }
2314  }
2315 
2316  if( !recalculate )
2317  return;
2318 
2319  SHAPE_POLY_SET tmpSet;
2320 
2321  if( aPartition )
2322  {
2323  // This partitions into regularly-sized grids (1cm in Pcbnew)
2324  SHAPE_POLY_SET flattened( *this );
2325  flattened.ClearArcs();
2326  partitionPolyIntoRegularCellGrid( flattened, 1e7, tmpSet );
2327  }
2328  else
2329  {
2330  tmpSet = *this;
2331 
2332  if( tmpSet.HasHoles() )
2333  tmpSet.Fracture( PM_FAST );
2334  }
2335 
2336  m_triangulatedPolys.clear();
2337  m_triangulationValid = false;
2338 
2339  while( tmpSet.OutlineCount() > 0 )
2340  {
2341 
2342  if( !m_triangulatedPolys.empty() && m_triangulatedPolys.back()->GetTriangleCount() == 0 )
2343  m_triangulatedPolys.erase( m_triangulatedPolys.end() - 1 );
2344 
2345  m_triangulatedPolys.push_back( std::make_unique<TRIANGULATED_POLYGON>() );
2346  PolygonTriangulation tess( *m_triangulatedPolys.back() );
2347 
2348  // If the tessellation fails, we re-fracture the polygon, which will
2349  // first simplify the system before fracturing and removing the holes
2350  // This may result in multiple, disjoint polygons.
2351  if( !tess.TesselatePolygon( tmpSet.Polygon( 0 ).front() ) )
2352  {
2353  tmpSet.Fracture( PM_FAST );
2354  m_triangulationValid = false;
2355  continue;
2356  }
2357 
2358  tmpSet.DeletePolygon( 0 );
2359  m_triangulationValid = true;
2360  }
2361 
2362  if( m_triangulationValid )
2363  m_hash = checksum();
2364 }
int OutlineCount() const
Return the number of vertices in a given outline/hole.
bool HasHoles() const
Return true if the polygon set has any holes that share a vertex.
MD5_HASH checksum() const
std::vector< std::unique_ptr< TRIANGULATED_POLYGON > > m_triangulatedPolys
void DeletePolygon(int aIdx)
static void partitionPolyIntoRegularCellGrid(const SHAPE_POLY_SET &aPoly, int aSize, SHAPE_POLY_SET &aOut)
Represent a set of closed polygons.
void Fracture(POLYGON_MODE aFastMode)
Convert a single outline slitted ("fractured") polygon into a set ouf outlines with holes.
POLYGON & Polygon(int aIndex)
bool IsValid() const
Definition: md5_hash.h:24

References checksum(), ClearArcs(), DeletePolygon(), Fracture(), HasHoles(), MD5_HASH::IsValid(), m_hash, m_triangulatedPolys, m_triangulationValid, OutlineCount(), partitionPolyIntoRegularCellGrid(), PM_FAST, and Polygon().

Referenced by FOOTPRINT::BuildPolyCourtyards(), ConvertPolygonToTriangles(), KIGFX::GERBVIEW_PAINTER::draw(), KIGFX::PCB_PAINTER::draw(), Mirror(), polygon_triangulation_main(), Rotate(), and PNS_KICAD_IFACE_BASE::syncZone().

◆ 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_FACESET::NewNode(), IFSG_SHAPE::NewNode(), IFSG_COLORS::SetColorList(), IFSG_COORDS::SetCoordsList(), IFSG_NORMALS::SetNormalList(), SGPOINT::x, SGPOINT::y, and SGPOINT::z.

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

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

◆ Chamfer()

SHAPE_POLY_SET SHAPE_POLY_SET::Chamfer ( int  aDistance)

Return a chamfered version of the polygon set.

Parameters
aDistanceis the chamfering distance.
Returns
A set containing the chamfered version of this set.

Definition at line 1997 of file shape_poly_set.cpp.

1998 {
1999  SHAPE_POLY_SET chamfered;
2000 
2001  for( unsigned int idx = 0; idx < m_polys.size(); idx++ )
2002  chamfered.m_polys.push_back( ChamferPolygon( aDistance, idx ) );
2003 
2004  return chamfered;
2005 }
Represent a set of closed polygons.
POLYGON ChamferPolygon(unsigned int aDistance, int aIndex)
Return a chamfered version of the aIndex-th polygon.

References ChamferPolygon(), and m_polys.

Referenced by ZONE_FILLER::addHatchFillTypeOnZone().

◆ chamferFilletPolygon()

SHAPE_POLY_SET::POLYGON SHAPE_POLY_SET::chamferFilletPolygon ( CORNER_MODE  aMode,
unsigned int  aDistance,
int  aIndex,
int  aErrorMax 
)
private

Return the chamfered or filleted version of the aIndex-th polygon in the set, depending on the aMode selected.

Parameters
aModerepresent which action will be taken: CORNER_MODE::CHAMFERED will return a chamfered version of the polygon, CORNER_MODE::FILLETED will return a filleted version of the polygon.
aDistanceis the chamfering distance if aMode = CHAMFERED; if aMode = FILLETED, is the filleting radius.
aIndexis the index of the polygon that will be chamfered/filleted.
aErrorMaxis the maximum allowable deviation of the polygon from the circle if aMode = FILLETED. If aMode = CHAMFERED, it is unused.
Returns
the chamfered/filleted version of the polygon.Return true if the polygon set has any holes that touch share a vertex.

Definition at line 2019 of file shape_poly_set.cpp.

2022 {
2023  // Null segments create serious issues in calculations. Remove them:
2025 
2026  SHAPE_POLY_SET::POLYGON currentPoly = Polygon( aIndex );
2027  SHAPE_POLY_SET::POLYGON newPoly;
2028 
2029  // If the chamfering distance is zero, then the polygon remain intact.
2030  if( aDistance == 0 )
2031  {
2032  return currentPoly;
2033  }
2034 
2035  // Iterate through all the contours (outline and holes) of the polygon.
2036  for( SHAPE_LINE_CHAIN& currContour : currentPoly )
2037  {
2038  // Generate a new contour in the new polygon
2039  SHAPE_LINE_CHAIN newContour;
2040 
2041  // Iterate through the vertices of the contour
2042  for( int currVertex = 0; currVertex < currContour.PointCount(); currVertex++ )
2043  {
2044  // Current vertex
2045  int x1 = currContour.CPoint( currVertex ).x;
2046  int y1 = currContour.CPoint( currVertex ).y;
2047 
2048  // Indices for previous and next vertices.
2049  int prevVertex;
2050  int nextVertex;
2051 
2052  // Previous and next vertices indices computation. Necessary to manage the edge cases.
2053 
2054  // Previous vertex is the last one if the current vertex is the first one
2055  prevVertex = currVertex == 0 ? currContour.PointCount() - 1 : currVertex - 1;
2056 
2057  // next vertex is the first one if the current vertex is the last one.
2058  nextVertex = currVertex == currContour.PointCount() - 1 ? 0 : currVertex + 1;
2059 
2060  // Previous vertex computation
2061  double xa = currContour.CPoint( prevVertex ).x - x1;
2062  double ya = currContour.CPoint( prevVertex ).y - y1;
2063 
2064  // Next vertex computation
2065  double xb = currContour.CPoint( nextVertex ).x - x1;
2066  double yb = currContour.CPoint( nextVertex ).y - y1;
2067 
2068  // Compute the new distances
2069  double lena = hypot( xa, ya );
2070  double lenb = hypot( xb, yb );
2071 
2072  // Make the final computations depending on the mode selected, chamfered or filleted.
2073  if( aMode == CORNER_MODE::CHAMFERED )
2074  {
2075  double distance = aDistance;
2076 
2077  // Chamfer one half of an edge at most
2078  if( 0.5 * lena < distance )
2079  distance = 0.5 * lena;
2080 
2081  if( 0.5 * lenb < distance )
2082  distance = 0.5 * lenb;
2083 
2084  int nx1 = KiROUND( distance * xa / lena );
2085  int ny1 = KiROUND( distance * ya / lena );
2086 
2087  newContour.Append( x1 + nx1, y1 + ny1 );
2088 
2089  int nx2 = KiROUND( distance * xb / lenb );
2090  int ny2 = KiROUND( distance * yb / lenb );
2091 
2092  newContour.Append( x1 + nx2, y1 + ny2 );
2093  }
2094  else // CORNER_MODE = FILLETED
2095  {
2096  double cosine = ( xa * xb + ya * yb ) / ( lena * lenb );
2097 
2098  double radius = aDistance;
2099  double denom = sqrt( 2.0 / ( 1 + cosine ) - 1 );
2100 
2101  // Do nothing in case of parallel edges
2102  if( std::isinf( denom ) )
2103  continue;
2104 
2105  // Limit rounding distance to one half of an edge
2106  if( 0.5 * lena * denom < radius )
2107  radius = 0.5 * lena * denom;
2108 
2109  if( 0.5 * lenb * denom < radius )
2110  radius = 0.5 * lenb * denom;
2111 
2112  // Calculate fillet arc absolute center point (xc, yx)
2113  double k = radius / sqrt( .5 * ( 1 - cosine ) );
2114  double lenab = sqrt( ( xa / lena + xb / lenb ) * ( xa / lena + xb / lenb ) +
2115  ( ya / lena + yb / lenb ) * ( ya / lena + yb / lenb ) );
2116  double xc = x1 + k * ( xa / lena + xb / lenb ) / lenab;
2117  double yc = y1 + k * ( ya / lena + yb / lenb ) / lenab;
2118 
2119  // Calculate arc start and end vectors
2120  k = radius / sqrt( 2 / ( 1 + cosine ) - 1 );
2121  double xs = x1 + k * xa / lena - xc;
2122  double ys = y1 + k * ya / lena - yc;
2123  double xe = x1 + k * xb / lenb - xc;
2124  double ye = y1 + k * yb / lenb - yc;
2125 
2126  // Cosine of arc angle
2127  double argument = ( xs * xe + ys * ye ) / ( radius * radius );
2128 
2129  // Make sure the argument is in [-1,1], interval in which the acos function is
2130  // defined
2131  if( argument < -1 )
2132  argument = -1;
2133  else if( argument > 1 )
2134  argument = 1;
2135 
2136  double arcAngle = acos( argument );
2137  double arcAngleDegrees = arcAngle * 180.0 / M_PI;
2138  int segments = GetArcToSegmentCount( radius, aErrorMax, arcAngleDegrees );
2139 
2140  double deltaAngle = arcAngle / segments;
2141  double startAngle = atan2( -ys, xs );
2142 
2143  // Flip arc for inner corners
2144  if( xa * yb - ya * xb <= 0 )
2145  deltaAngle *= -1;
2146 
2147  double nx = xc + xs;
2148  double ny = yc + ys;
2149 
2150  newContour.Append( KiROUND( nx ), KiROUND( ny ) );
2151 
2152  // Store the previous added corner to make a sanity check
2153  int prevX = KiROUND( nx );
2154  int prevY = KiROUND( ny );
2155 
2156  for( int j = 0; j < segments; j++ )
2157  {
2158  nx = xc + cos( startAngle + ( j + 1 ) * deltaAngle ) * radius;
2159  ny = yc - sin( startAngle + ( j + 1 ) * deltaAngle ) * radius;
2160 
2161  // Sanity check: the rounding can produce repeated corners; do not add them.
2162  if( KiROUND( nx ) != prevX || KiROUND( ny ) != prevY )
2163  {
2164  newContour.Append( KiROUND( nx ), KiROUND( ny ) );
2165  prevX = KiROUND( nx );
2166  prevY = KiROUND( ny );
2167  }
2168  }
2169  }
2170  }
2171 
2172  // Close the current contour and add it the new polygon
2173  newContour.SetClosed( true );
2174  newPoly.push_back( newContour );
2175  }
2176 
2177  return newPoly;
2178 }
std::vector< SHAPE_LINE_CHAIN > POLYGON
< represents a single polygon outline with holes.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
static float distance(const SFVEC2UI &a, const SFVEC2UI &b)
int RemoveNullSegments()
Look for null segments; ie, segments whose ends are exactly the same and deletes them.
Represent a polyline (an zero-thickness chain of connected line segments).
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:73
POLYGON & Polygon(int aIndex)
int GetArcToSegmentCount(int aRadius, int aErrorMax, double aArcAngleDegree)

References SHAPE_LINE_CHAIN::Append(), SHAPE_LINE_CHAIN::CPoint(), distance(), GetArcToSegmentCount(), KiROUND(), Polygon(), RemoveNullSegments(), SHAPE_LINE_CHAIN::SetClosed(), and VECTOR2< T >::x.

Referenced by ChamferPolygon(), and FilletPolygon().

◆ ChamferPolygon()

SHAPE_POLY_SET::POLYGON SHAPE_POLY_SET::ChamferPolygon ( unsigned int  aDistance,
int  aIndex 
)

Return a chamfered version of the aIndex-th polygon.

Parameters
aDistanceis the chamfering distance.
aIndexis the index of the polygon to be chamfered.
Returns
A polygon containing the chamfered version of the aIndex-th polygon.

Definition at line 1848 of file shape_poly_set.cpp.

1849 {
1850  return chamferFilletPolygon( CHAMFERED, aDistance, aIndex, 0 );
1851 }
POLYGON chamferFilletPolygon(CORNER_MODE aMode, unsigned int aDistance, int aIndex, int aErrorMax)
Return the chamfered or filleted version of the aIndex-th polygon in the set, depending on the aMode ...

References CHAMFERED, and chamferFilletPolygon().

Referenced by Chamfer().

◆ checksum()

MD5_HASH SHAPE_POLY_SET::checksum ( ) const
private

Definition at line 2367 of file shape_poly_set.cpp.

2368 {
2369  MD5_HASH hash;
2370 
2371  hash.Hash( m_polys.size() );
2372 
2373  for( const POLYGON& outline : m_polys )
2374  {
2375  hash.Hash( outline.size() );
2376 
2377  for( const SHAPE_LINE_CHAIN& lc : outline )
2378  {
2379  hash.Hash( lc.PointCount() );
2380 
2381  for( int i = 0; i < lc.PointCount(); i++ )
2382  {
2383  hash.Hash( lc.CPoint( i ).x );
2384  hash.Hash( lc.CPoint( i ).y );
2385  }
2386  }
2387  }
2388 
2389  hash.Finalize();
2390 
2391  return hash;
2392 }
std::vector< SHAPE_LINE_CHAIN > POLYGON
< represents a single polygon outline with holes.
void Hash(uint8_t *data, uint32_t length)
Definition: md5_hash.cpp:65
Represent a polyline (an zero-thickness chain of connected line segments).
void Finalize()
Definition: md5_hash.cpp:75

References MD5_HASH::Finalize(), MD5_HASH::Hash(), and m_polys.

Referenced by CacheTriangulation(), GetHash(), IsTriangulationUpToDate(), and Move().

◆ CHole()

◆ CIterate() [1/3]

CONST_ITERATOR SHAPE_POLY_SET::CIterate ( int  aFirst,
int  aLast,
bool  aIterateHoles = false 
) const
inline

Definition at line 791 of file shape_poly_set.h.

792  {
793  CONST_ITERATOR iter;
794 
795  iter.m_poly = const_cast<SHAPE_POLY_SET*>( this );
796  iter.m_currentPolygon = aFirst;
797  iter.m_lastPolygon = aLast < 0 ? OutlineCount() - 1 : aLast;
798  iter.m_currentContour = 0;
799  iter.m_currentVertex = 0;
800  iter.m_iterateHoles = aIterateHoles;
801 
802  return iter;
803  }
int OutlineCount() const
Return the number of vertices in a given outline/hole.
ITERATOR_TEMPLATE< const VECTOR2I > CONST_ITERATOR

References SHAPE_POLY_SET::ITERATOR_TEMPLATE< T >::m_currentContour, SHAPE_POLY_SET::ITERATOR_TEMPLATE< T >::m_currentPolygon, SHAPE_POLY_SET::ITERATOR_TEMPLATE< T >::m_currentVertex, SHAPE_POLY_SET::ITERATOR_TEMPLATE< T >::m_iterateHoles, SHAPE_POLY_SET::ITERATOR_TEMPLATE< T >::m_lastPolygon, SHAPE_POLY_SET::ITERATOR_TEMPLATE< T >::m_poly, and OutlineCount().

Referenced by ConvertOutlineToPolygon(), EDA_SHAPE::DupPolyPointsList(), EDA_SHAPE::getBoundingBox(), ZONE::GetInteractingZones(), and PNS_KICAD_IFACE_BASE::syncPad().

◆ CIterate() [2/3]

CONST_ITERATOR SHAPE_POLY_SET::CIterate ( int  aOutline) const
inline

Definition at line 805 of file shape_poly_set.h.

806  {
807  return CIterate( aOutline, aOutline );
808  }
CONST_ITERATOR CIterate() const

References CIterate().

◆ CIterate() [3/3]

CONST_ITERATOR SHAPE_POLY_SET::CIterate ( ) const
inline

Definition at line 815 of file shape_poly_set.h.

816  {
817  return CIterate( 0, OutlineCount() - 1 );
818  }
int OutlineCount() const
Return the number of vertices in a given outline/hole.
CONST_ITERATOR CIterate() const

References OutlineCount().

Referenced by CIterate(), and CIterateWithHoles().

◆ CIterateSegments() [1/3]

◆ CIterateSegments() [2/3]

CONST_SEGMENT_ITERATOR SHAPE_POLY_SET::CIterateSegments ( int  aPolygonIdx) const
inline

Return an iterator object, for all outlines in the set (no holes).

Definition at line 884 of file shape_poly_set.h.

References CIterateSegments().

◆ CIterateSegments() [3/3]

CONST_SEGMENT_ITERATOR SHAPE_POLY_SET::CIterateSegments ( ) const
inline

Returns an iterator object, for all outlines in the set (with holes)

Definition at line 896 of file shape_poly_set.h.

References OutlineCount().

Referenced by CIterateSegments(), and CIterateSegmentsWithHoles().

◆ CIterateSegmentsWithHoles() [1/2]

CONST_SEGMENT_ITERATOR SHAPE_POLY_SET::CIterateSegmentsWithHoles ( ) const
inline

Return an iterator object, for the aOutline-th outline in the set (with holes).

Definition at line 914 of file shape_poly_set.h.

References CIterateSegments(), and OutlineCount().

Referenced by CollideEdge(), IsPolygonSelfIntersecting(), and SquaredDistanceToPolygon().

◆ CIterateSegmentsWithHoles() [2/2]

CONST_SEGMENT_ITERATOR SHAPE_POLY_SET::CIterateSegmentsWithHoles ( int  aOutline) const
inline

Definition at line 920 of file shape_poly_set.h.

921  {
922  return CIterateSegments( aOutline, aOutline, true );
923  }
CONST_SEGMENT_ITERATOR CIterateSegments() const
Returns an iterator object, for all outlines in the set (with holes)

References CIterateSegments().

◆ CIterateWithHoles() [1/2]

CONST_ITERATOR SHAPE_POLY_SET::CIterateWithHoles ( int  aOutline) const
inline

Definition at line 810 of file shape_poly_set.h.

811  {
812  return CIterate( aOutline, aOutline, true );
813  }
CONST_ITERATOR CIterate() const

References CIterate().

Referenced by PCB_POINT_EDITOR::buildForPolyOutline(), ZONE::CIterateWithHoles(), and PCB_GRID_HELPER::computeAnchors().

◆ CIterateWithHoles() [2/2]

CONST_ITERATOR SHAPE_POLY_SET::CIterateWithHoles ( ) const
inline

Definition at line 820 of file shape_poly_set.h.

821  {
822  return CIterate( 0, OutlineCount() - 1, true );
823  }
int OutlineCount() const
Return the number of vertices in a given outline/hole.
CONST_ITERATOR CIterate() const

References CIterate(), and OutlineCount().

Referenced by CollideVertex().

◆ ClearArcs()

void SHAPE_POLY_SET::ClearArcs ( )

Appends a vertex at the end of the given outline/hole (default: the last outline)

Definition at line 534 of file shape_poly_set.cpp.

535 {
536  for( POLYGON& poly : m_polys )
537  {
538  for( size_t i = 0; i < poly.size(); i++ )
539  poly[i].ClearArcs();
540  }
541 }
std::vector< SHAPE_LINE_CHAIN > POLYGON
< represents a single polygon outline with holes.
void ClearArcs()
Appends a vertex at the end of the given outline/hole (default: the last outline)

References m_polys.

Referenced by BOOST_AUTO_TEST_CASE(), ZONE::BuildSmoothedPoly(), CacheTriangulation(), CADSTAR_PCB_ARCHIVE_LOADER::getPolySetFromCadstarShape(), and CADSTAR_PCB_ARCHIVE_LOADER::loadCoppers().

◆ Clone()

SHAPE * SHAPE_POLY_SET::Clone ( ) const
overridevirtual

Return a dynamically allocated copy of the shape.

Return values
copyof the shape Creates a new empty polygon in the set and returns its index

Reimplemented from SHAPE.

Definition at line 115 of file shape_poly_set.cpp.

116 {
117  return new SHAPE_POLY_SET( *this );
118 }

References SHAPE_POLY_SET().

◆ 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_POLY_SET::Collide ( const SHAPE aShape,
int  aClearance = 0,
int *  aActual = nullptr,
VECTOR2I aLocation = nullptr 
) const
overridevirtual

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
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 from SHAPE.

Definition at line 1462 of file shape_poly_set.cpp.

1464 {
1465  // A couple of simple cases are worth trying before we fall back on triangulation.
1466 
1467  if( aShape->Type() == SH_SEGMENT )
1468  {
1469  const SHAPE_SEGMENT* segment = static_cast<const SHAPE_SEGMENT*>( aShape );
1470  int extra = segment->GetWidth() / 2;
1471 
1472  if( Collide( segment->GetSeg(), aClearance + extra, aActual, aLocation ) )
1473  {
1474  if( aActual )
1475  *aActual = std::max( 0, *aActual - extra );
1476 
1477  return true;
1478  }
1479 
1480  return false;
1481  }
1482 
1483  if( aShape->Type() == SH_CIRCLE )
1484  {
1485  const SHAPE_CIRCLE* circle = static_cast<const SHAPE_CIRCLE*>( aShape );
1486  int extra = circle->GetRadius();
1487 
1488  if( Collide( circle->GetCenter(), aClearance + extra, aActual, aLocation ) )
1489  {
1490  if( aActual )
1491  *aActual = std::max( 0, *aActual - extra );
1492 
1493  return true;
1494  }
1495 
1496  return false;
1497  }
1498 
1499  const_cast<SHAPE_POLY_SET*>( this )->CacheTriangulation( true );
1500 
1501  int actual = INT_MAX;
1502  VECTOR2I location;
1503 
1504  for( const std::unique_ptr<TRIANGULATED_POLYGON>& tpoly : m_triangulatedPolys )
1505  {
1506  for( const TRIANGULATED_POLYGON::TRI& tri : tpoly->Triangles() )
1507  {
1508  if( aActual || aLocation )
1509  {
1510  int triActual;
1511  VECTOR2I triLocation;
1512 
1513  if( aShape->Collide( &tri, aClearance, &triActual, &triLocation ) )
1514  {
1515  if( triActual < actual )
1516  {
1517  actual = triActual;
1518  location = triLocation;
1519  }
1520  }
1521  }
1522  else // A much faster version of above
1523  {
1524  if( aShape->Collide( &tri, aClearance ) )
1525  return true;
1526  }
1527  }
1528  }
1529 
1530  if( actual < INT_MAX )
1531  {
1532  if( aActual )
1533  *aActual = std::max( 0, actual );
1534 
1535  if( aLocation )
1536  *aLocation = location;
1537 
1538  return true;
1539  }
1540 
1541  return false;
1542 }
int GetRadius() const
Definition: shape_circle.h:107
Define a general 2D-vector/point.
Definition: vector2d.h:61
const VECTOR2I GetCenter() const
Definition: shape_circle.h:112
std::vector< std::unique_ptr< TRIANGULATED_POLYGON > > m_triangulatedPolys
virtual bool Collide(const VECTOR2I &aP, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const
Check if the boundary of shape (this) lies closer to the point aP than aClearance,...
Definition: shape.h:165
const SEG & GetSeg() const
circle
Definition: shape.h:46
bool Collide(const SHAPE *aShape, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
Check if the boundary of shape (this) lies closer to the shape aShape than aClearance,...
int GetWidth() const
SHAPE_TYPE Type() const
Return the type of the shape.
Definition: shape.h:94
line segment
Definition: shape.h:44

References SHAPE::Collide(), SHAPE_CIRCLE::GetCenter(), SHAPE_CIRCLE::GetRadius(), SHAPE_SEGMENT::GetSeg(), SHAPE_SEGMENT::GetWidth(), m_triangulatedPolys, SH_CIRCLE, SH_SEGMENT, and SHAPE_BASE::Type().

Referenced by calcIsInsideArea(), calcIsInsideCourtyard(), DS_DRAW_ITEM_POLYPOLYGONS::HitTest(), EDA_SHAPE::hitTest(), FOOTPRINT::HitTestAccurate(), PCB_SELECTION_TOOL::hitTestDistance(), and DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testCourtyardClearances().

◆ Collide() [3/4]

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

Check whether the point aP is either inside or on the edge of the polygon set.

Note that prior to Jul 2020 we considered the edge to not be part of the polygon. However, most other shapes (rects, circles, segments, etc.) include their edges and the difference was causing issues when used for DRC.

(FWIW, SHAPE_LINE_CHAIN was a split personality, with Collide() including its edges but PointInside() not. That has also been corrected.)

Parameters
aPis the VECTOR2I point whose collision with respect to the poly set will be tested.
aClearanceis the security distance; if the point lies closer to the polygon than aClearance distance, then there is a collision.
aActualan optional pointer to an int to store the actual distance in the event of a collision.
Returns
true if the point aP collides with the polygon; false in any other case.

Reimplemented from SHAPE.

Definition at line 1438 of file shape_poly_set.cpp.

1440 {
1441  if( IsEmpty() || VertexCount() == 0 )
1442  return false;
1443 
1444  VECTOR2I nearest;
1445  ecoord dist_sq = SquaredDistance( aP, aLocation ? &nearest : nullptr );
1446 
1447  if( dist_sq == 0 || dist_sq < SEG::Square( aClearance ) )
1448  {
1449  if( aLocation )
1450  *aLocation = nearest;
1451 
1452  if( aActual )
1453  *aActual = sqrt( dist_sq );
1454 
1455  return true;
1456  }
1457 
1458  return false;
1459 }
bool IsEmpty() const
int VertexCount(int aOutline=-1, int aHole=-1) const
Returns the number of holes in a given outline.
Define a general 2D-vector/point.
Definition: vector2d.h:61
static SEG::ecoord Square(int a)
Definition: seg.h:122
SEG::ecoord SquaredDistance(VECTOR2I aPoint, VECTOR2I *aNearest=nullptr) const
Compute the minimum distance squared between aPoint and all the polygons in the set.
VECTOR2I::extended_type ecoord

References IsEmpty(), SEG::Square(), SquaredDistance(), and VertexCount().

◆ Collide() [4/4]

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

Check whether the segment aSeg collides with the polygon set (or its edge).

Note that prior to Jul 2020 we considered the edge to not be part of the polygon. However, most other shapes (rects, circles, segments, etc.) include their edges and the difference was causing issues when used for DRC.

(FWIW, SHAPE_LINE_CHAIN was a split personality, with Collide() including its edges but PointInside() not. That has also been corrected.)

Parameters
aSegis the SEG segment whose collision with respect to the poly set will be tested.
aClearanceis the security distance; if the segment passes closer to the polygon than aClearance distance, then there is a collision.
aActualan optional pointer to an int to store the actual distance in the event of a collision.
Returns
true if the segment aSeg collides with the polygon, false in any other case.

Implements SHAPE.

Definition at line 1417 of file shape_poly_set.cpp.

1419 {
1420  VECTOR2I nearest;
1421  ecoord dist_sq = SquaredDistance( aSeg, aLocation ? &nearest : nullptr );
1422 
1423  if( dist_sq == 0 || dist_sq < SEG::Square( aClearance ) )
1424  {
1425  if( aLocation )
1426  *aLocation = nearest;
1427 
1428  if( aActual )
1429  *aActual = sqrt( dist_sq );
1430 
1431  return true;
1432  }
1433 
1434  return false;
1435 }
Define a general 2D-vector/point.
Definition: vector2d.h:61
static SEG::ecoord Square(int a)
Definition: seg.h:122
SEG::ecoord SquaredDistance(VECTOR2I aPoint, VECTOR2I *aNearest=nullptr) const
Compute the minimum distance squared between aPoint and all the polygons in the set.
VECTOR2I::extended_type ecoord

References SEG::Square(), and SquaredDistance().

◆ CollideEdge()

bool SHAPE_POLY_SET::CollideEdge ( const VECTOR2I aPoint,
SHAPE_POLY_SET::VERTEX_INDEX aClosestVertex,
int  aClearance = 0 
) const

Check whether aPoint collides with any edge of any of the contours of the polygon.

Parameters
aPointis the VECTOR2I point whose collision with respect to the polygon will be tested.
aClearanceis the security distance; if aPoint lies closer to a vertex than aClearance distance, then there is a collision.
aClosestVertexis the index of the closes vertex to aPoint.
Returns
bool - true if there is a collision, false in any other case.

Definition at line 1671 of file shape_poly_set.cpp.

1674 {
1675  // Shows whether there was a collision
1676  bool collision = false;
1677 
1678  for( CONST_SEGMENT_ITERATOR iterator = CIterateSegmentsWithHoles(); iterator; iterator++ )
1679  {
1680  const SEG currentSegment = *iterator;
1681  int distance = currentSegment.Distance( aPoint );
1682 
1683  // Check for collisions
1684  if( distance <= aClearance )
1685  {
1686  collision = true;
1687 
1688  // Update aClearance to look for closer edges
1689  aClearance = distance;
1690 
1691  // Store the indices that identify the vertex
1692  aClosestVertex = iterator.GetIndex();
1693  }
1694  }
1695 
1696  return collision;
1697 }
int Distance(const SEG &aSeg) const
Compute minimum Euclidean distance to segment aSeg.
Definition: seg.cpp:285
SEGMENT_ITERATOR_TEMPLATE< const SEG > CONST_SEGMENT_ITERATOR
CONST_SEGMENT_ITERATOR CIterateSegmentsWithHoles() const
Return an iterator object, for the aOutline-th outline in the set (with holes).
static float distance(const SFVEC2UI &a, const SFVEC2UI &b)
Definition: seg.h:40

References CIterateSegmentsWithHoles(), SEG::Distance(), and distance().

Referenced by EDA_SHAPE::hitTest(), and ZONE::HitTestForEdge().

◆ CollideVertex()

bool SHAPE_POLY_SET::CollideVertex ( const VECTOR2I aPoint,
SHAPE_POLY_SET::VERTEX_INDEX aClosestVertex,
int  aClearance = 0 
) const

Check whether aPoint collides with any vertex of any of the contours of the polygon.

Parameters
aPointis the VECTOR2I point whose collision with respect to the polygon will be tested.
aClearanceis the security distance; if aPoint lies closer to a vertex than aClearance distance, then there is a collision.
aClosestVertexis the index of the closes vertex to aPoint.
Returns
bool - true if there is a collision, false in any other case.

Definition at line 1632 of file shape_poly_set.cpp.

1635 {
1636  // Shows whether there was a collision
1637  bool collision = false;
1638 
1639  // Difference vector between each vertex and aPoint.
1640  VECTOR2D delta;
1641  double distance, clearance;
1642 
1643  // Convert clearance to double for precision when comparing distances
1644  clearance = aClearance;
1645 
1646  for( CONST_ITERATOR iterator = CIterateWithHoles(); iterator; iterator++ )
1647  {
1648  // Get the difference vector between current vertex and aPoint
1649  delta = *iterator - aPoint;
1650 
1651  // Compute distance
1652  distance = delta.EuclideanNorm();
1653 
1654  // Check for collisions
1655  if( distance <= clearance )
1656  {
1657  collision = true;
1658 
1659  // Update aClearance to look for closer vertices
1660  clearance = distance;
1661 
1662  // Store the indices that identify the vertex
1663  aClosestVertex = iterator.GetIndex();
1664  }
1665  }
1666 
1667  return collision;
1668 }
static float distance(const SFVEC2UI &a, const SFVEC2UI &b)
ITERATOR_TEMPLATE< const VECTOR2I > CONST_ITERATOR
constexpr int delta
CONST_ITERATOR CIterateWithHoles() const

References CIterateWithHoles(), delta, and distance().

Referenced by ZONE::HitTestForCorner().

◆ Contains()

bool SHAPE_POLY_SET::Contains ( const VECTOR2I aP,
int  aSubpolyIndex = -1,
int  aAccuracy = 0,
bool  aUseBBoxCaches = false 
) const

Return true if a given subpolygon contains the point aP.

Parameters
aPis the point to check
aSubpolyIndexis the subpolygon to check, or -1 to check all
aUseBBoxCachesgives faster performance when multiple calls are made with no editing in between, but the caller MUST cache the bbox caches before calling (via BuildBBoxCaches(), above)
Returns
true if the polygon contains the pointReturn true if the set is empty (no polygons at all)

Definition at line 1712 of file shape_poly_set.cpp.

1714 {
1715  if( m_polys.empty() )
1716  return false;
1717 
1718  // If there is a polygon specified, check the condition against that polygon
1719  if( aSubpolyIndex >= 0 )
1720  return containsSingle( aP, aSubpolyIndex, aAccuracy, aUseBBoxCaches );
1721 
1722  // In any other case, check it against all polygons in the set
1723  for( int polygonIdx = 0; polygonIdx < OutlineCount(); polygonIdx++ )
1724  {
1725  if( containsSingle( aP, polygonIdx, aAccuracy, aUseBBoxCaches ) )
1726  return true;
1727  }
1728 
1729  return false;
1730 }
int OutlineCount() const
Return the number of vertices in a given outline/hole.
bool containsSingle(const VECTOR2I &aP, int aSubpolyIndex, int aAccuracy, bool aUseBBoxCaches=false) const
Check whether the point aP is inside the aSubpolyIndex-th polygon of the polyset.

References containsSingle(), m_polys, and OutlineCount().

Referenced by SHAPE_RECT::Collide(), ZONE_FILLER::computeRawFilledArea(), ZONE_FILLER::Fill(), PAD::GetBestAnchorPosition(), CADSTAR_PCB_ARCHIVE_LOADER::getKiCadPad(), GERBER_DRAW_ITEM::HitTest(), ZONE::HitTestFilledArea(), PCB_DIMENSION_BASE::segPolyIntersection(), BOARD::TestZoneIntersection(), PCB_DIM_ALIGNED::updateGeometry(), and PCB_DIM_ORTHOGONAL::updateGeometry().

◆ containsSingle()

bool SHAPE_POLY_SET::containsSingle ( const VECTOR2I aP,
int  aSubpolyIndex,
int  aAccuracy,
bool  aUseBBoxCaches = false 
) const
private

Check whether the point aP is inside the aSubpolyIndex-th polygon of the polyset.

If the points lies on an edge, the polygon is considered to contain it.

Parameters
aPis the VECTOR2I point whose position with respect to the inside of the aSubpolyIndex-th polygon will be tested.
aSubpolyIndexis an integer specifying which polygon in the set has to be checked.
aAccuracyaccuracy in internal units
aUseBBoxCachesgives faster performance when multiple calls are made with no editing in between, but the caller MUST cache the bbox caches before calling (via BuildBBoxCaches(), above)
Returns
true if aP is inside aSubpolyIndex-th polygon; false in any other case.

Definition at line 1768 of file shape_poly_set.cpp.

1770 {
1771  // Check that the point is inside the outline
1772  if( m_polys[aSubpolyIndex][0].PointInside( aP, aAccuracy ) )
1773  {
1774  // Check that the point is not in any of the holes
1775  for( int holeIdx = 0; holeIdx < HoleCount( aSubpolyIndex ); holeIdx++ )
1776  {
1777  const SHAPE_LINE_CHAIN& hole = CHole( aSubpolyIndex, holeIdx );
1778 
1779  // If the point is inside a hole it is outside of the polygon. Do not use aAccuracy
1780  // here as it's meaning would be inverted.
1781  if( hole.PointInside( aP, 1, aUseBBoxCaches ) )
1782  return false;
1783  }
1784 
1785  return true;
1786  }
1787 
1788  return false;
1789 }
const SHAPE_LINE_CHAIN & CHole(int aOutline, int aHole) 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.
int HoleCount(int aOutline) const
Return the reference to aIndex-th outline in the set.
Represent a polyline (an zero-thickness chain of connected line segments).

References CHole(), HoleCount(), m_polys, and SHAPE_LINE_CHAIN_BASE::PointInside().

Referenced by Contains(), and SquaredDistanceToPolygon().

◆ COutline()

const SHAPE_LINE_CHAIN& SHAPE_POLY_SET::COutline ( int  aIndex) const
inline

◆ CPolygon()

◆ CVertex() [1/3]

const VECTOR2I & SHAPE_POLY_SET::CVertex ( int  aIndex,
int  aOutline,
int  aHole 
) const

Return the aGlobalIndex-th vertex in the poly set.

Definition at line 335 of file shape_poly_set.cpp.

336 {
337  if( aOutline < 0 )
338  aOutline += m_polys.size();
339 
340  int idx;
341 
342  if( aHole < 0 )
343  idx = 0;
344  else
345  idx = aHole + 1;
346 
347  assert( aOutline < (int) m_polys.size() );
348  assert( idx < (int) m_polys[aOutline].size() );
349 
350  return m_polys[aOutline][idx].CPoint( aIndex );
351 }

References m_polys.

Referenced by PCB_POINT_EDITOR::addCorner(), EDA_SHAPE::Compare(), CVertex(), D_CODE::DrawFlashedPolygon(), GERBER_FILE_IMAGE::Execute_DCODE_Command(), GERBER_FILE_IMAGE::Execute_G_Command(), findVertex(), ZONE::GetCornerPosition(), EDA_SHAPE::getPosition(), ZONE::HatchBorder(), ZONE::HitTest(), ZONE::MoveEdge(), ZONE::SetCornerPosition(), PCB_POINT_EDITOR::updateItem(), and PCB_POINT_EDITOR::updatePoints().

◆ CVertex() [2/3]

const VECTOR2I & SHAPE_POLY_SET::CVertex ( int  aGlobalIndex) const

Return the index-th vertex in a given hole outline within a given outline.

Definition at line 354 of file shape_poly_set.cpp.

355 {
357 
358  // Assure the passed index references a legal position; abort otherwise
359  if( !GetRelativeIndices( aGlobalIndex, &index ) )
360  throw( std::out_of_range( "aGlobalIndex-th vertex does not exist" ) );
361 
362  return m_polys[index.m_polygon][index.m_contour].CPoint( index.m_vertex );
363 }
Structure to hold the necessary information in order to index a vertex on a SHAPE_POLY_SET object: th...
bool GetRelativeIndices(int aGlobalIdx, VERTEX_INDEX *aRelativeIndices) const
Convert a global vertex index —i.e., a number that globally identifies a vertex in a concatenated lis...

References GetRelativeIndices(), SHAPE_POLY_SET::VERTEX_INDEX::m_contour, SHAPE_POLY_SET::VERTEX_INDEX::m_polygon, m_polys, and SHAPE_POLY_SET::VERTEX_INDEX::m_vertex.

◆ CVertex() [3/3]

const VECTOR2I & SHAPE_POLY_SET::CVertex ( SHAPE_POLY_SET::VERTEX_INDEX  index) const

Definition at line 366 of file shape_poly_set.cpp.

367 {
368  return CVertex( index.m_vertex, index.m_polygon, index.m_contour - 1 );
369 }
const VECTOR2I & CVertex(int aIndex, int aOutline, int aHole) const
Return the aGlobalIndex-th vertex in the poly set.

References CVertex(), SHAPE_POLY_SET::VERTEX_INDEX::m_contour, SHAPE_POLY_SET::VERTEX_INDEX::m_polygon, and SHAPE_POLY_SET::VERTEX_INDEX::m_vertex.

◆ Deflate()

void SHAPE_POLY_SET::Deflate ( int  aAmount,
int  aCircleSegmentsCount,
CORNER_STRATEGY  aCornerStrategy = ROUND_ALL_CORNERS 
)
inline

Definition at line 995 of file shape_poly_set.h.

997  {
998  Inflate( -aAmount, aCircleSegmentsCount, aCornerStrategy );
999  }
void Inflate(int aAmount, int aCircleSegCount, CORNER_STRATEGY aCornerStrategy=ROUND_ALL_CORNERS)
Perform outline inflation/deflation.

References Inflate().

Referenced by ZONE_FILLER::addHatchFillTypeOnZone(), calcIsInsideArea(), ZONE_FILLER::computeRawFilledArea(), KIGFX::PCB_PAINTER::draw(), ZONE_FILLER::fillSingleZone(), PCB_BASE_FRAME::FocusOnItem(), ALTIUM_PCB::ParseRegions6Data(), and PlotSolderMaskLayer().

◆ DeletePolygon()

void SHAPE_POLY_SET::DeletePolygon ( int  aIdx)

Definition at line 1614 of file shape_poly_set.cpp.

1615 {
1616  m_polys.erase( m_polys.begin() + aIdx );
1617 }

References m_polys.

Referenced by ZONE_FILLER::addHatchFillTypeOnZone(), CacheTriangulation(), ZONE_FILLER::Fill(), and PlotStandardLayer().

◆ Fillet()

SHAPE_POLY_SET SHAPE_POLY_SET::Fillet ( int  aRadius,
int  aErrorMax 
)

Return a filleted version of the polygon set.

Parameters
aRadiusis the fillet radius.
aErrorMaxis the maximum allowable deviation of the polygon from the circle
Returns
A set containing the filleted version of this set.

Definition at line 2008 of file shape_poly_set.cpp.

2009 {
2010  SHAPE_POLY_SET filleted;
2011 
2012  for( size_t idx = 0; idx < m_polys.size(); idx++ )
2013  filleted.m_polys.push_back( FilletPolygon( aRadius, aErrorMax, idx ) );
2014 
2015  return filleted;
2016 }
Represent a set of closed polygons.
POLYGON FilletPolygon(unsigned int aRadius, int aErrorMax, int aIndex)
Return a filleted version of the aIndex-th polygon.

References FilletPolygon(), and m_polys.

Referenced by ZONE_FILLER::addHatchFillTypeOnZone().

◆ FilletPolygon()

SHAPE_POLY_SET::POLYGON SHAPE_POLY_SET::FilletPolygon ( unsigned int  aRadius,
int  aErrorMax,
int  aIndex 
)

Return a filleted version of the aIndex-th polygon.

Parameters
aRadiusis the fillet radius.
aErrorMaxis the maximum allowable deviation of the polygon from the circle
aIndexis the index of the polygon to be filleted
Returns
A polygon containing the filleted version of the aIndex-th polygon.

Definition at line 1854 of file shape_poly_set.cpp.

1856 {
1857  return chamferFilletPolygon( FILLETED, aRadius, aIndex, aErrorMax );
1858 }
POLYGON chamferFilletPolygon(CORNER_MODE aMode, unsigned int aDistance, int aIndex, int aErrorMax)
Return the chamfered or filleted version of the aIndex-th polygon in the set, depending on the aMode ...

References chamferFilletPolygon(), and FILLETED.

Referenced by Fillet(), and GEOM_TEST::FilletPolySet().

◆ Format()

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

Reimplemented from SHAPE.

Definition at line 1277 of file shape_poly_set.cpp.

1278 {
1279  std::stringstream ss;
1280 
1281  ss << "SHAPE_LINE_CHAIN poly; \n";
1282 
1283  for( unsigned i = 0; i < m_polys.size(); i++ )
1284  {
1285  for( unsigned j = 0; j < m_polys[i].size(); j++ )
1286  {
1287 
1288  ss << "{ auto tmp = " << m_polys[i][j].Format() << ";\n";
1289 
1290  SHAPE_POLY_SET poly;
1291 
1292  if( j == 0 )
1293  {
1294  ss << " poly.AddOutline(tmp); } \n";
1295  }
1296  else
1297  {
1298  ss << " poly.AddHole(tmp); } \n";
1299  }
1300 
1301  }
1302  }
1303 
1304  return ss.str();
1305 }
Represent a set of closed polygons.

References m_polys.

◆ Fracture()

void SHAPE_POLY_SET::Fracture ( POLYGON_MODE  aFastMode)

Convert a single outline slitted ("fractured") polygon into a set ouf outlines with holes.

Definition at line 1041 of file shape_poly_set.cpp.

1042 {
1043  Simplify( aFastMode ); // remove overlapping holes/degeneracy
1044 
1045  for( POLYGON& paths : m_polys )
1046  fractureSingle( paths );
1047 }
std::vector< SHAPE_LINE_CHAIN > POLYGON
< represents a single polygon outline with holes.
void fractureSingle(POLYGON &paths)
void Simplify(POLYGON_MODE aFastMode)

References fractureSingle(), m_polys, and Simplify().

Referenced by addHoleToPolygon(), PAD::addPadPrimitivesToPolygon(), PAD::AddPrimitivePoly(), CacheTriangulation(), ZONE_FILLER::computeRawFilledArea(), BITMAPCONV_INFO::createOutputData(), CADSTAR_PCB_ARCHIVE_LOADER::drawCadstarShape(), AR_AUTOPLACER::drawPlacementRoutingMatrix(), EXPORTER_PCB_VRML::ExportStandardLayers(), EXPORTER_PCB_VRML::ExportVrmlSolderMask(), AR_AUTOPLACER::fillMatrix(), ZONE_FILLER::fillSingleZone(), APERTURE_MACRO::GetApertureMacroShape(), InflateWithLinkedHoles(), CADSTAR_PCB_ARCHIVE_LOADER::loadCoppers(), FABMASTER::loadFootprints(), EAGLE_PLUGIN::loadPolygon(), FABMASTER::loadShapePolySet(), ALTIUM_PCB::ParseRegions6Data(), BRDITEMS_PLOTTER::PlotFootprintGraphicItem(), BRDITEMS_PLOTTER::PlotPcbShape(), DXF_PLOTTER::PlotPoly(), PlotSolderMaskLayer(), RENDER_3D_RAYTRACE::Reload(), TransformRingToPolygon(), PAD::TransformShapeWithClearanceToPolygon(), ZONE::TransformSmoothedOutlineToPolygon(), and GBR_TO_PCB_EXPORTER::writePcbPolygon().

◆ fractureSingle()

void SHAPE_POLY_SET::fractureSingle ( POLYGON paths)
private

Definition at line 925 of file shape_poly_set.cpp.

926 {
927  FractureEdgeSet edges;
928  FractureEdgeSet border_edges;
929  FractureEdge* root = nullptr;
930 
931  bool first = true;
932 
933  if( paths.size() == 1 )
934  return;
935 
936  int num_unconnected = 0;
937 
938  for( const SHAPE_LINE_CHAIN& path : paths )
939  {
940  const std::vector<VECTOR2I>& points = path.CPoints();
941  int pointCount = points.size();
942 
943  FractureEdge* prev = nullptr, * first_edge = nullptr;
944 
945  int x_min = std::numeric_limits<int>::max();
946 
947  for( int i = 0; i < pointCount; i++ )
948  {
949  if( points[i].x < x_min )
950  x_min = points[i].x;
951 
952  // Do not use path.CPoint() here; open-coding it using the local variables "points"
953  // and "pointCount" gives a non-trivial performance boost to zone fill times.
954  FractureEdge* fe = new FractureEdge( first, points[ i ],
955  points[ i+1 == pointCount ? 0 : i+1 ] );
956 
957  if( !root )
958  root = fe;
959 
960  if( !first_edge )
961  first_edge = fe;
962 
963  if( prev )
964  prev->m_next = fe;
965 
966  if( i == pointCount - 1 )
967  fe->m_next = first_edge;
968 
969  prev = fe;
970  edges.push_back( fe );
971 
972  if( !first )
973  {
974  if( fe->m_p1.x == x_min )
975  border_edges.push_back( fe );
976  }
977 
978  if( !fe->m_connected )
979  num_unconnected++;
980  }
981 
982  first = false; // first path is always the outline
983  }
984 
985  // keep connecting holes to the main outline, until there's no holes left...
986  while( num_unconnected > 0 )
987  {
988  int x_min = std::numeric_limits<int>::max();
989  auto it = border_edges.begin();
990 
991  FractureEdge* smallestX = nullptr;
992 
993  // find the left-most hole edge and merge with the outline
994  for( ; it != border_edges.end(); ++it )
995  {
996  FractureEdge* border_edge = *it;
997  int xt = border_edge->m_p1.x;
998 
999  if( ( xt <= x_min ) && !border_edge->m_connected )
1000  {
1001  x_min = xt;
1002  smallestX = border_edge;
1003  }
1004  }
1005 
1006  int num_processed = processEdge( edges, smallestX );
1007 
1008  // If we can't handle the edge, the zone is broken (maybe)
1009  if( !num_processed )
1010  {
1011  wxLogWarning( "Broken polygon, dropping path" );
1012 
1013  for( FractureEdge* edge : edges )
1014  delete edge;
1015 
1016  return;
1017  }
1018 
1019  num_unconnected -= num_processed;
1020  }
1021 
1022  paths.clear();
1023  SHAPE_LINE_CHAIN newPath;
1024 
1025  newPath.SetClosed( true );
1026 
1027  FractureEdge* e;
1028 
1029  for( e = root; e->m_next != root; e = e->m_next )
1030  newPath.Append( e->m_p1 );
1031 
1032  newPath.Append( e->m_p1 );
1033 
1034  for( FractureEdge* edge : edges )
1035  delete edge;
1036 
1037  paths.push_back( std::move( newPath ) );
1038 }
static int processEdge(FractureEdgeSet &edges, FractureEdge *edge)
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
Represent a polyline (an zero-thickness chain of connected line segments).
FractureEdge * m_next
std::vector< FractureEdge * > FractureEdgeSet

References SHAPE_LINE_CHAIN::Append(), FractureEdge::m_connected, FractureEdge::m_next, FractureEdge::m_p1, path, processEdge(), SHAPE_LINE_CHAIN::SetClosed(), and VECTOR2< T >::x.

Referenced by Fracture().

◆ GetArcs()

void SHAPE_POLY_SET::GetArcs ( std::vector< SHAPE_ARC > &  aArcBuffer) const

Removes all arc references from all the outlines and holes in the polyset.

Definition at line 521 of file shape_poly_set.cpp.

522 {
523  for( const POLYGON& poly : m_polys )
524  {
525  for( size_t i = 0; i < poly.size(); i++ )
526  {
527  for( SHAPE_ARC arc : poly[i].m_arcs )
528  aArcBuffer.push_back( arc );
529  }
530  }
531 }
std::vector< SHAPE_LINE_CHAIN > POLYGON
< represents a single polygon outline with holes.

References m_polys.

Referenced by BOOST_AUTO_TEST_CASE().

◆ GetGlobalIndex()

bool SHAPE_POLY_SET::GetGlobalIndex ( SHAPE_POLY_SET::VERTEX_INDEX  aRelativeIndices,
int &  aGlobalIdx 
) const

Compute the global index of a vertex from the relative indices of polygon, contour and vertex.

Parameters
aRelativeIndicesis the set of relative indices.
aGlobalIdx[out] is the computed global index.
Returns
true if the relative indices are correct; false otherwise. The computed global index is returned in the aGlobalIdx reference.

Definition at line 161 of file shape_poly_set.cpp.

163 {
164  int selectedVertex = aRelativeIndices.m_vertex;
165  unsigned int selectedContour = aRelativeIndices.m_contour;
166  unsigned int selectedPolygon = aRelativeIndices.m_polygon;
167 
168  // Check whether the vertex indices make sense in this poly set
169  if( selectedPolygon < m_polys.size() && selectedContour < m_polys[selectedPolygon].size()
170  && selectedVertex < m_polys[selectedPolygon][selectedContour].PointCount() )
171  {
172  POLYGON currentPolygon;
173 
174  aGlobalIdx = 0;
175 
176  for( unsigned int polygonIdx = 0; polygonIdx < selectedPolygon; polygonIdx++ )
177  {
178  currentPolygon = Polygon( polygonIdx );
179 
180  for( unsigned int contourIdx = 0; contourIdx < currentPolygon.size(); contourIdx++ )
181  aGlobalIdx += currentPolygon[contourIdx].PointCount();
182  }
183 
184  currentPolygon = Polygon( selectedPolygon );
185 
186  for( unsigned int contourIdx = 0; contourIdx < selectedContour; contourIdx++ )
187  aGlobalIdx += currentPolygon[contourIdx].PointCount();
188 
189  aGlobalIdx += selectedVertex;
190 
191  return true;
192  }
193  else
194  {
195  return false;
196  }
197 }
std::vector< SHAPE_LINE_CHAIN > POLYGON
< represents a single polygon outline with holes.
POLYGON & Polygon(int aIndex)

References SHAPE_POLY_SET::VERTEX_INDEX::m_contour, SHAPE_POLY_SET::VERTEX_INDEX::m_polygon, m_polys, SHAPE_POLY_SET::VERTEX_INDEX::m_vertex, and Polygon().

Referenced by GetNeighbourIndexes(), and ZONE::GetSelectedCorner().

◆ GetHash()

MD5_HASH SHAPE_POLY_SET::GetHash ( ) const

Definition at line 2204 of file shape_poly_set.cpp.

2205 {
2206  if( !m_hash.IsValid() )
2207  return checksum();
2208 
2209  return m_hash;
2210 }
MD5_HASH checksum() const
bool IsValid() const
Definition: md5_hash.h:24

References checksum(), MD5_HASH::IsValid(), and m_hash.

Referenced by ZONE::BuildHashValue(), ZONE::GetHashValue(), DSN::SPECCTRA_DB::makePADSTACK(), operator=(), and SHAPE_POLY_SET().

◆ GetIndexableSubshapeCount()

size_t SHAPE_POLY_SET::GetIndexableSubshapeCount ( ) const
overridevirtual

Reimplemented from SHAPE_BASE.

Definition at line 2434 of file shape_poly_set.cpp.

2435 {
2436  size_t n = 0;
2437 
2438  for( const std::unique_ptr<TRIANGULATED_POLYGON>& t : m_triangulatedPolys )
2439  n += t->GetTriangleCount();
2440 
2441  return n;
2442 }
std::vector< std::unique_ptr< TRIANGULATED_POLYGON > > m_triangulatedPolys

References m_triangulatedPolys.

Referenced by GetIndexableSubshapes().

◆ GetIndexableSubshapes()

void SHAPE_POLY_SET::GetIndexableSubshapes ( std::vector< SHAPE * > &  aSubshapes)
overridevirtual

Reimplemented from SHAPE_BASE.

Definition at line 2445 of file shape_poly_set.cpp.

2446 {
2447  aSubshapes.reserve( GetIndexableSubshapeCount() );
2448 
2449  for( const std::unique_ptr<TRIANGULATED_POLYGON>& tpoly : m_triangulatedPolys )
2450  {
2451  for( TRIANGULATED_POLYGON::TRI& tri : tpoly->Triangles() )
2452  aSubshapes.push_back( &tri );
2453  }
2454 }
std::vector< std::unique_ptr< TRIANGULATED_POLYGON > > m_triangulatedPolys
virtual size_t GetIndexableSubshapeCount() const override

References GetIndexableSubshapeCount(), and m_triangulatedPolys.

◆ GetNeighbourIndexes()

bool SHAPE_POLY_SET::GetNeighbourIndexes ( int  aGlobalIndex,
int *  aPrevious,
int *  aNext 
)

Return the global indexes of the previous and the next corner of the aGlobalIndex-th corner of a contour in the polygon set.

They are often aGlobalIndex-1 and aGlobalIndex+1, but not for the first and last corner of the contour.

Parameters
aGlobalIndexis index of the corner, globally indexed between all edges in all contours
aPreviousis the globalIndex of the previous corner of the same contour.
aNextis the globalIndex of the next corner of the same contour.
Returns
true if OK, false if aGlobalIndex is out of range

Definition at line 372 of file shape_poly_set.cpp.

373 {
375 
376  // If the edge does not exist, throw an exception, it is an illegal access memory error
377  if( !GetRelativeIndices( aGlobalIndex, &index ) )
378  return false;
379 
380  // Calculate the previous and next index of aGlobalIndex, corresponding to
381  // the same contour;
382  VERTEX_INDEX inext = index;
383  int lastpoint = m_polys[index.m_polygon][index.m_contour].SegmentCount();
384 
385  if( index.m_vertex == 0 )
386  {
387  index.m_vertex = lastpoint;
388  inext.m_vertex = 1;
389  }
390  else if( index.m_vertex == lastpoint )
391  {
392  index.m_vertex--;
393  inext.m_vertex = 0;
394  }
395  else
396  {
397  inext.m_vertex++;
398  index.m_vertex--;
399  }
400 
401  if( aPrevious )
402  {
403  int previous;
404  GetGlobalIndex( index, previous );
405  *aPrevious = previous;
406  }
407 
408  if( aNext )
409  {
410  int next;
411  GetGlobalIndex( inext, next );
412  *aNext = next;
413  }
414 
415  return true;
416 }
CITER next(CITER it)
Definition: ptree.cpp:126
Structure to hold the necessary information in order to index a vertex on a SHAPE_POLY_SET object: th...
bool GetRelativeIndices(int aGlobalIdx, VERTEX_INDEX *aRelativeIndices) const
Convert a global vertex index —i.e., a number that globally identifies a vertex in a concatenated lis...
bool GetGlobalIndex(VERTEX_INDEX aRelativeIndices, int &aGlobalIdx) const
Compute the global index of a vertex from the relative indices of polygon, contour and vertex.

References GetGlobalIndex(), GetRelativeIndices(), SHAPE_POLY_SET::VERTEX_INDEX::m_contour, SHAPE_POLY_SET::VERTEX_INDEX::m_polygon, m_polys, SHAPE_POLY_SET::VERTEX_INDEX::m_vertex, and next().

Referenced by ZONE::MoveEdge().

◆ GetRelativeIndices()

bool SHAPE_POLY_SET::GetRelativeIndices ( int  aGlobalIdx,
SHAPE_POLY_SET::VERTEX_INDEX aRelativeIndices 
) const

Convert a global vertex index —i.e., a number that globally identifies a vertex in a concatenated list of all vertices in all contours— and get the index of the vertex relative to the contour relative to the polygon in which it is.

Parameters
aGlobalIdxis the global index of the corner whose structured index wants to be found
aRelativeIndicesis a pointer to the set of relative indices to store.
Returns
true if the global index is correct and the information in aRelativeIndices is valid; false otherwise.

Definition at line 121 of file shape_poly_set.cpp.

123 {
124  int polygonIdx = 0;
125  unsigned int contourIdx = 0;
126  int vertexIdx = 0;
127 
128  int currentGlobalIdx = 0;
129 
130  for( polygonIdx = 0; polygonIdx < OutlineCount(); polygonIdx++ )
131  {
132  const POLYGON& currentPolygon = CPolygon( polygonIdx );
133 
134  for( contourIdx = 0; contourIdx < currentPolygon.size(); contourIdx++ )
135  {
136  const SHAPE_LINE_CHAIN& currentContour = currentPolygon[contourIdx];
137  int totalPoints = currentContour.PointCount();
138 
139  for( vertexIdx = 0; vertexIdx < totalPoints; vertexIdx++ )
140  {
141  // Check if the current vertex is the globally indexed as aGlobalIdx
142  if( currentGlobalIdx == aGlobalIdx )
143  {
144  aRelativeIndices->m_polygon = polygonIdx;
145  aRelativeIndices->m_contour = contourIdx;
146  aRelativeIndices->m_vertex = vertexIdx;
147 
148  return true;
149  }
150 
151  // Advance
152  currentGlobalIdx++;
153  }
154  }
155  }
156 
157  return false;
158 }
std::vector< SHAPE_LINE_CHAIN > POLYGON
< represents a single polygon outline with holes.
const POLYGON & CPolygon(int aIndex) const
int OutlineCount() const
Return the number of vertices in a given outline/hole.
int PointCount() const
Return the number of points (vertices) in this line chain.
Represent a polyline (an zero-thickness chain of connected line segments).

References CPolygon(), SHAPE_POLY_SET::VERTEX_INDEX::m_contour, SHAPE_POLY_SET::VERTEX_INDEX::m_polygon, SHAPE_POLY_SET::VERTEX_INDEX::m_vertex, OutlineCount(), and SHAPE_LINE_CHAIN::PointCount().

Referenced by CVertex(), ZONE::GetCornerPosition(), GetNeighbourIndexes(), InsertVertex(), IsVertexInHole(), IterateFromVertexWithHoles(), RemoveVertex(), ZONE::SetCornerPosition(), ZONE::SetSelectedCorner(), and SetVertex().

◆ HasHoles()

bool SHAPE_POLY_SET::HasHoles ( ) const

Return true if the polygon set has any holes that share a vertex.

Definition at line 1212 of file shape_poly_set.cpp.

1213 {
1214  // Iterate through all the polygons on the set
1215  for( const POLYGON& paths : m_polys )
1216  {
1217  // If any of them has more than one contour, it is a hole.
1218  if( paths.size() > 1 )
1219  return true;
1220  }
1221 
1222  // Return false if and only if every polygon has just one outline, without holes.
1223  return false;
1224 }
std::vector< SHAPE_LINE_CHAIN > POLYGON
< represents a single polygon outline with holes.

References m_polys.

Referenced by CacheTriangulation().

◆ HasIndexableSubshapes()

bool SHAPE_POLY_SET::HasIndexableSubshapes ( ) const
overridevirtual

Reimplemented from SHAPE_BASE.

Definition at line 2428 of file shape_poly_set.cpp.

2429 {
2430  return IsTriangulationUpToDate();
2431 }
bool IsTriangulationUpToDate() const

References IsTriangulationUpToDate().

◆ HasTouchingHoles()

bool SHAPE_POLY_SET::HasTouchingHoles ( ) const

Simplify the polyset (merges overlapping polys, eliminates degeneracy/self-intersections) For aFastMode meaning, see function booleanOp.

Definition at line 2395 of file shape_poly_set.cpp.

2396 {
2397  for( int i = 0; i < OutlineCount(); i++ )
2398  {
2399  if( hasTouchingHoles( CPolygon( i ) ) )
2400  return true;
2401  }
2402 
2403  return false;
2404 }
const POLYGON & CPolygon(int aIndex) const
int OutlineCount() const
Return the number of vertices in a given outline/hole.
bool hasTouchingHoles(const POLYGON &aPoly) const

References CPolygon(), hasTouchingHoles(), and OutlineCount().

◆ hasTouchingHoles()

bool SHAPE_POLY_SET::hasTouchingHoles ( const POLYGON aPoly) const
private

Definition at line 2407 of file shape_poly_set.cpp.

2408 {
2409  std::set<long long> ptHashes;
2410 
2411  for( const SHAPE_LINE_CHAIN& lc : aPoly )
2412  {
2413  for( const VECTOR2I& pt : lc.CPoints() )
2414  {
2415  const long long ptHash = (long long) pt.x << 32 | pt.y;
2416 
2417  if( ptHashes.count( ptHash ) > 0 )
2418  return true;
2419 
2420  ptHashes.insert( ptHash );
2421  }
2422  }
2423 
2424  return false;
2425 }
Define a general 2D-vector/point.
Definition: vector2d.h:61
Represent a polyline (an zero-thickness chain of connected line segments).

Referenced by HasTouchingHoles().

◆ Hole()

◆ HoleCount()

◆ importTree()

void SHAPE_POLY_SET::importTree ( ClipperLib::PolyTree *  tree,
const std::vector< CLIPPER_Z_VALUE > &  aZValueBuffer,
const std::vector< SHAPE_ARC > &  aArcBuffe 
)
private

Definition at line 795 of file shape_poly_set.cpp.

798 {
799  m_polys.clear();
800 
801  for( ClipperLib::PolyNode* n = tree->GetFirst(); n; n = n->GetNext() )
802  {
803  if( !n->IsHole() )
804  {
805  POLYGON paths;
806  paths.reserve( n->Childs.size() + 1 );
807 
808  paths.emplace_back( n->Contour, aZValueBuffer, aArcBuffer );
809 
810  for( unsigned int i = 0; i < n->Childs.size(); i++ )
811  paths.emplace_back( n->Childs[i]->Contour, aZValueBuffer, aArcBuffer );
812 
813  m_polys.push_back( paths );
814  }
815  }
816 }
std::vector< SHAPE_LINE_CHAIN > POLYGON
< represents a single polygon outline with holes.

References m_polys.

Referenced by booleanOp(), and Inflate().

◆ Inflate()

void SHAPE_POLY_SET::Inflate ( int  aAmount,
int  aCircleSegCount,
CORNER_STRATEGY  aCornerStrategy = ROUND_ALL_CORNERS 
)

Perform outline inflation/deflation.

Polygons can have holes, but not linked holes with main outlines, if aFactor < 0. For those use InflateWithLinkedHoles() to avoid odd corners where the link segments meet the outline.

Parameters
aAmountis the number of units to offset edges.
aCircleSegCountis the number of segments per 360 degrees to use in curve approx
aCornerStrategyALLOW_ACUTE_CORNERS to preserve all angles, CHAMFER_ACUTE_CORNERS to chop angles less than 90°, ROUND_ACUTE_CORNERS to round off angles less than 90°, ROUND_ALL_CORNERS to round regardless of angles

Definition at line 704 of file shape_poly_set.cpp.

705 {
706  using namespace ClipperLib;
707  // A static table to avoid repetitive calculations of the coefficient
708  // 1.0 - cos( M_PI / aCircleSegCount )
709  // aCircleSegCount is most of time <= 64 and usually 8, 12, 16, 32
710  #define SEG_CNT_MAX 64
711  static double arc_tolerance_factor[SEG_CNT_MAX + 1];
712 
713  ClipperOffset c;
714 
715  // N.B. see the Clipper documentation for jtSquare/jtMiter/jtRound. They are poorly named
716  // and are not what you'd think they are.
717  // http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Types/JoinType.htm
718  JoinType joinType = jtRound; // The way corners are offsetted
719  double miterLimit = 2.0; // Smaller value when using jtMiter for joinType
720  JoinType miterFallback = jtSquare;
721 
722  switch( aCornerStrategy )
723  {
724  case ALLOW_ACUTE_CORNERS:
725  joinType = jtMiter;
726  miterLimit = 10; // Allows large spikes
727  miterFallback = jtSquare;
728  break;
729 
730  case CHAMFER_ACUTE_CORNERS: // Acute angles are chamfered
731  joinType = jtMiter;
732  miterFallback = jtRound;
733  break;
734 
735  case ROUND_ACUTE_CORNERS: // Acute angles are rounded
736  joinType = jtMiter;
737  miterFallback = jtSquare;
738  break;
739 
740  case CHAMFER_ALL_CORNERS: // All angles are chamfered.
741  joinType = jtSquare;
742  miterFallback = jtSquare;
743  break;
744 
745  case ROUND_ALL_CORNERS: // All angles are rounded.
746  joinType = jtRound;
747  miterFallback = jtSquare;
748  break;
749  }
750 
751  std::vector<CLIPPER_Z_VALUE> zValues;
752  std::vector<SHAPE_ARC> arcBuffer;
753 
754  for( const POLYGON& poly : m_polys )
755  {
756  for( size_t i = 0; i < poly.size(); i++ )
757  {
758  c.AddPath( poly[i].convertToClipper( i == 0, zValues, arcBuffer ),
759  joinType, etClosedPolygon );
760  }
761  }
762 
763  PolyTree solution;
764 
765  // Calculate the arc tolerance (arc error) from the seg count by circle. The seg count is
766  // nn = M_PI / acos(1.0 - c.ArcTolerance / abs(aAmount))
767  // http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Classes/ClipperOffset/Properties/ArcTolerance.htm
768 
769  if( aCircleSegCount < 6 ) // avoid incorrect aCircleSegCount values
770  aCircleSegCount = 6;
771 
772  double coeff;
773 
774  if( aCircleSegCount > SEG_CNT_MAX || arc_tolerance_factor[aCircleSegCount] == 0 )
775  {
776  coeff = 1.0 - cos( M_PI / aCircleSegCount );
777 
778  if( aCircleSegCount <= SEG_CNT_MAX )
779  arc_tolerance_factor[aCircleSegCount] = coeff;
780  }
781  else
782  {
783  coeff = arc_tolerance_factor[aCircleSegCount];
784  }
785 
786  c.ArcTolerance = std::abs( aAmount ) * coeff;
787  c.MiterLimit = miterLimit;
788  c.MiterFallback = miterFallback;
789  c.Execute( solution, aAmount );
790 
791  importTree( &solution, zValues, arcBuffer );
792 }
std::vector< SHAPE_LINE_CHAIN > POLYGON
< represents a single polygon outline with holes.
All angles are chamfered.
#define SEG_CNT_MAX
Acute angles are rounded.
Acute angles are chamfered.
just inflate the polygon. Acute angles create spikes
void importTree(ClipperLib::PolyTree *tree, const std::vector< CLIPPER_Z_VALUE > &aZValueBuffer, const std::vector< SHAPE_ARC > &aArcBuffe)

References ALLOW_ACUTE_CORNERS, CHAMFER_ACUTE_CORNERS, CHAMFER_ALL_CORNERS, importTree(), m_polys, ROUND_ACUTE_CORNERS, ROUND_ALL_CORNERS, and SEG_CNT_MAX.

Referenced by FOOTPRINT::BuildPolyCourtyards(), ZONE::BuildSmoothedPoly(), CADSTAR_PCB_ARCHIVE_LOADER::calculateZonePriorities(), ZONE_FILLER::computeRawFilledArea(), BOARD_ADAPTER::createPadWithClearance(), Deflate(), ZONE_FILLER::fillSingleZone(), GERBER_PLOTTER::FlashPadCustom(), GERBER_PLOTTER::FlashPadRoundRect(), CADSTAR_PCB_ARCHIVE_LOADER::getPolySetFromCadstarShape(), InflateWithLinkedHoles(), CADSTAR_PCB_ARCHIVE_LOADER::loadCoppers(), EAGLE_PLUGIN::loadPolygon(), EAGLE_PLUGIN::packagePolygon(), PlotSolderMaskLayer(), PAD::TransformShapeWithClearanceToPolygon(), ZONE::TransformShapeWithClearanceToPolygon(), and ZONE::TransformSmoothedOutlineToPolygon().

◆ InflateWithLinkedHoles()

void SHAPE_POLY_SET::InflateWithLinkedHoles ( int  aFactor,
int  aCircleSegmentsCount,
POLYGON_MODE  aFastMode 
)

Perform outline inflation/deflation, using round corners.

Polygons can have holes and/or linked holes with main outlines. The resulting polygons are also polygons with linked holes to main outlines. For aFastMode meaning, see function booleanOp .Convert a set of polygons with holes to a single outline with "slits"/"fractures" connecting the outer ring to the inner holes For aFastMode meaning, see function booleanOp

Definition at line 695 of file shape_poly_set.cpp.

697 {
698  Simplify( aFastMode );
699  Inflate( aFactor, aCircleSegmentsCount );
700  Fracture( aFastMode );
701 }
void Simplify(POLYGON_MODE aFastMode)
void Fracture(POLYGON_MODE aFastMode)
Convert a single outline slitted ("fractured") polygon into a set ouf outlines with holes.
void Inflate(int aAmount, int aCircleSegCount, CORNER_STRATEGY aCornerStrategy=ROUND_ALL_CORNERS)
Perform outline inflation/deflation.

References Fracture(), Inflate(), and Simplify().

Referenced by PlotStandardLayer(), and ZONE::TransformSolidAreasShapesToPolygon().

◆ InsertVertex()

void SHAPE_POLY_SET::InsertVertex ( int  aGlobalIndex,
const VECTOR2I aNewVertex 
)

Adds a vertex in the globally indexed position aGlobalIndex.

Parameters
aGlobalIndexis the global index of the position in which the new vertex will be inserted.
aNewVertexis the new inserted vertex.Return the index-th vertex in a given hole outline within a given outline

Definition at line 275 of file shape_poly_set.cpp.

276 {
277  VERTEX_INDEX index;
278 
279  if( aGlobalIndex < 0 )
280  aGlobalIndex = 0;
281 
282  if( aGlobalIndex >= TotalVertices() )
283  {
284  Append( aNewVertex );
285  }
286  else
287  {
288  // Assure the position to be inserted exists; throw an exception otherwise
289  if( GetRelativeIndices( aGlobalIndex, &index ) )
290  m_polys[index.m_polygon][index.m_contour].Insert( index.m_vertex, aNewVertex );
291  else
292  throw( std::out_of_range( "aGlobalIndex-th vertex does not exist" ) );
293  }
294 }
int TotalVertices() const
Delete aIdx-th polygon from the set.
bool GetRelativeIndices(int aGlobalIdx, VERTEX_INDEX *aRelativeIndices) const
Convert a global vertex index —i.e., a number that globally identifies a vertex in a concatenated lis...
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Add a new vertex to the contour indexed by aOutline and aHole (defaults to the outline of the last po...

References Append(), GetRelativeIndices(), SHAPE_POLY_SET::VERTEX_INDEX::m_contour, SHAPE_POLY_SET::VERTEX_INDEX::m_polygon, m_polys, SHAPE_POLY_SET::VERTEX_INDEX::m_vertex, and TotalVertices().

Referenced by PCB_POINT_EDITOR::addCorner().

◆ IsEmpty()

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

◆ IsPolygonSelfIntersecting()

bool SHAPE_POLY_SET::IsPolygonSelfIntersecting ( int  aPolygonIndex) const

Check whether the aPolygonIndex-th polygon in the set is self intersecting.

Parameters
aPolygonIndexis the index of the polygon that wants to be checked.
Returns
true if the aPolygonIndex-th polygon is self intersecting, false otherwise.

Definition at line 419 of file shape_poly_set.cpp.

420 {
421  CONST_SEGMENT_ITERATOR iterator = CIterateSegmentsWithHoles( aPolygonIndex );
422  CONST_SEGMENT_ITERATOR innerIterator;
423 
424  for( iterator = CIterateSegmentsWithHoles( aPolygonIndex ); iterator; iterator++ )
425  {
426  SEG firstSegment = *iterator;
427 
428  // Iterate through all remaining segments.
429  innerIterator = iterator;
430 
431  // Start in the next segment, we don't want to check collision between a segment and itself
432  for( innerIterator++; innerIterator; innerIterator++ )
433  {
434  SEG secondSegment = *innerIterator;
435 
436  // Check whether the two segments built collide, only when they are not adjacent.
437  if( !iterator.IsAdjacent( innerIterator ) && firstSegment.Collide( secondSegment, 0 ) )
438  return true;
439  }
440  }
441 
442  return false;
443 }
bool Collide(const SEG &aSeg, int aClearance, int *aActual=nullptr) const
Definition: seg.cpp:189
SEGMENT_ITERATOR_TEMPLATE< const SEG > CONST_SEGMENT_ITERATOR
CONST_SEGMENT_ITERATOR CIterateSegmentsWithHoles() const
Return an iterator object, for the aOutline-th outline in the set (with holes).
Definition: seg.h:40

References CIterateSegmentsWithHoles(), SEG::Collide(), and SHAPE_POLY_SET::SEGMENT_ITERATOR_TEMPLATE< T >::IsAdjacent().

Referenced by IsSelfIntersecting().

◆ IsSelfIntersecting()

bool SHAPE_POLY_SET::IsSelfIntersecting ( ) const

Check whether any of the polygons in the set is self intersecting.

Returns
true if any of the polygons is self intersecting, false otherwise.Return the number of triangulated polygons

Definition at line 446 of file shape_poly_set.cpp.

447 {
448  for( unsigned int polygon = 0; polygon < m_polys.size(); polygon++ )
449  {
450  if( IsPolygonSelfIntersecting( polygon ) )
451  return true;
452  }
453 
454  return false;
455 }
bool IsPolygonSelfIntersecting(int aPolygonIndex) const
Check whether the aPolygonIndex-th polygon in the set is self intersecting.

References IsPolygonSelfIntersecting(), and m_polys.

Referenced by BOARD::NormalizeAreaPolygon(), and PCB_POINT_EDITOR::validatePolygon().

◆ IsSolid()

bool SHAPE_POLY_SET::IsSolid ( ) const
inlineoverridevirtual

Implements SHAPE.

Definition at line 1067 of file shape_poly_set.h.

1068  {
1069  return true;
1070  }

◆ IsTriangulationUpToDate()

bool SHAPE_POLY_SET::IsTriangulationUpToDate ( ) const

Definition at line 2213 of file shape_poly_set.cpp.

2214 {
2215  if( !m_triangulationValid )
2216  return false;
2217 
2218  if( !m_hash.IsValid() )
2219  return false;
2220 
2221  MD5_HASH hash = checksum();
2222 
2223  return hash == m_hash;
2224 }
MD5_HASH checksum() const
bool IsValid() const
Definition: md5_hash.h:24

References checksum(), MD5_HASH::IsValid(), m_hash, and m_triangulationValid.

Referenced by KIGFX::GERBVIEW_PAINTER::draw(), KIGFX::PCB_PAINTER::draw(), KIGFX::OPENGL_GAL::DrawPolygon(), HasIndexableSubshapes(), operator=(), SHAPE_POLY_SET(), and PNS_KICAD_IFACE_BASE::syncZone().

◆ IsVertexInHole()

bool SHAPE_POLY_SET::IsVertexInHole ( int  aGlobalIdx)

Check whether the aGlobalIndex-th vertex belongs to a hole.

Parameters
aGlobalIdxis the index of the vertex.
Returns
true if the globally indexed aGlobalIdx-th vertex belongs to a hole.

Definition at line 1984 of file shape_poly_set.cpp.

1985 {
1986  VERTEX_INDEX index;
1987 
1988  // Get the polygon and contour where the vertex is. If the vertex does not exist, return false
1989  if( !GetRelativeIndices( aGlobalIdx, &index ) )
1990  return false;
1991 
1992  // The contour is a hole if its index is greater than zero
1993  return index.m_contour > 0;
1994 }
bool GetRelativeIndices(int aGlobalIdx, VERTEX_INDEX *aRelativeIndices) const
Convert a global vertex index —i.e., a number that globally identifies a vertex in a concatenated lis...

References GetRelativeIndices(), and SHAPE_POLY_SET::VERTEX_INDEX::m_contour.

◆ Iterate() [1/3]

ITERATOR SHAPE_POLY_SET::Iterate ( int  aFirst,
int  aLast,
bool  aIterateHoles = false 
)
inline

Return an object to iterate through the points of the polygons between aFirst and aLast.

Parameters
aFirstis the first polygon whose points will be iterated.
aLastis the last polygon whose points will be iterated.
aIterateHolesis a flag to indicate whether the points of the holes should be iterated.
Returns
ITERATOR - the iterator object.

Definition at line 738 of file shape_poly_set.h.

739  {
740  ITERATOR iter;
741 
742  iter.m_poly = this;
743  iter.m_currentPolygon = aFirst;
744  iter.m_lastPolygon = aLast < 0 ? OutlineCount() - 1 : aLast;
745  iter.m_currentContour = 0;
746  iter.m_currentVertex = 0;
747  iter.m_iterateHoles = aIterateHoles;
748 
749  return iter;
750  }
int OutlineCount() const
Return the number of vertices in a given outline/hole.
ITERATOR_TEMPLATE< VECTOR2I > ITERATOR

References SHAPE_POLY_SET::ITERATOR_TEMPLATE< T >::m_currentContour, SHAPE_POLY_SET::ITERATOR_TEMPLATE< T >::m_currentPolygon, SHAPE_POLY_SET::ITERATOR_TEMPLATE< T >::m_currentVertex, SHAPE_POLY_SET::ITERATOR_TEMPLATE< T >::m_iterateHoles, SHAPE_POLY_SET::ITERATOR_TEMPLATE< T >::m_lastPolygon, SHAPE_POLY_SET::ITERATOR_TEMPLATE< T >::m_poly, and OutlineCount().

Referenced by PCB_POINT_EDITOR::addCorner(), and ZONE::Iterate().

◆ Iterate() [2/3]

ITERATOR SHAPE_POLY_SET::Iterate ( int  aOutline)
inline
Parameters
aOutlineis the index of the polygon to be iterated.
Returns
an iterator object to visit all points in the main outline of the aOutline-th polygon, without visiting the points in the holes.

Definition at line 757 of file shape_poly_set.h.

758  {
759  return Iterate( aOutline, aOutline );
760  }
ITERATOR Iterate()

References Iterate().

◆ Iterate() [3/3]

ITERATOR SHAPE_POLY_SET::Iterate ( )
inline
Returns
an iterator object to visit all points in all outlines of the set, without visiting the points in the holes.

Definition at line 776 of file shape_poly_set.h.

777  {
778  return Iterate( 0, OutlineCount() - 1 );
779  }
int OutlineCount() const
Return the number of vertices in a given outline/hole.
ITERATOR Iterate()

References OutlineCount().

Referenced by Iterate(), and IterateWithHoles().

◆ IterateFromVertexWithHoles()

ITERATOR SHAPE_POLY_SET::IterateFromVertexWithHoles ( int  aGlobalIdx)
inline

◆ IterateSegments() [1/3]

◆ IterateSegments() [2/3]

SEGMENT_ITERATOR SHAPE_POLY_SET::IterateSegments ( int  aPolygonIdx)
inline

Return an iterator object, for iterating aPolygonIdx-th polygon edges.

Definition at line 878 of file shape_poly_set.h.

References IterateSegments().

◆ IterateSegments() [3/3]

SEGMENT_ITERATOR SHAPE_POLY_SET::IterateSegments ( )
inline

Returns an iterator object, for all outlines in the set (no holes)

Definition at line 890 of file shape_poly_set.h.

References OutlineCount().

Referenced by IterateSegments(), and IterateSegmentsWithHoles().

◆ IterateSegmentsWithHoles() [1/2]

SEGMENT_ITERATOR SHAPE_POLY_SET::IterateSegmentsWithHoles ( )
inline

Return an iterator object, for the aOutline-th outline in the set (with holes).

Definition at line 902 of file shape_poly_set.h.

References IterateSegments(), and OutlineCount().

Referenced by ConvertOutlineToPolygon(), ZONE::HatchBorder(), and BOARD::TestZoneIntersection().

◆ IterateSegmentsWithHoles() [2/2]

SEGMENT_ITERATOR SHAPE_POLY_SET::IterateSegmentsWithHoles ( int  aOutline)
inline

Return an iterator object, for the aOutline-th outline in the set (with holes).

Definition at line 908 of file shape_poly_set.h.

References IterateSegments().

◆ IterateWithHoles() [1/2]

ITERATOR SHAPE_POLY_SET::IterateWithHoles ( int  aOutline)
inline
Parameters
aOutlinethe index of the polygon to be iterated.
Returns
an iterator object to visit all points in the main outline of the aOutline-th polygon, visiting also the points in the holes.

Definition at line 767 of file shape_poly_set.h.

768  {
769  return Iterate( aOutline, aOutline, true );
770  }
ITERATOR Iterate()

References Iterate().

Referenced by findVertex(), ZONE::HatchBorder(), ZONE::IterateWithHoles(), and BOARD::TestZoneIntersection().

◆ IterateWithHoles() [2/2]

ITERATOR SHAPE_POLY_SET::IterateWithHoles ( )
inline
Returns
an iterator object to visit all points in all outlines of the set, visiting also the points in the holes.

Definition at line 785 of file shape_poly_set.h.

786  {
787  return Iterate( 0, OutlineCount() - 1, true );
788  }
int OutlineCount() const
Return the number of vertices in a given outline/hole.
ITERATOR Iterate()

References Iterate(), and OutlineCount().

Referenced by IterateFromVertexWithHoles(), and RemoveNullSegments().

◆ Mirror()

void SHAPE_POLY_SET::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
aRefsets the reference point about which to mirror

Definition at line 1807 of file shape_poly_set.cpp.

1808 {
1809  for( POLYGON& poly : m_polys )
1810  {
1811  for( SHAPE_LINE_CHAIN& path : poly )
1812  path.Mirror( aX, aY, aRef );
1813  }
1814 
1815  if( m_triangulationValid )
1817 }
std::vector< SHAPE_LINE_CHAIN > POLYGON
< represents a single polygon outline with holes.
Represent a polyline (an zero-thickness chain of connected line segments).
void CacheTriangulation(bool aPartition=true)

References CacheTriangulation(), m_polys, m_triangulationValid, and path.

Referenced by GERBER_DRAW_ITEM::ConvertSegmentToPolygon(), FP_SHAPE::Flip(), FOOTPRINT::Flip(), EDA_SHAPE::flip(), FABMASTER::loadFootprints(), FP_SHAPE::Mirror(), and ZONE::Mirror().

◆ Move()

void SHAPE_POLY_SET::Move ( const VECTOR2I aVector)
overridevirtual

Implements SHAPE.

Definition at line 1792 of file shape_poly_set.cpp.

1793 {
1794  for( POLYGON& poly : m_polys )
1795  {
1796  for( SHAPE_LINE_CHAIN& path : poly )
1797  path.Move( aVector );
1798  }
1799 
1800  for( std::unique_ptr<TRIANGULATED_POLYGON>& tri : m_triangulatedPolys )
1801  tri->Move( aVector );
1802 
1803  m_hash = checksum();
1804 }
std::vector< SHAPE_LINE_CHAIN > POLYGON
< represents a single polygon outline with holes.
MD5_HASH checksum() const
std::vector< std::unique_ptr< TRIANGULATED_POLYGON > > m_triangulatedPolys
Represent a polyline (an zero-thickness chain of connected line segments).

References checksum(), m_hash, m_polys, m_triangulatedPolys, and path.

Referenced by ZONE_FILLER::addHatchFillTypeOnZone(), GERBER_DRAW_ITEM::ConvertSegmentToPolygon(), ALTIUM_PCB::HelperShapeSetLocalCoord(), GERBER_DRAW_ITEM::HitTest(), FABMASTER::loadFootprints(), CADSTAR_PCB_ARCHIVE_LOADER::loadLibraryCoppers(), FP_SHAPE::Move(), EDA_SHAPE::move(), ZONE::Move(), GERBER_DRAW_ITEM::MoveAB(), FOOTPRINT::MoveAnchorPosition(), GERBER_DRAW_ITEM::MoveXY(), DS_DRAW_ITEM_POLYPOLYGONS::SetPosition(), FOOTPRINT::SetPosition(), TransformOvalToPolygon(), TransformRoundChamferedRectToPolygon(), PAD::TransformShapeWithClearanceToPolygon(), and TransformTrapezoidToPolygon().

◆ 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(), WRL2FACESET::TranslateToSG(), and X3DIFACESET::TranslateToSG().

◆ NewHole()

int SHAPE_POLY_SET::NewHole ( int  aOutline = -1)

Adds a new outline to the set and returns its index.

Definition at line 212 of file shape_poly_set.cpp.

213 {
214  SHAPE_LINE_CHAIN empty_path;
215 
216  empty_path.SetClosed( true );
217 
218  // Default outline is the last one
219  if( aOutline < 0 )
220  aOutline += m_polys.size();
221 
222  // Add hole to the selected outline
223  m_polys[aOutline].push_back( empty_path );
224 
225  return m_polys.back().size() - 2;
226 }
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
Represent a polyline (an zero-thickness chain of connected line segments).

References m_polys, and SHAPE_LINE_CHAIN::SetClosed().

Referenced by ConvertOutlineToPolygon(), ZONE::NewHole(), and TransformRingToPolygon().

◆ NewOutline()

int SHAPE_POLY_SET::NewOutline ( )

Creates a new hole in a given outline.

Definition at line 200 of file shape_poly_set.cpp.

201 {
202  SHAPE_LINE_CHAIN empty_path;
203  POLYGON poly;
204 
205  empty_path.SetClosed( true );
206  poly.push_back( empty_path );
207  m_polys.push_back( poly );
208  return m_polys.size() - 1;
209 }
std::vector< SHAPE_LINE_CHAIN > POLYGON
< represents a single polygon outline with holes.
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
Represent a polyline (an zero-thickness chain of connected line segments).

References m_polys, and SHAPE_LINE_CHAIN::SetClosed().

Referenced by AR_AUTOPLACER::addFpBody(), addHoleToPolygon(), ZONE_FILLER::addKnockout(), AR_AUTOPLACER::addPad(), LIB_SHAPE::AddPoint(), ZONE::AppendCorner(), EDA_SHAPE::beginEdit(), BuildBoardPolygonOutlines(), BuildFootprintPolygonOutlines(), KI_TEST::CommonTestData::CommonTestData(), ConvertOutlineToPolygon(), GERBER_DRAW_ITEM::ConvertSegmentToPolygon(), D_CODE::ConvertShapeToPolygon(), CornerListToPolygon(), BITMAPCONV_INFO::createOutputData(), BOARD_ADAPTER::createPadWithClearance(), KIGFX::PCB_PAINTER::draw(), KIGFX::GERBVIEW_PAINTER::drawPolygon(), GERBER_FILE_IMAGE::Execute_DCODE_Command(), fillArcPOLY(), PCB_BASE_FRAME::FocusOnItem(), FOOTPRINT::GetBoundingHull(), getRectangleAlongCentreLine(), EDA_SHAPE::hitTest(), FABMASTER::loadFootprints(), EAGLE_PLUGIN::loadPolygon(), FABMASTER::loadShapePolySet(), FABMASTER::loadZone(), LEGACY_PLUGIN::loadZONE_CONTAINER(), PCB_PARSER::parseZONE(), DXF_PLOTTER::PlotPoly(), PlotStandardLayer(), RENDER_3D_OPENGL::reload(), EDA_SHAPE::rotate(), KIGFX::PREVIEW::POLYGON_ITEM::SetPoints(), EDA_SHAPE::SetPolyPoints(), SHAPE_POLY_SET(), DS_DATA_ITEM_POLYGONS::SyncDrawItems(), TransformArcToPolygon(), EDA_TEXT::TransformBoundingBoxWithClearanceToPolygon(), TransformCircleToPolygon(), TransformOvalToPolygon(), EDA_SHAPE::TransformShapeWithClearanceToPolygon(), PCB_DIM_ALIGNED::updateGeometry(), PCB_DIM_ORTHOGONAL::updateGeometry(), PCB_DIM_LEADER::updateGeometry(), and EE_POINT_EDITOR::updateParentItem().

◆ NormalizeAreaOutlines()

int SHAPE_POLY_SET::NormalizeAreaOutlines ( )

Convert a self-intersecting polygon to one (or more) non self-intersecting polygon(s).

Removes null segments.

Returns
the polygon count (always >= 1, because there is at least one polygon) There are new polygons only if the polygon count is > 1.

Definition at line 1244 of file shape_poly_set.cpp.

1245 {
1246  // We are expecting only one main outline, but this main outline can have holes
1247  // if holes: combine holes and remove them from the main outline.
1248  // Note also we are using SHAPE_POLY_SET::PM_STRICTLY_SIMPLE in polygon
1249  // calculations, but it is not mandatory. It is used mainly
1250  // because there is usually only very few vertices in area outlines
1251  SHAPE_POLY_SET::POLYGON& outline = Polygon( 0 );
1252  SHAPE_POLY_SET holesBuffer;
1253 
1254  // Move holes stored in outline to holesBuffer:
1255  // The first SHAPE_LINE_CHAIN is the main outline, others are holes
1256  while( outline.size() > 1 )
1257  {
1258  holesBuffer.AddOutline( outline.back() );
1259  outline.pop_back();
1260  }
1261 
1263 
1264  // If any hole, subtract it to main outline
1265  if( holesBuffer.OutlineCount() )
1266  {
1267  holesBuffer.Simplify( SHAPE_POLY_SET::PM_FAST );
1269  }
1270 
1272 
1273  return OutlineCount();
1274 }
std::vector< SHAPE_LINE_CHAIN > POLYGON
< represents a single polygon outline with holes.
int OutlineCount() const
Return the number of vertices in a given outline/hole.
Represent a set of closed polygons.
void Simplify(POLYGON_MODE aFastMode)
int RemoveNullSegments()
Look for null segments; ie, segments whose ends are exactly the same and deletes them.
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new hole to the given outline (default: last) and returns its index.
void BooleanSubtract(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Perform boolean polyset intersection For aFastMode meaning, see function booleanOp.
POLYGON & Polygon(int aIndex)

References AddOutline(), BooleanSubtract(), OutlineCount(), PM_FAST, PM_STRICTLY_SIMPLE, Polygon(), RemoveNullSegments(), and Simplify().

Referenced by BITMAPCONV_INFO::createOutputData(), and BOARD::NormalizeAreaPolygon().

◆ operator=()

SHAPE_POLY_SET & SHAPE_POLY_SET::operator= ( const SHAPE_POLY_SET aOther)

Definition at line 2181 of file shape_poly_set.cpp.

2182 {
2183  static_cast<SHAPE&>(*this) = aOther;
2184  m_polys = aOther.m_polys;
2185  m_triangulatedPolys.clear();
2186  m_triangulationValid = false;
2187 
2188  if( aOther.IsTriangulationUpToDate() )
2189  {
2190  for( unsigned i = 0; i < aOther.TriangulatedPolyCount(); i++ )
2191  {
2192  const TRIANGULATED_POLYGON* poly = aOther.TriangulatedPolygon( i );
2193  m_triangulatedPolys.push_back( std::make_unique<TRIANGULATED_POLYGON>( *poly ) );
2194  }
2195 
2196  m_hash = aOther.GetHash();
2197  m_triangulationValid = true;
2198  }
2199 
2200  return *this;
2201 }
std::vector< std::unique_ptr< TRIANGULATED_POLYGON > > m_triangulatedPolys
bool IsTriangulationUpToDate() const
MD5_HASH GetHash() const
unsigned int TriangulatedPolyCount() const
Return the number of outlines in the set.
const TRIANGULATED_POLYGON * TriangulatedPolygon(int aIndex) const

References GetHash(), IsTriangulationUpToDate(), m_hash, m_polys, m_triangulatedPolys, m_triangulationValid, TriangulatedPolyCount(), and TriangulatedPolygon().

◆ Outline() [1/2]

SHAPE_LINE_CHAIN& SHAPE_POLY_SET::Outline ( int  aIndex)
inline

Definition at line 665 of file shape_poly_set.h.

666  {
667  return m_polys[aIndex][0];
668  }

References m_polys.

Referenced by EE_POINT_EDITOR::addCorner(), ZONE_FILLER::addHatchFillTypeOnZone(), LIB_SHAPE::AddPoint(), Area(), EDA_SHAPE::beginEdit(), BOOST_AUTO_TEST_CASE(), BuildFootprintPolygonOutlines(), ZONE::BuildSmoothedPoly(), EDA_SHAPE::calcEdit(), calcIsInsideArea(), ZONE::CalculateFilledArea(), PCB_GRID_HELPER::computeAnchors(), EDA_SHAPE::continueEdit(), ConvertPolygonToBlocks(), FOOTPRINT::CoverageRatio(), CONVERT_TOOL::CreateLines(), BITMAPCONV_INFO::createOutputData(), PLACEFILE_GERBER_WRITER::CreatePlaceFile(), DIALOG_PAD_PRIMITIVE_POLY_PROPS::DIALOG_PAD_PRIMITIVE_POLY_PROPS(), KIGFX::DS_PAINTER::draw(), KIGFX::SCH_PAINTER::draw(), KIGFX::PCB_PAINTER::draw(), APERTURE_MACRO::DrawApertureMacroShape(), EDA_SHAPE::endEdit(), DSN::SPECCTRA_DB::fillBOUNDARY(), AR_AUTOPLACER::fillMatrix(), 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(), PCB_IO::format(), formatPoly(), DIALOG_BOARD_STATISTICS::getDataFromPCB(), PCB_SHAPE::GetFocusPosition(), CADSTAR_PCB_ARCHIVE_LOADER::getPolySetFromCadstarShape(), CADSTAR_SCH_ARCHIVE_LOADER::getScaledLibPart(), LIB_SHAPE::GetSelectMenuText(), EDA_SHAPE::hitTest(), GEOM_TEST::IsPolySetValid(), FABMASTER::loadFootprints(), FABMASTER::loadZone(), EDIT_POINTS_FACTORY::Make(), DSN::SPECCTRA_DB::makeIMAGE(), DSN::SPECCTRA_DB::makePADSTACK(), BOARD::NormalizeAreaPolygon(), PCB_PARSER::parseZONE(), LIB_SHAPE::Plot(), PlotDrawingSheet(), BRDITEMS_PLOTTER::PlotFilledAreas(), BRDITEMS_PLOTTER::PlotFootprintGraphicItem(), polygonArea(), LIB_SHAPE::print(), GERBER_DRAW_ITEM::PrintGerberPoly(), DS_DRAW_ITEM_POLYPOLYGONS::PrintWsItem(), RENDER_3D_OPENGL::reload(), EE_POINT_EDITOR::removeCorner(), EE_POINT_EDITOR::removeCornerCondition(), PCB_POINT_EDITOR::removeCornerCondition(), DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run(), EDA_SHAPE::scale(), SHAPE_POLY_SET(), TransformArcToPolygon(), EE_POINT_EDITOR::updatePoints(), GBR_TO_PCB_EXPORTER::writePcbPolygon(), and GBR_TO_PCB_EXPORTER::writePcbZoneItem().

◆ Outline() [2/2]

const SHAPE_LINE_CHAIN& SHAPE_POLY_SET::Outline ( int  aIndex) const
inline

Definition at line 670 of file shape_poly_set.h.

671  {
672  return m_polys[aIndex][0];
673  }

References m_polys.

◆ OutlineCount()

int SHAPE_POLY_SET::OutlineCount ( ) const
inline

Return the number of vertices in a given outline/hole.

Definition at line 647 of file shape_poly_set.h.

References m_polys.

Referenced by PCB_POINT_EDITOR::addCorner(), ZONE_FILLER::addHatchFillTypeOnZone(), PAD::addPadPrimitivesToPolygon(), ZONE::AddPolygon(), BOARD_ADAPTER::addSolidAreasShapes(), TRIANGLE_DISPLAY_LIST::AddToMiddleContourns(), ZONE::AppendCorner(), Area(), booleanOp(), BOOST_AUTO_TEST_CASE(), BOOST_FIXTURE_TEST_CASE(), BuildBBoxCaches(), BuildBoardPolygonOutlines(), BuildConvexHull(), BuildFootprintPolygonOutlines(), CacheTriangulation(), calcIsInsideArea(), ZONE::CalculateFilledArea(), CIterate(), CIterateSegments(), CIterateSegmentsWithHoles(), CIterateWithHoles(), Contains(), ConvertPolygonToBlocks(), RENDER_3D_OPENGL::createBoard(), BITMAPCONV_INFO::createOutputData(), PLACEFILE_GERBER_WRITER::CreatePlaceFile(), CONVERT_TOOL::CreatePolys(), KIGFX::DS_PAINTER::draw(), KIGFX::GERBVIEW_PAINTER::draw(), KIGFX::PCB_PAINTER::draw(), KIGFX::GERBVIEW_PAINTER::drawApertureMacro(), APERTURE_MACRO::DrawApertureMacroShape(), D_CODE::DrawFlashedPolygon(), D_CODE::DrawFlashedShape(), KIGFX::GERBVIEW_PAINTER::drawFlashedShape(), AR_AUTOPLACER::drawPlacementRoutingMatrix(), KIGFX::CAIRO_GAL_BASE::DrawPolygon(), KIGFX::OPENGL_GAL::DrawPolygon(), KIGFX::GERBVIEW_PAINTER::drawPolygon(), KIGFX::PREVIEW::POLYGON_ITEM::drawPreviewShape(), KIGFX::OPENGL_GAL::drawTriangulatedPolyset(), EDA_SHAPE::DupPolyPointsList(), GERBER_FILE_IMAGE::Execute_DCODE_Command(), EXPORTER_PCB_VRML::ExportVrmlBoard(), EXPORTER_PCB_VRML::ExportVrmlPolygonSet(), ZONE_FILLER::Fill(), fillArcPOLY(), DSN::SPECCTRA_DB::fillBOUNDARY(), GEOM_TEST::FilletPolySet(), PSLIKE_PLOTTER::FlashPadCustom(), GERBER_PLOTTER::FlashPadCustom(), HPGL_PLOTTER::FlashPadCustom(), DXF_PLOTTER::FlashPadCustom(), PCB_IO::format(), RENDER_3D_OPENGL::generateHoles(), RENDER_3D_OPENGL::generateLayerList(), RENDER_3D_OPENGL::generateViasAndPads(), APERTURE_MACRO::GetApertureMacroShape(), PAD::GetBestAnchorPosition(), GERBER_DRAW_ITEM::GetBoundingBox(), FOOTPRINT::GetBoundingHull(), DIALOG_BOARD_STATISTICS::getDataFromPCB(), CADSTAR_PCB_ARCHIVE_LOADER::getPolySetFromCadstarShape(), GetRelativeIndices(), HasTouchingHoles(), DS_DRAW_ITEM_POLYPOLYGONS::HitTest(), ZONE::HitTestCutout(), isCopperOutside(), GEOM_TEST::IsPolySetValid(), Iterate(), IterateSegments(), IterateSegmentsWithHoles(), IterateWithHoles(), FABMASTER::loadFootprints(), FABMASTER::loadGraphics(), FABMASTER::loadPolygon(), NormalizeAreaOutlines(), SHAPE_POLY_SET::ITERATOR_TEMPLATE< T >::operator bool(), DIALOG_PAD_PROPERTIES::padValuesOK(), partitionPolyIntoRegularCellGrid(), PlotDrawingSheet(), BRDITEMS_PLOTTER::PlotFilledAreas(), BRDITEMS_PLOTTER::PlotFootprintGraphicItem(), PlotLayerOutlines(), DXF_PLOTTER::PlotPoly(), PlotSolderMaskLayer(), PlotStandardLayer(), polygon_triangulation_main(), polygonArea(), GERBER_DRAW_ITEM::Print(), DS_DRAW_ITEM_POLYPOLYGONS::PrintWsItem(), RENDER_3D_RAYTRACE::Reload(), ZONE::RemoveCutout(), Subset(), PNS_KICAD_IFACE_BASE::syncZone(), TestConcaveSquareFillet(), DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testCourtyardClearances(), TestSquareFillet(), HYPERLYNX_EXPORTER::writeBoardInfo(), HYPERLYNX_EXPORTER::writeNetObjects(), GBR_TO_PCB_EXPORTER::writePcbPolygon(), and GBR_TO_PCB_EXPORTER::writePcbZoneItem().

◆ Parse()

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

Reimplemented from SHAPE.

Definition at line 1308 of file shape_poly_set.cpp.

1309 {
1310  std::string tmp;
1311 
1312  aStream >> tmp;
1313 
1314  if( tmp != "polyset" )
1315  return false;
1316 
1317  aStream >> tmp;
1318 
1319  int n_polys = atoi( tmp.c_str() );
1320 
1321  if( n_polys < 0 )
1322  return false;
1323 
1324  for( int i = 0; i < n_polys; i++ )
1325  {
1326  POLYGON paths;
1327 
1328  aStream >> tmp;
1329 
1330  if( tmp != "poly" )
1331  return false;
1332 
1333  aStream >> tmp;
1334  int n_outlines = atoi( tmp.c_str() );
1335 
1336  if( n_outlines < 0 )
1337  return false;
1338 
1339  for( int j = 0; j < n_outlines; j++ )
1340  {
1341  SHAPE_LINE_CHAIN outline;
1342 
1343  outline.SetClosed( true );
1344 
1345  aStream >> tmp;
1346  int n_vertices = atoi( tmp.c_str() );
1347 
1348  for( int v = 0; v < n_vertices; v++ )
1349  {
1350  VECTOR2I p;
1351 
1352  aStream >> tmp; p.x = atoi( tmp.c_str() );
1353  aStream >> tmp; p.y = atoi( tmp.c_str() );
1354  outline.Append( p );
1355  }
1356 
1357  paths.push_back( outline );
1358  }
1359 
1360  m_polys.push_back( paths );
1361  }
1362 
1363  return true;
1364 }
std::vector< SHAPE_LINE_CHAIN > POLYGON
< represents a single polygon outline with holes.
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.
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
Represent a polyline (an zero-thickness chain of connected line segments).

References SHAPE_LINE_CHAIN::Append(), m_polys, SHAPE_LINE_CHAIN::SetClosed(), VECTOR2< T >::x, and VECTOR2< T >::y.

◆ PointOnEdge()

bool SHAPE_POLY_SET::PointOnEdge ( const VECTOR2I aP) const

Check if point aP lies on an edge or vertex of some of the outlines or holes.

Parameters
aPis the point to check.
Returns
true if the point lies on the edge of any polygon.

Definition at line 1400 of file shape_poly_set.cpp.

1401 {
1402  // Iterate through all the polygons in the set
1403  for( const POLYGON& polygon : m_polys )
1404  {
1405  // Iterate through all the line chains in the polygon
1406  for( const SHAPE_LINE_CHAIN& lineChain : polygon )
1407  {
1408  if( lineChain.PointOnEdge( aP ) )
1409  return true;
1410  }
1411  }
1412 
1413  return false;
1414 }
std::vector< SHAPE_LINE_CHAIN > POLYGON
< represents a single polygon outline with holes.
Represent a polyline (an zero-thickness chain of connected line segments).

References m_polys.

◆ Polygon() [1/2]

◆ Polygon() [2/2]

const POLYGON& SHAPE_POLY_SET::Polygon ( int  aIndex) const
inline

Definition at line 703 of file shape_poly_set.h.

704  {
705  return m_polys[aIndex];
706  }

References m_polys.

◆ RemoveAllContours()

◆ RemoveContour()

void SHAPE_POLY_SET::RemoveContour ( int  aContourIdx,
int  aPolygonIdx = -1 
)

Delete the aContourIdx-th contour of the aPolygonIdx-th polygon in the set.

Parameters
aContourIdxis the index of the contour in the aPolygonIdx-th polygon to be removed.
aPolygonIdxis the index of the polygon in which the to-be-removed contour is. Defaults to the last polygon in the set.

Definition at line 1551 of file shape_poly_set.cpp.

1552 {
1553  // Default polygon is the last one
1554  if( aPolygonIdx < 0 )
1555  aPolygonIdx += m_polys.size();
1556 
1557  m_polys[aPolygonIdx].erase( m_polys[aPolygonIdx].begin() + aContourIdx );
1558 }

References m_polys.

Referenced by PCB_POINT_EDITOR::removeCorner().

◆ RemoveNullSegments()

int SHAPE_POLY_SET::RemoveNullSegments ( )

Look for null segments; ie, segments whose ends are exactly the same and deletes them.

Returns
the number of deleted segments.

Definition at line 1561 of file shape_poly_set.cpp.

1562 {
1563  int removed = 0;
1564 
1565  ITERATOR iterator = IterateWithHoles();
1566 
1567  VECTOR2I contourStart = *iterator;
1568  VECTOR2I segmentStart, segmentEnd;
1569 
1570  VERTEX_INDEX indexStart;
1571 
1572  while( iterator )
1573  {
1574  // Obtain first point and its index
1575  segmentStart = *iterator;
1576  indexStart = iterator.GetIndex();
1577 
1578  // Obtain last point
1579  if( iterator.IsEndContour() )
1580  {
1581  segmentEnd = contourStart;
1582 
1583  // Advance
1584  iterator++;
1585 
1586  if( iterator )
1587  contourStart = *iterator;
1588  }
1589  else
1590  {
1591  // Advance
1592  iterator++;
1593 
1594  if( iterator )
1595  segmentEnd = *iterator;
1596  }
1597 
1598  // Remove segment start if both points are equal
1599  if( segmentStart == segmentEnd )
1600  {
1601  RemoveVertex( indexStart );
1602  removed++;
1603 
1604  // Advance the iterator one position, as there is one vertex less.
1605  if( iterator )
1606  iterator++;
1607  }
1608  }
1609 
1610  return removed;
1611 }
Define a general 2D-vector/point.
Definition: vector2d.h:61
ITERATOR_TEMPLATE< VECTOR2I > ITERATOR
ITERATOR IterateWithHoles()
void RemoveVertex(int aGlobalIndex)
Delete the aGlobalIndex-th vertex.

References SHAPE_POLY_SET::ITERATOR_TEMPLATE< T >::GetIndex(), SHAPE_POLY_SET::ITERATOR_TEMPLATE< T >::IsEndContour(), IterateWithHoles(), and RemoveVertex().

Referenced by chamferFilletPolygon(), and NormalizeAreaOutlines().

◆ RemoveVertex() [1/2]

void SHAPE_POLY_SET::RemoveVertex ( int  aGlobalIndex)

Delete the aGlobalIndex-th vertex.

Parameters
aGlobalIndexis the global index of the to-be-removed vertex.

Definition at line 1733 of file shape_poly_set.cpp.

1734 {
1735  VERTEX_INDEX index;
1736 
1737  // Assure the to be removed vertex exists, abort otherwise
1738  if( GetRelativeIndices( aGlobalIndex, &index ) )
1739  RemoveVertex( index );
1740  else
1741  throw( std::out_of_range( "aGlobalIndex-th vertex does not exist" ) );
1742 }
bool GetRelativeIndices(int aGlobalIdx, VERTEX_INDEX *aRelativeIndices) const
Convert a global vertex index —i.e., a number that globally identifies a vertex in a concatenated lis...
void RemoveVertex(int aGlobalIndex)
Delete the aGlobalIndex-th vertex.

References GetRelativeIndices().

Referenced by PCB_POINT_EDITOR::removeCorner(), and RemoveNullSegments().

◆ RemoveVertex() [2/2]

void SHAPE_POLY_SET::RemoveVertex ( VERTEX_INDEX  aRelativeIndices)

Delete the vertex indexed by aRelativeIndex (index of polygon, contour and vertex).

Parameters
aRelativeIndicesis the set of relative indices of the to-be-removed vertex.Remove all outlines & holes (clears) the polygon set.

Definition at line 1745 of file shape_poly_set.cpp.

1746 {
1747  m_polys[aIndex.m_polygon][aIndex.m_contour].Remove( aIndex.m_vertex );
1748 }

References SHAPE_POLY_SET::VERTEX_INDEX::m_contour, SHAPE_POLY_SET::VERTEX_INDEX::m_polygon, m_polys, and SHAPE_POLY_SET::VERTEX_INDEX::m_vertex.

◆ Rotate()

void SHAPE_POLY_SET::Rotate ( double  aAngle,
const VECTOR2I aCenter = { 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 1820 of file shape_poly_set.cpp.

1821 {
1822  for( POLYGON& poly : m_polys )
1823  {
1824  for( SHAPE_LINE_CHAIN& path : poly )
1825  path.Rotate( aAngle, aCenter );
1826  }
1827 
1828  // Don't re-cache if the triangulation is already invalid
1829  if( m_triangulationValid )
1831 }
std::vector< SHAPE_LINE_CHAIN > POLYGON
< represents a single polygon outline with holes.
Represent a polyline (an zero-thickness chain of connected line segments).
void CacheTriangulation(bool aPartition=true)

References CacheTriangulation(), m_polys, m_triangulationValid, and path.

Referenced by ZONE_FILLER::addHatchFillTypeOnZone(), D_CODE::ConvertShapeToPolygon(), ALTIUM_PCB::HelperShapeSetLocalCoord(), FABMASTER::loadFootprints(), EDA_SHAPE::rotate(), ZONE::Rotate(), FOOTPRINT::SetOrientation(), TransformOvalToPolygon(), TransformRoundChamferedRectToPolygon(), FP_TEXT::TransformShapeWithClearanceToPolygon(), PAD::TransformShapeWithClearanceToPolygon(), TransformTrapezoidToPolygon(), PCB_DIM_ALIGNED::updateGeometry(), PCB_DIM_ORTHOGONAL::updateGeometry(), and PCB_DIM_LEADER::updateGeometry().

◆ SetVertex() [1/2]

void SHAPE_POLY_SET::SetVertex ( const VERTEX_INDEX aIndex,
const VECTOR2I aPos 
)

Accessor function to set the position of a specific point.

Parameters
aIndex#VERTEX_INDEX of the point to move.
aPosdestination position of the specified point.

Definition at line 1762 of file shape_poly_set.cpp.

1763 {
1764  m_polys[aIndex.m_polygon][aIndex.m_contour].SetPoint( aIndex.m_vertex, aPos );
1765 }

References SHAPE_POLY_SET::VERTEX_INDEX::m_contour, SHAPE_POLY_SET::VERTEX_INDEX::m_polygon, m_polys, and SHAPE_POLY_SET::VERTEX_INDEX::m_vertex.

Referenced by ZONE::MoveEdge(), ZONE::SetCornerPosition(), SetVertex(), and PCB_POINT_EDITOR::updateItem().

◆ SetVertex() [2/2]

void SHAPE_POLY_SET::SetVertex ( int  aGlobalIndex,
const VECTOR2I aPos 
)

Set the vertex based on the global index.

Throws if the index doesn't exist.

Parameters
aGlobalIndexglobal index of the to-be-moved vertex
aPosNew position on the vertexReturn total number of vertices stored in the set.

Definition at line 1751 of file shape_poly_set.cpp.

1752 {
1753  VERTEX_INDEX index;
1754 
1755  if( GetRelativeIndices( aGlobalIndex, &index ) )
1756  SetVertex( index, aPos );
1757  else
1758  throw( std::out_of_range( "aGlobalIndex-th vertex does not exist" ) );
1759 }
void SetVertex(const VERTEX_INDEX &aIndex, const VECTOR2I &aPos)
Accessor function to set the position of a specific point.
bool GetRelativeIndices(int aGlobalIdx, VERTEX_INDEX *aRelativeIndices) const
Convert a global vertex index —i.e., a number that globally identifies a vertex in a concatenated lis...

References GetRelativeIndices(), and SetVertex().

◆ Simplify()

◆ SquaredDistance() [1/2]

SEG::ecoord SHAPE_POLY_SET::SquaredDistance ( VECTOR2I  aPoint,
VECTOR2I aNearest = nullptr 
) const

Compute the minimum distance squared between aPoint and all the polygons in the set.

Squared distances are used because they avoid the cost of doing square-roots.

Parameters
aPointis the point whose distance to the set has to be measured.
aNearest[out] an optional pointer to be filled in with the point on the polyset which is closest to aPoint.
Returns
The minimum distance squared between aPoint and all the polygons in the set. If the point is contained in any of the polygons, the distance is zero.

Definition at line 1934 of file shape_poly_set.cpp.

1935 {
1936  SEG::ecoord currentDistance_sq;
1937  SEG::ecoord minDistance_sq = VECTOR2I::ECOORD_MAX;
1938  VECTOR2I nearest;
1939 
1940  // Iterate through all the polygons and get the minimum distance.
1941  for( unsigned int polygonIdx = 0; polygonIdx < m_polys.size(); polygonIdx++ )
1942  {
1943  currentDistance_sq = SquaredDistanceToPolygon( aPoint, polygonIdx,
1944  aNearest ? &nearest : nullptr );
1945 
1946  if( currentDistance_sq < minDistance_sq )
1947  {
1948  if( aNearest )
1949  *aNearest = nearest;
1950 
1951  minDistance_sq = currentDistance_sq;
1952  }
1953  }
1954 
1955  return minDistance_sq;
1956 }
VECTOR2I::extended_type ecoord
Definition: seg.h:43
Define a general 2D-vector/point.
Definition: vector2d.h:61
static constexpr extended_type ECOORD_MAX
Definition: vector2d.h:79
SEG::ecoord SquaredDistanceToPolygon(VECTOR2I aPoint, int aIndex, VECTOR2I *aNearest) const
Compute the minimum distance between the aIndex-th polygon and aPoint.

References VECTOR2< T >::ECOORD_MAX, m_polys, and SquaredDistanceToPolygon().

Referenced by BOOST_AUTO_TEST_CASE(), and Collide().

◆ SquaredDistance() [2/2]

SEG::ecoord SHAPE_POLY_SET::SquaredDistance ( const SEG aSegment,
VECTOR2I aNearest = nullptr 
) const

Compute the minimum distance squared between aSegment and all the polygons in the set.

Squared distances are used because they avoid the cost of doing square-roots.

Parameters
aSegmentis the segment whose distance to the polygon set has to be measured.
aSegmentWidthis the width of the segment; defaults to zero.
aNearest[out] an optional pointer to be filled in with the point on the polyset which is closest to aSegment.
Returns
The minimum distance squared between aSegment and all the polygons in the set. If the point is contained in the polygon, the distance is zero.

Definition at line 1959 of file shape_poly_set.cpp.

1960 {
1961  SEG::ecoord currentDistance_sq;
1962  SEG::ecoord minDistance_sq = VECTOR2I::ECOORD_MAX;
1963  VECTOR2I nearest;
1964 
1965  // Iterate through all the polygons and get the minimum distance.
1966  for( unsigned int polygonIdx = 0; polygonIdx < m_polys.size(); polygonIdx++ )
1967  {
1968  currentDistance_sq = SquaredDistanceToPolygon( aSegment, polygonIdx,
1969  aNearest ? &nearest : nullptr );
1970 
1971  if( currentDistance_sq < minDistance_sq )
1972  {
1973  if( aNearest )
1974  *aNearest = nearest;
1975 
1976  minDistance_sq = currentDistance_sq;
1977  }
1978  }
1979 
1980  return minDistance_sq;
1981 }
VECTOR2I::extended_type ecoord
Definition: seg.h:43
Define a general 2D-vector/point.
Definition: vector2d.h:61
static constexpr extended_type ECOORD_MAX
Definition: vector2d.h:79
SEG::ecoord SquaredDistanceToPolygon(VECTOR2I aPoint, int aIndex, VECTOR2I *aNearest) const
Compute the minimum distance between the aIndex-th polygon and aPoint.

References VECTOR2< T >::ECOORD_MAX, m_polys, and SquaredDistanceToPolygon().

◆ SquaredDistanceToPolygon() [1/2]

SEG::ecoord SHAPE_POLY_SET::SquaredDistanceToPolygon ( VECTOR2I  aPoint,
int  aIndex,
VECTOR2I aNearest 
) const

Compute the minimum distance between the aIndex-th polygon and aPoint.

Parameters
aPointis the point whose distance to the aIndex-th polygon has to be measured.
aIndexis the index of the polygon whose distance to aPoint has to be measured.
aNearest[out] an optional pointer to be filled in with the point on the polyset which is closest to aPoint.
Returns
The minimum distance between aPoint and all the segments of the aIndex-th polygon. If the point is contained in the polygon, the distance is zero.

Definition at line 1861 of file shape_poly_set.cpp.

1863 {
1864  // We calculate the min dist between the segment and each outline segment. However, if the
1865  // segment to test is inside the outline, and does not cross any edge, it can be seen outside
1866  // the polygon. Therefore test if a segment end is inside (testing only one end is enough).
1867  // Use an accuracy of "1" to say that we don't care if it's exactly on the edge or not.
1868  if( containsSingle( aPoint, aPolygonIndex, 1 ) )
1869  {
1870  if( aNearest )
1871  *aNearest = aPoint;
1872 
1873  return 0;
1874  }
1875 
1876  CONST_SEGMENT_ITERATOR iterator = CIterateSegmentsWithHoles( aPolygonIndex );
1877 
1878  SEG::ecoord minDistance = (*iterator).SquaredDistance( aPoint );
1879 
1880  for( iterator++; iterator && minDistance > 0; iterator++ )
1881  {
1882  SEG::ecoord currentDistance = (*iterator).SquaredDistance( aPoint );
1883 
1884  if( currentDistance < minDistance )
1885  {
1886  if( aNearest )
1887  *aNearest = (*iterator).NearestPoint( aPoint );
1888 
1889  minDistance = currentDistance;
1890  }
1891  }
1892 
1893  return minDistance;
1894 }
SEGMENT_ITERATOR_TEMPLATE< const SEG > CONST_SEGMENT_ITERATOR
VECTOR2I::extended_type ecoord
Definition: seg.h:43
CONST_SEGMENT_ITERATOR CIterateSegmentsWithHoles() const
Return an iterator object, for the aOutline-th outline in the set (with holes).
bool containsSingle(const VECTOR2I &aP, int aSubpolyIndex, int aAccuracy, bool aUseBBoxCaches=false) const
Check whether the point aP is inside the aSubpolyIndex-th polygon of the polyset.

References CIterateSegmentsWithHoles(), and containsSingle().

Referenced by SquaredDistance().

◆ SquaredDistanceToPolygon() [2/2]

SEG::ecoord SHAPE_POLY_SET::SquaredDistanceToPolygon ( const SEG aSegment,
int  aIndex,
VECTOR2I aNearest 
) const

Compute the minimum distance between the aIndex-th polygon and aSegment with a possible width.

Parameters
aSegmentis the segment whose distance to the aIndex-th polygon has to be measured.
aIndexis the index of the polygon whose distance to aPoint has to be measured.
aNearest[out] an optional pointer to be filled in with the point on the polyset which is closest to aSegment.
Returns
The minimum distance between aSegment and all the segments of the aIndex-th polygon. If the point is contained in the polygon, the distance is zero.

Definition at line 1897 of file shape_poly_set.cpp.

1899 {
1900  // Check if the segment is fully-contained. If so, its midpoint is a good-enough nearest point.
1901  if( containsSingle( aSegment.A, aPolygonIndex, 1 ) &&
1902  containsSingle( aSegment.B, aPolygonIndex, 1 ) )
1903  {
1904  if( aNearest )
1905  *aNearest = ( aSegment.A + aSegment.B ) / 2;
1906 
1907  return 0;
1908  }
1909 
1910  CONST_SEGMENT_ITERATOR iterator = CIterateSegmentsWithHoles( aPolygonIndex );
1911  SEG::ecoord minDistance = (*iterator).SquaredDistance( aSegment );
1912 
1913  if( aNearest && minDistance == 0 )
1914  *aNearest = ( *iterator ).NearestPoint( aSegment );
1915 
1916  for( iterator++; iterator && minDistance > 0; iterator++ )
1917  {
1918  SEG::ecoord currentDistance = (*iterator).SquaredDistance( aSegment );
1919 
1920  if( currentDistance < minDistance )
1921  {
1922  if( aNearest )
1923  *aNearest = (*iterator).NearestPoint( aSegment );
1924 
1925  minDistance = currentDistance;
1926  }
1927  }
1928 
1929  // Return the maximum of minDistance and zero
1930  return minDistance < 0 ? 0 : minDistance;
1931 }
SEGMENT_ITERATOR_TEMPLATE< const SEG > CONST_SEGMENT_ITERATOR
VECTOR2I::extended_type ecoord
Definition: seg.h:43
CONST_SEGMENT_ITERATOR CIterateSegmentsWithHoles() const
Return an iterator object, for the aOutline-th outline in the set (with holes).
VECTOR2I A
Definition: seg.h:48
bool containsSingle(const VECTOR2I &aP, int aSubpolyIndex, int aAccuracy, bool aUseBBoxCaches=false) const
Check whether the point aP is inside the aSubpolyIndex-th polygon of the polyset.
VECTOR2I B
Definition: seg.h:49

References SEG::A, SEG::B, CIterateSegmentsWithHoles(), and containsSingle().

◆ Subset()

SHAPE_POLY_SET SHAPE_POLY_SET::Subset ( int  aFirstPolygon,
int  aLastPolygon 
)

Return a subset of the polygons in this set, the ones between aFirstPolygon and aLastPolygon.

Parameters
aFirstPolygonis the first polygon to be included in the returned set.
aLastPolygonis the last polygon to be excluded of the returned set.
Returns
a set containing the polygons between aFirstPolygon (included) and aLastPolygon (excluded).

Definition at line 322 of file shape_poly_set.cpp.

323 {
324  assert( aFirstPolygon >= 0 && aLastPolygon <= OutlineCount() );
325 
326  SHAPE_POLY_SET newPolySet;
327 
328  for( int index = aFirstPolygon; index < aLastPolygon; index++ )
329  newPolySet.m_polys.push_back( Polygon( index ) );
330 
331  return newPolySet;
332 }
int OutlineCount() const
Return the number of vertices in a given outline/hole.
Represent a set of closed polygons.
POLYGON & Polygon(int aIndex)

References m_polys, OutlineCount(), and Polygon().

Referenced by UnitSet().

◆ TotalVertices()

int SHAPE_POLY_SET::TotalVertices ( ) const

Delete aIdx-th polygon from the set.

Definition at line 1834 of file shape_poly_set.cpp.

1835 {
1836  int c = 0;
1837 
1838  for( const POLYGON& poly : m_polys )
1839  {
1840  for( const SHAPE_LINE_CHAIN& path : poly )
1841  c += path.PointCount();
1842  }
1843 
1844  return c;
1845 }
std::vector< SHAPE_LINE_CHAIN > POLYGON
< represents a single polygon outline with holes.
Represent a polyline (an zero-thickness chain of connected line segments).

References m_polys, and path.

Referenced by PCB_POINT_EDITOR::buildForPolyOutline(), EDA_SHAPE::Compare(), ZONE::GetNumCorners(), ZONE::HitTest(), InsertVertex(), PCB_POINT_EDITOR::updateItem(), and PCB_POINT_EDITOR::updatePoints().

◆ TriangulatedPolyCount()

unsigned int SHAPE_POLY_SET::TriangulatedPolyCount ( ) const
inline

Return the number of outlines in the set.

Definition at line 644 of file shape_poly_set.h.

References m_triangulatedPolys.

Referenced by ConvertPolygonToTriangles(), KIGFX::OPENGL_GAL::drawTriangulatedPolyset(), operator=(), and SHAPE_POLY_SET().

◆ TriangulatedPolygon()

const TRIANGULATED_POLYGON* SHAPE_POLY_SET::TriangulatedPolygon ( int  aIndex) const
inline

Definition at line 708 of file shape_poly_set.h.

709  {
710  return m_triangulatedPolys[aIndex].get();
711  }
std::vector< std::unique_ptr< TRIANGULATED_POLYGON > > m_triangulatedPolys

References m_triangulatedPolys.

Referenced by ConvertPolygonToTriangles(), KIGFX::OPENGL_GAL::drawTriangulatedPolyset(), operator=(), SHAPE_POLY_SET(), and PNS_KICAD_IFACE_BASE::syncZone().

◆ Type()

SHAPE_TYPE SHAPE_BASE::Type ( ) const
inlineinherited

◆ Unfracture()

void SHAPE_POLY_SET::Unfracture ( POLYGON_MODE  aFastMode)

Return true if the polygon set has any holes.

Definition at line 1227 of file shape_poly_set.cpp.

1228 {
1229  for( POLYGON& path : m_polys )
1231 
1232  Simplify( aFastMode ); // remove overlapping holes/degeneracy
1233 }
std::vector< SHAPE_LINE_CHAIN > POLYGON
< represents a single polygon outline with holes.
void unfractureSingle(POLYGON &path)
void Simplify(POLYGON_MODE aFastMode)

References m_polys, path, Simplify(), and unfractureSingle().

Referenced by PGPartitionFixture::PGPartitionFixture(), and polygon_triangulation_main().

◆ unfractureSingle()

void SHAPE_POLY_SET::unfractureSingle ( SHAPE_POLY_SET::POLYGON aPoly)
private

Definition at line 1050 of file shape_poly_set.cpp.

1051 {
1052  assert( aPoly.size() == 1 );
1053 
1054  struct EDGE
1055  {
1056  int m_index = 0;
1057  SHAPE_LINE_CHAIN* m_poly = nullptr;
1058  bool m_duplicate = false;
1059 
1060  EDGE( SHAPE_LINE_CHAIN* aPolygon, int aIndex ) :
1061  m_index( aIndex ),
1062  m_poly( aPolygon )
1063  {}
1064 
1065  bool compareSegs( const SEG& s1, const SEG& s2 ) const
1066  {
1067  return (s1.A == s2.B && s1.B == s2.A);
1068  }
1069 
1070  bool operator==( const EDGE& aOther ) const
1071  {
1072  return compareSegs( m_poly->CSegment( m_index ),
1073  aOther.m_poly->CSegment( aOther.m_index ) );
1074  }
1075 
1076  bool operator!=( const EDGE& aOther ) const
1077  {
1078  return !compareSegs( m_poly->CSegment( m_index ),
1079  aOther.m_poly->CSegment( aOther.m_index ) );
1080  }
1081 
1082  struct HASH
1083  {
1084  std::size_t operator()( const EDGE& aEdge ) const
1085  {
1086  const SEG& a = aEdge.m_poly->CSegment( aEdge.m_index );
1087 
1088  return (std::size_t) ( a.A.x + a.B.x + a.A.y + a.B.y );
1089  }
1090  };
1091  };
1092 
1093  struct EDGE_LIST_ENTRY
1094  {
1095  int index;
1096  EDGE_LIST_ENTRY* next;
1097  };
1098 
1099  std::unordered_set<EDGE, EDGE::HASH> uniqueEdges;
1100 
1101  SHAPE_LINE_CHAIN lc = aPoly[0];
1102  lc.Simplify();
1103 
1104  auto edgeList = std::make_unique<EDGE_LIST_ENTRY[]>( lc.SegmentCount() );
1105 
1106  for( int i = 0; i < lc.SegmentCount(); i++ )
1107  {
1108  edgeList[i].index = i;
1109  edgeList[i].next = &edgeList[ (i != lc.SegmentCount() - 1) ? i + 1 : 0 ];
1110  }
1111 
1112  std::unordered_set<EDGE_LIST_ENTRY*> queue;
1113 
1114  for( int i = 0; i < lc.SegmentCount(); i++ )
1115  {
1116  EDGE e( &lc, i );
1117  uniqueEdges.insert( e );
1118  }
1119 
1120  for( int i = 0; i < lc.SegmentCount(); i++ )
1121  {
1122  EDGE e( &lc, i );
1123  auto it = uniqueEdges.find( e );
1124 
1125  if( it != uniqueEdges.end() && it->m_index != i )
1126  {
1127  int e1 = it->m_index;
1128  int e2 = i;
1129 
1130  if( e1 > e2 )
1131  std::swap( e1, e2 );
1132 
1133  int e1_prev = e1 - 1;
1134 
1135  if( e1_prev < 0 )
1136  e1_prev = lc.SegmentCount() - 1;
1137 
1138  int e2_prev = e2 - 1;
1139 
1140  if( e2_prev < 0 )
1141  e2_prev = lc.SegmentCount() - 1;
1142 
1143  int e1_next = e1 + 1;
1144 
1145  if( e1_next == lc.SegmentCount() )
1146  e1_next = 0;
1147 
1148  int e2_next = e2 + 1;
1149 
1150  if( e2_next == lc.SegmentCount() )
1151  e2_next = 0;
1152 
1153  edgeList[e1_prev].next = &edgeList[ e2_next ];
1154  edgeList[e2_prev].next = &edgeList[ e1_next ];
1155  edgeList[i].next = nullptr;
1156  edgeList[it->m_index].next = nullptr;
1157  }
1158  }
1159 
1160  for( int i = 0; i < lc.SegmentCount(); i++ )
1161  {
1162  if( edgeList[i].next )
1163  queue.insert( &edgeList[i] );
1164  }
1165 
1166  auto edgeBuf = std::make_unique<EDGE_LIST_ENTRY* []>( lc.SegmentCount() );
1167 
1168  int n = 0;
1169  int outline = -1;
1170 
1171  POLYGON result;
1172 
1173  while( queue.size() )
1174  {
1175  EDGE_LIST_ENTRY* e_first = *queue.begin();
1176  EDGE_LIST_ENTRY* e = e_first;
1177  int cnt = 0;
1178 
1179  do
1180  {
1181  edgeBuf[cnt++] = e;
1182  e = e->next;
1183  } while( e && e != e_first );
1184 
1185  SHAPE_LINE_CHAIN outl;
1186 
1187  for( int i = 0; i < cnt; i++ )
1188  {
1189  VECTOR2I p = lc.CPoint( edgeBuf[i]->index );
1190  outl.Append( p );
1191  queue.erase( edgeBuf[i] );
1192  }
1193 
1194  outl.SetClosed( true );
1195 
1196  bool cw = outl.Area() > 0.0;
1197 
1198  if( cw )
1199  outline = n;
1200 
1201  result.push_back( outl );
1202  n++;
1203  }
1204 
1205  if( outline > 0 )
1206  std::swap( result[0], result[outline] );
1207 
1208  aPoly = result;
1209 }
std::vector< SHAPE_LINE_CHAIN > POLYGON
< represents a single polygon outline with holes.
CITER next(CITER it)
Definition: ptree.cpp:126
SHAPE_LINE_CHAIN & Simplify(bool aRemoveColinear=true)
Simplify the line chain by removing colinear adjacent segments and duplicate vertices.
Define a general 2D-vector/point.
Definition: vector2d.h:61
bool operator!=(const SYMBOL_LIB &aLibrary, const wxString &aName)
double Area(bool aAbsolute=true) const
Return the area of this chain.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
bool operator==(const SYMBOL_LIB &aLibrary, const wxString &aName)
Case insensitive library name comparison.
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.
Represent a polyline (an zero-thickness chain of connected line segments).
VECTOR2I A
Definition: seg.h:48
VECTOR2I B
Definition: seg.h:49

References SEG::A, SHAPE_LINE_CHAIN::Append(), SHAPE_LINE_CHAIN::Area(), SEG::B, SHAPE_LINE_CHAIN::CPoint(), SHAPE_LINE_CHAIN::CSegment(), next(), operator!=(), operator==(), SHAPE_LINE_CHAIN::SegmentCount(), SHAPE_LINE_CHAIN::SetClosed(), SHAPE_LINE_CHAIN::Simplify(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by Unfracture().

◆ UnitSet()

SHAPE_POLY_SET SHAPE_POLY_SET::UnitSet ( int  aPolygonIndex)
inline

Return the reference to aHole-th hole in the aIndex-th outline.

Definition at line 686 of file shape_poly_set.h.

References Subset().

Referenced by BOARD::NormalizeAreaPolygon().

◆ VertexCount()

int SHAPE_POLY_SET::VertexCount ( int  aOutline = -1,
int  aHole = -1 
) const

Returns the number of holes in a given outline.

Definition at line 297 of file shape_poly_set.cpp.

298 {
299  if( m_polys.size() == 0 ) // Empty poly set
300  return 0;
301 
302  if( aOutline < 0 ) // Use last outline
303  aOutline += m_polys.size();
304 
305  int idx;
306 
307  if( aHole < 0 )
308  idx = 0;
309  else
310  idx = aHole + 1;
311 
312  if( aOutline >= (int) m_polys.size() ) // not existing outline
313  return 0;
314 
315  if( idx >= (int) m_polys[aOutline].size() ) // not existing hole
316  return 0;
317 
318  return m_polys[aOutline][idx].PointCount();
319 }

References m_polys.

Referenced by Collide(), D_CODE::DrawFlashedPolygon(), GERBER_FILE_IMAGE::Execute_G_Command(), EDA_SHAPE::GetPointCount(), FABMASTER::loadFootprints(), FABMASTER::loadShapePolySet(), and FABMASTER::loadZone().

Member Data Documentation

◆ m_hash

MD5_HASH SHAPE_POLY_SET::m_hash
private

◆ m_polys

◆ m_triangulatedPolys

std::vector<std::unique_ptr<TRIANGULATED_POLYGON> > SHAPE_POLY_SET::m_triangulatedPolys
private

◆ m_triangulationValid

bool SHAPE_POLY_SET::m_triangulationValid = false
private

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

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


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