KiCad PCB EDA Suite
KIFONT::OUTLINE_GLYPH Class Reference

#include <glyph.h>

Inheritance diagram for KIFONT::OUTLINE_GLYPH:
KIFONT::GLYPH SHAPE_POLY_SET SHAPE SHAPE_BASE

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

 OUTLINE_GLYPH ()
 
 OUTLINE_GLYPH (const OUTLINE_GLYPH &aGlyph)
 
 OUTLINE_GLYPH (const SHAPE_POLY_SET &aPoly)
 
bool IsOutline () const override
 
BOX2D BoundingBox () override
 
void Triangulate (std::function< void(const VECTOR2I &aPt1, const VECTOR2I &aPt2, const VECTOR2I &aPt3)> aCallback) const
 
virtual bool IsStroke () const
 
void CacheTriangulation (bool aPartition=true, bool aSimplify=false)
 Build a polygon triangulation, needed to draw a polygon on OpenGL and in some other calculations. More...
 
bool IsTriangulationUpToDate () const
 
MD5_HASH GetHash () const
 
virtual bool HasIndexableSubshapes () const override
 
virtual size_t GetIndexableSubshapeCount () const override
 
virtual void GetIndexableSubshapes (std::vector< const SHAPE * > &aSubshapes) const 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...
 
SHAPE_POLY_SET CloneDropTriangulation () const
 Creates a new empty polygon in the set and returns its index. 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, double aAccuracy=SHAPE_ARC::DefaultAccuracyForPCB())
 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
 Return the number of points in the shape poly set. More...
 
int FullPointCount () 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 Iterate ()
 
ITERATOR IterateWithHoles (int aOutline)
 
ITERATOR IterateWithHoles ()
 
CONST_ITERATOR CIterate (int aFirst, int aLast, bool aIterateHoles=false) const
 
CONST_ITERATOR CIterate (int aOutline) const
 
CONST_ITERATOR CIterate () const
 
CONST_ITERATOR CIterateWithHoles (int aOutline) 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...
 
SEGMENT_ITERATOR IterateSegments (int aPolygonIdx)
 Return an iterator object, for iterating aPolygonIdx-th polygon edges. More...
 
SEGMENT_ITERATOR IterateSegments ()
 Returns an iterator object, for all outlines in the set (no holes) More...
 
CONST_SEGMENT_ITERATOR CIterateSegments (int aFirst, int aLast, bool aIterateHoles=false) const
 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...
 
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 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 &b, POLYGON_MODE aFastMode)
 Perform boolean polyset intersection 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 &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 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 (bool aCplusPlus=true) 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 (const EDA_ANGLE &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...
 
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...
 
bool CollideVertex (const VECTOR2I &aPoint, VERTEX_INDEX *aClosestVertex=nullptr, 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=nullptr, 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)
 Delete aIdx-th polygon and its triangulation data from the set. More...
 
void DeletePolygonAndTriangulationData (int aIdx, bool aUpdateHash=true)
 
void UpdateTriangulationDataHash ()
 
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...
 
int GetClearance (const SHAPE *aOther) const
 Return the actual minimum distance between two shapes. More...
 
bool IsNull () const
 Return true if the shape is a null shape. More...
 
virtual VECTOR2I Centre () const
 Compute a center-of-mass of the shape. More...
 
FACETNewFacet ()
 
SGNODECalcShape (SGNODE *aParent, SGNODE *aColor, WRL1_ORDER aVertexOrder, float aCreaseLimit=0.74317, bool isVRML2=false)
 
SHAPE_TYPE Type () const
 Return the type of the shape. More...
 
wxString TypeName () const
 

Static Public Member Functions

static const SHAPE_POLY_SET BuildPolysetFromOrientedPaths (const std::vector< SHAPE_LINE_CHAIN > &aPaths, bool aReverseOrientation=false, bool aEvenOdd=false)
 Build a SHAPE_POLY_SET from a bunch of outlines in provided in random order. 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  DROP_TRIANGULATION_FLAG { SINGLETON }
 
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...
 

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 importTree (Clipper2Lib::PolyTree64 &tree, const std::vector< CLIPPER_Z_VALUE > &aZValueBuffer, const std::vector< SHAPE_ARC > &aArcBuffe)
 
void importPaths (Clipper2Lib::Paths64 &paths, const std::vector< CLIPPER_Z_VALUE > &aZValueBuffer, const std::vector< SHAPE_ARC > &aArcBuffe)
 
void importPolyPath (Clipper2Lib::PolyPath64 *aPolyPath, const std::vector< CLIPPER_Z_VALUE > &aZValueBuffer, const std::vector< SHAPE_ARC > &aArcBuffer)
 
void inflate1 (int aAmount, int aCircleSegCount, CORNER_STRATEGY aCornerStrategy)
 
void inflate2 (int aAmount, int aCircleSegCount, CORNER_STRATEGY aCornerStrategy)
 
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, ... and polygon simplification (merging overlapping polygons). More...
 
void booleanOp (ClipperLib::ClipType aType, const SHAPE_POLY_SET &aShape, const SHAPE_POLY_SET &aOtherShape, POLYGON_MODE aFastMode)
 
void booleanOp (Clipper2Lib::ClipType aType, const SHAPE_POLY_SET &aOtherShape)
 
void booleanOp (Clipper2Lib::ClipType aType, const SHAPE_POLY_SET &aShape, const SHAPE_POLY_SET &aOtherShape)
 
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

std::vector< POLYGONm_polys
 
std::vector< std::unique_ptr< TRIANGULATED_POLYGON > > m_triangulatedPolys
 
bool m_triangulationValid = false
 
MD5_HASH m_hash
 
std::list< FACET * > facets
 

Detailed Description

Definition at line 58 of file glyph.h.

Member Typedef Documentation

◆ CONST_ITERATOR

Definition at line 473 of file shape_poly_set.h.

◆ CONST_SEGMENT_ITERATOR

Definition at line 477 of file shape_poly_set.h.

◆ ecoord

typedef VECTOR2I::extended_type SHAPE::ecoord
protectedinherited

Definition at line 249 of file shape.h.

◆ ITERATOR

Definition at line 472 of file shape_poly_set.h.

◆ POLYGON

typedef std::vector<SHAPE_LINE_CHAIN> SHAPE_POLY_SET::POLYGON
inherited

< 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 71 of file shape_poly_set.h.

◆ SEGMENT_ITERATOR

Definition at line 476 of file shape_poly_set.h.

Member Enumeration Documentation

◆ CORNER_MODE

enum SHAPE_POLY_SET::CORNER_MODE
privateinherited

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 1452 of file shape_poly_set.h.

1453 {
1454 CHAMFERED,
1455 FILLETED
1456 };

◆ 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 985 of file shape_poly_set.h.

986 {
995 };
@ 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.
@ ROUND_ALL_CORNERS
All angles are rounded.

◆ DROP_TRIANGULATION_FLAG

Enumerator
SINGLETON 

Definition at line 1385 of file shape_poly_set.h.

◆ 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 952 of file shape_poly_set.h.

953 {
954 PM_FAST = true,
955 PM_STRICTLY_SIMPLE = false
956 };

Constructor & Destructor Documentation

◆ OUTLINE_GLYPH() [1/3]

KIFONT::OUTLINE_GLYPH::OUTLINE_GLYPH ( )
inline

Definition at line 61 of file glyph.h.

61 :
63 {}

◆ OUTLINE_GLYPH() [2/3]

KIFONT::OUTLINE_GLYPH::OUTLINE_GLYPH ( const OUTLINE_GLYPH aGlyph)
inline

Definition at line 65 of file glyph.h.

65 :
66 SHAPE_POLY_SET( aGlyph )
67 {}

◆ OUTLINE_GLYPH() [3/3]

KIFONT::OUTLINE_GLYPH::OUTLINE_GLYPH ( const SHAPE_POLY_SET aPoly)
inline

Definition at line 69 of file glyph.h.

69 :
70 SHAPE_POLY_SET( aPoly )
71 {}

Member Function Documentation

◆ AddHole()

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

Return the area of this poly set.

Definition at line 540 of file shape_poly_set.cpp.

541{
542 assert( m_polys.size() );
543
544 if( aOutline < 0 )
545 aOutline += m_polys.size();
546
547 assert( aOutline < (int)m_polys.size() );
548
549 POLYGON& poly = m_polys[aOutline];
550
551 assert( poly.size() );
552
553 poly.push_back( aHole );
554
555 return poly.size() - 2;
556}
std::vector< SHAPE_LINE_CHAIN > POLYGON
< represents a single polygon outline with holes.
std::vector< POLYGON > m_polys

References SHAPE_POLY_SET::m_polys.

Referenced by ZONE::AddPolygon(), BuildBoardPolygonOutlines(), BuildFootprintPolygonOutlines(), KI_TEST::BuildHollowSquare(), SHAPE_POLY_SET::CacheTriangulation(), KI_TEST::CommonTestData::CommonTestData(), ConvertOutlineToPolygon(), CADSTAR_ARCHIVE_PARSER::SHAPE::ConvertToPolySet(), CADSTAR_PCB_ARCHIVE_LOADER::getPolySetFromCadstarShape(), FABMASTER::loadFootprints(), FABMASTER::loadShapePolySet(), FABMASTER::loadZone(), ALTIUM_PCB::ParseRegions6Data(), and PCB_PARSER::parseRenderCache().

◆ AddOutline()

int SHAPE_POLY_SET::AddOutline ( const SHAPE_LINE_CHAIN aOutline)
inherited

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

Definition at line 526 of file shape_poly_set.cpp.

527{
528 assert( aOutline.IsClosed() );
529
530 POLYGON poly;
531
532 poly.push_back( aOutline );
533
534 m_polys.push_back( poly );
535
536 return m_polys.size() - 1;
537}
bool IsClosed() const override

References SHAPE_LINE_CHAIN::IsClosed(), and SHAPE_POLY_SET::m_polys.

Referenced by ZONE_FILLER::addHatchFillTypeOnZone(), ZONE::AddPolygon(), BOARD_ADAPTER::addText(), BOOST_AUTO_TEST_CASE(), buildBoardBoundingBoxPoly(), KI_TEST::BuildHollowSquare(), KI_TEST::BuildPolyset(), KI_TEST::CommonTestData::CommonTestData(), ConvertOutlineToPolygon(), ConvertPolygonToBlocks(), ALTIUM_PCB::ConvertShapeBasedRegions6ToBoardItem(), ALTIUM_PCB::ConvertShapeBasedRegions6ToFootprintItem(), CADSTAR_ARCHIVE_PARSER::SHAPE::ConvertToPolySet(), FOOTPRINT::CoverageRatio(), BOARD_ADAPTER::createPadWithMargin(), KIGFX::PCB_PAINTER::draw(), KIGFX::GERBVIEW_PAINTER::draw(), ZONE_FILLER::fillCopperZone(), GEOM_TEST::FilletPolySet(), FOOTPRINT::GetBoundingHull(), PNS::SOLID::HoleHull(), PNS::SOLID::Hull(), IteratorFixture::IteratorFixture(), DSN::SPECCTRA_DB::makeIMAGE(), CONVERT_TOOL::makePolysFromChainedSegs(), PAD::MergePrimitivesAsPolygon(), SHAPE_POLY_SET::NormalizeAreaOutlines(), EAGLE_PLUGIN::packagePolygon(), ALTIUM_PCB::ParsePolygons6Data(), ALTIUM_PCB::ParseRegions6Data(), PCB_PARSER::parseRenderCache(), partitionPolyIntoRegularCellGrid(), ZONE_CREATE_HELPER::performZoneCutout(), BRDITEMS_PLOTTER::PlotFootprintShape(), BRDITEMS_PLOTTER::PlotPcbText(), PlotStandardLayer(), SHAPE_POLY_SET::SHAPE_POLY_SET(), TestConcaveSquareFillet(), and TestSquareFillet().

◆ Append() [1/4]

void SHAPE_POLY_SET::Append ( const SHAPE_POLY_SET aSet)
inherited

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

Definition at line 2031 of file shape_poly_set.cpp.

2032{
2033 m_polys.insert( m_polys.end(), aSet.m_polys.begin(), aSet.m_polys.end() );
2034}

References SHAPE_POLY_SET::m_polys.

◆ Append() [2/4]

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

Definition at line 2037 of file shape_poly_set.cpp.

2038{
2039 Append( aP.x, aP.y, aOutline, aHole );
2040}
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 SHAPE_POLY_SET::Append(), VECTOR2< T >::x, and VECTOR2< T >::y.

◆ Append() [3/4]

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

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

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

References SHAPE_POLY_SET::m_polys.

Referenced by AR_AUTOPLACER::addFpBody(), addHoleToPolygon(), ZONE_FILLER::addKnockout(), AR_AUTOPLACER::addPad(), PAD::AddPrimitivePoly(), SHAPE_POLY_SET::Append(), ZONE::AppendCorner(), BOARD::BOARD(), BOOST_AUTO_TEST_CASE(), BuildBoardPolygonOutlines(), ZONE_FILLER::buildCopperItemClearances(), BuildFootprintPolygonOutlines(), TEARDROP_MANAGER::ComputePointsOnPadVia(), GERBER_DRAW_ITEM::ConvertSegmentToPolygon(), D_CODE::ConvertShapeToPolygon(), CornerListToPolygon(), BITMAPCONV_INFO::createOutputData(), BOARD_ADAPTER::createPadWithMargin(), CONVERT_TOOL::CreatePolys(), TEARDROP_MANAGER::createTeardrop(), KIGFX::PCB_PAINTER::draw(), KIGFX::GERBVIEW_PAINTER::drawPolygon(), GERBER_FILE_IMAGE::Execute_DCODE_Command(), GERBER_FILE_IMAGE::Execute_G_Command(), fillArcPOLY(), PCB_BASE_FRAME::FocusOnItems(), FOOTPRINT::GetBoundingHull(), getRectangleAlongCentreLine(), EDA_SHAPE::hitTest(), SHAPE_POLY_SET::InsertVertex(), FABMASTER::loadFootprints(), EAGLE_PLUGIN::loadPolygon(), FABMASTER::loadShapePolySet(), SCH_EAGLE_PLUGIN::loadSymbolPolyLine(), FABMASTER::loadZone(), LEGACY_PLUGIN::loadZONE_CONTAINER(), DSN::SPECCTRA_DB::makeIMAGE(), CONVERT_TOOL::makePolysFromClosedGraphics(), DXF_PLOTTER::PlotPoly(), PlotStandardLayer(), RENDER_3D_OPENGL::reload(), EDA_SHAPE::rotate(), KIGFX::PREVIEW::POLYGON_ITEM::SetPoints(), EDA_SHAPE::SetPolyPoints(), SHAPE_POLY_SET::SHAPE_POLY_SET(), DS_DATA_ITEM_POLYGONS::SyncDrawItems(), TransformArcToPolygon(), EDA_TEXT::TransformBoundingBoxToPolygon(), TransformCircleToPolygon(), TransformOvalToPolygon(), TransformRingToPolygon(), TransformRoundChamferedRectToPolygon(), EDA_SHAPE::TransformShapeToPolygon(), FP_TEXT::TransformShapeToPolygon(), FP_TEXTBOX::TransformShapeToPolygon(), PCB_TEXTBOX::TransformShapeToPolygon(), ZONE::TransformShapeToPolygon(), PAD::TransformShapeToPolygon(), ZONE::TransformSmoothedOutlineToPolygon(), ZONE::TransformSolidAreasShapesToPolygon(), FP_TEXT::TransformTextToPolySet(), FP_TEXTBOX::TransformTextToPolySet(), PCB_TEXT::TransformTextToPolySet(), PCB_TEXTBOX::TransformTextToPolySet(), TransformTrapezoidToPolygon(), PCB_DIM_ALIGNED::updateGeometry(), PCB_DIM_ORTHOGONAL::updateGeometry(), PCB_DIM_RADIAL::updateGeometry(), PCB_DIM_LEADER::updateGeometry(), and EE_POINT_EDITOR::updateParentItem().

◆ Append() [4/4]

int SHAPE_POLY_SET::Append ( SHAPE_ARC aArc,
int  aOutline = -1,
int  aHole = -1,
double  aAccuracy = SHAPE_ARC::DefaultAccuracyForPCB() 
)
inherited

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)
aAccuracyAccuracy of the arc representation in IU
Returns
the number of points in the arc (including the interpolated points from the arc)

Definition at line 276 of file shape_poly_set.cpp.

277{
278 assert( m_polys.size() );
279
280 if( aOutline < 0 )
281 aOutline += m_polys.size();
282
283 int idx;
284
285 if( aHole < 0 )
286 idx = 0;
287 else
288 idx = aHole + 1;
289
290 assert( aOutline < (int) m_polys.size() );
291 assert( idx < (int) m_polys[aOutline].size() );
292
293 m_polys[aOutline][idx].Append( aArc, aAccuracy );
294
295 return m_polys[aOutline][idx].PointCount();
296}

References SHAPE_POLY_SET::m_polys.

◆ ArcCount()

int SHAPE_POLY_SET::ArcCount ( ) const
inherited

Appends all the arcs in this polyset to aArcBuffer.

Definition at line 575 of file shape_poly_set.cpp.

576{
577 int retval = 0;
578
579 for( const POLYGON& poly : m_polys )
580 {
581 for( size_t i = 0; i < poly.size(); i++ )
582 retval += poly[i].ArcCount();
583 }
584
585 return retval;
586}
int ArcCount() const
Appends all the arcs in this polyset to aArcBuffer.

References SHAPE_POLY_SET::ArcCount(), and SHAPE_POLY_SET::m_polys.

Referenced by SHAPE_POLY_SET::ArcCount(), and SHAPE_POLY_SET::booleanOp().

◆ Area()

double SHAPE_POLY_SET::Area ( )
inherited

Count the number of arc shapes present.

Definition at line 559 of file shape_poly_set.cpp.

560{
561 double area = 0.0;
562
563 for( int i = 0; i < OutlineCount(); i++ )
564 {
565 area += Outline( i ).Area();
566
567 for( int j = 0; j < HoleCount( i ); j++ )
568 area -= Hole( i, j ).Area();
569 }
570
571 return area;
572}
double Area(bool aAbsolute=true) const
Return the area of this chain.
int HoleCount(int aOutline) const
Return the reference to aIndex-th outline in the set.
SHAPE_LINE_CHAIN & Outline(int aIndex)
SHAPE_LINE_CHAIN & Hole(int aOutline, int aHole)
Return the aIndex-th subpolygon in the set.
int OutlineCount() const
Return the number of vertices in a given outline/hole.

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

Referenced by BOOST_AUTO_TEST_CASE(), ZONE::CalculateOutlineArea(), CADSTAR_PCB_ARCHIVE_LOADER::calculateZonePriorities(), polygonArea(), and DRC_TEST_PROVIDER_TEXT_DIMS::Run().

◆ BBox()

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

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

1745{
1746 BOX2I bb;
1747
1748 for( unsigned i = 0; i < m_polys.size(); i++ )
1749 {
1750 if( i == 0 )
1751 bb = m_polys[i][0].BBox();
1752 else
1753 bb.Merge( m_polys[i][0].BBox() );
1754 }
1755
1756 bb.Inflate( aClearance );
1757 return bb;
1758}
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:506
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: box2.h:588
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.

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

Referenced by ZONE_FILLER::addHatchFillTypeOnZone(), SHAPE_POLY_SET::BBox(), BoundingBox(), ZONE::CacheBoundingBox(), DRAWING_TOOL::DrawBoardCharacteristics(), PCB_BASE_FRAME::FocusOnItems(), PAD::GetBestAnchorPosition(), GERBER_DRAW_ITEM::GetBoundingBox(), DS_DRAW_ITEM_POLYPOLYGONS::GetBoundingBox(), ZONE::GetBoundingBox(), D_CODE::GetShapeDim(), partitionPolyIntoRegularCellGrid(), KIGFX::VIEW::SetCenter(), BOARD::TestZoneIntersection(), KIGFX::PREVIEW::CENTRELINE_RECT_ITEM::ViewBBox(), KIGFX::PREVIEW::POLYGON_ITEM::ViewBBox(), and GERBER_DRAW_ITEM::ViewGetLOD().

◆ BBoxFromCaches()

const BOX2I SHAPE_POLY_SET::BBoxFromCaches ( ) const
inherited

Definition at line 1761 of file shape_poly_set.cpp.

1762{
1763 BOX2I bb;
1764
1765 for( unsigned i = 0; i < m_polys.size(); i++ )
1766 {
1767 if( i == 0 )
1768 bb = *m_polys[i][0].GetCachedBBox();
1769 else
1770 bb.Merge( *m_polys[i][0].GetCachedBBox() );
1771 }
1772
1773 return bb;
1774}

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

Referenced by DRC_INTERACTIVE_COURTYARD_CLEARANCE::testCourtyardClearances(), and DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testCourtyardClearances().

◆ BooleanAdd() [1/2]

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

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

Definition at line 865 of file shape_poly_set.cpp.

867{
868 if( ADVANCED_CFG::GetCfg().m_UseClipper2 )
869 booleanOp( Clipper2Lib::ClipType::Union, a, b );
870 else
871 booleanOp( ClipperLib::ctUnion, a, b, aFastMode );
872}
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
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, ... and polygon simplification...

References SHAPE_POLY_SET::booleanOp(), and ADVANCED_CFG::GetCfg().

◆ BooleanAdd() [2/2]

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

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

Definition at line 838 of file shape_poly_set.cpp.

839{
840 if( ADVANCED_CFG::GetCfg().m_UseClipper2 )
841 booleanOp( Clipper2Lib::ClipType::Union, b );
842 else
843 booleanOp( ClipperLib::ctUnion, b, aFastMode );
844}

References SHAPE_POLY_SET::booleanOp(), and ADVANCED_CFG::GetCfg().

Referenced by DRC_TEST_PROVIDER_SOLDER_MASK::addItemToRTrees(), 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().

◆ BooleanIntersection() [1/2]

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

Definition at line 885 of file shape_poly_set.cpp.

887{
888 if( ADVANCED_CFG::GetCfg().m_UseClipper2 )
889 booleanOp( Clipper2Lib::ClipType::Intersection, a, b );
890 else
891 booleanOp( ClipperLib::ctIntersection, a, b, aFastMode );
892}

References SHAPE_POLY_SET::booleanOp(), and ADVANCED_CFG::GetCfg().

◆ BooleanIntersection() [2/2]

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

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

Definition at line 856 of file shape_poly_set.cpp.

857{
858 if( ADVANCED_CFG::GetCfg().m_UseClipper2 )
859 booleanOp( Clipper2Lib::ClipType::Intersection, b );
860 else
861 booleanOp( ClipperLib::ctIntersection, b, aFastMode );
862}

References SHAPE_POLY_SET::booleanOp(), and ADVANCED_CFG::GetCfg().

Referenced by ZONE_FILLER::addHatchFillTypeOnZone(), BOOST_AUTO_TEST_CASE(), ZONE::BuildSmoothedPoly(), CADSTAR_PCB_ARCHIVE_LOADER::calculateZonePriorities(), TEARDROP_MANAGER::ComputePointsOnPadVia(), ConvertPolygonToBlocks(), ZONE_FILLER::fillCopperZone(), PCB_BASE_FRAME::FocusOnItems(), isCopperOutside(), PAD_TOOL::RecombinePad(), RENDER_3D_OPENGL::reload(), and TransformOvalToPolygon().

◆ booleanOp() [1/4]

void SHAPE_POLY_SET::booleanOp ( Clipper2Lib::ClipType  aType,
const SHAPE_POLY_SET aOtherShape 
)
privateinherited

Definition at line 724 of file shape_poly_set.cpp.

725{
726 booleanOp( aType, *this, aOtherShape );
727}

References SHAPE_POLY_SET::booleanOp().

◆ booleanOp() [2/4]

void SHAPE_POLY_SET::booleanOp ( Clipper2Lib::ClipType  aType,
const SHAPE_POLY_SET aShape,
const SHAPE_POLY_SET aOtherShape 
)
privateinherited

Definition at line 730 of file shape_poly_set.cpp.

732{
733 if( ( aShape.OutlineCount() > 1 || aOtherShape.OutlineCount() > 0 )
734 && ( aShape.ArcCount() > 0 || aOtherShape.ArcCount() > 0 ) )
735 {
736 wxFAIL_MSG( wxT( "Boolean ops on curved polygons are not supported. You should call "
737 "ClearArcs() before carrying out the boolean operation." ) );
738 }
739
740 Clipper2Lib::Clipper64 c;
741
742 std::vector<CLIPPER_Z_VALUE> zValues;
743 std::vector<SHAPE_ARC> arcBuffer;
744 std::map<VECTOR2I, CLIPPER_Z_VALUE> newIntersectPoints;
745
746 Clipper2Lib::Paths64 paths;
747 Clipper2Lib::Paths64 clips;
748
749 for( const POLYGON& poly : aShape.m_polys )
750 {
751 for( size_t i = 0; i < poly.size(); i++ )
752 {
753 paths.push_back( poly[i].convertToClipper2( i == 0, zValues, arcBuffer ) );
754 }
755 }
756
757 for( const POLYGON& poly : aOtherShape.m_polys )
758 {
759 for( size_t i = 0; i < poly.size(); i++ )
760 {
761 clips.push_back( poly[i].convertToClipper2( i == 0, zValues, arcBuffer ) );
762 }
763 }
764
765 c.AddSubject( paths );
766 c.AddClip( clips );
767
768 Clipper2Lib::PolyTree64 solution;
769
770 Clipper2Lib::ZCallback64 callback =
771 [&]( const Clipper2Lib::Point64 & e1bot, const Clipper2Lib::Point64 & e1top,
772 const Clipper2Lib::Point64 & e2bot, const Clipper2Lib::Point64 & e2top,
773 Clipper2Lib::Point64 & pt )
774 {
775 auto arcIndex =
776 [&]( const ssize_t& aZvalue, const ssize_t& aCompareVal = -1 ) -> ssize_t
777 {
778 ssize_t retval;
779
780 retval = zValues.at( aZvalue ).m_SecondArcIdx;
781
782 if( retval == -1 || ( aCompareVal > 0 && retval != aCompareVal ) )
783 retval = zValues.at( aZvalue ).m_FirstArcIdx;
784
785 return retval;
786 };
787
788 auto arcSegment =
789 [&]( const ssize_t& aBottomZ, const ssize_t aTopZ ) -> ssize_t
790 {
791 ssize_t retval = arcIndex( aBottomZ );
792
793 if( retval != -1 )
794 {
795 if( retval != arcIndex( aTopZ, retval ) )
796 retval = -1; // Not an arc segment as the two indices do not match
797 }
798
799 return retval;
800 };
801
802 ssize_t e1ArcSegmentIndex = arcSegment( e1bot.z, e1top.z );
803 ssize_t e2ArcSegmentIndex = arcSegment( e2bot.z, e2top.z );
804
805 CLIPPER_Z_VALUE newZval;
806
807 if( e1ArcSegmentIndex != -1 )
808 {
809 newZval.m_FirstArcIdx = e1ArcSegmentIndex;
810 newZval.m_SecondArcIdx = e2ArcSegmentIndex;
811 }
812 else
813 {
814 newZval.m_FirstArcIdx = e2ArcSegmentIndex;
815 newZval.m_SecondArcIdx = -1;
816 }
817
818 size_t z_value_ptr = zValues.size();
819 zValues.push_back( newZval );
820
821 // Only worry about arc segments for later processing
822 if( newZval.m_FirstArcIdx != -1 )
823 newIntersectPoints.insert( { VECTOR2I( pt.x, pt.y ), newZval } );
824
825 pt.z = z_value_ptr;
826 //@todo amend X,Y values to true intersection between arcs or arc and segment
827 };
828
829 c.SetZCallback( callback ); // register callback
830
831 c.Execute( aType, Clipper2Lib::FillRule::NonZero, solution );
832
833 importTree( solution, zValues, arcBuffer );
834 solution.Clear(); // Free used memory (not done in dtor)
835}
void importTree(ClipperLib::PolyTree *tree, const std::vector< CLIPPER_Z_VALUE > &aZValueBuffer, const std::vector< SHAPE_ARC > &aArcBuffe)
Holds information on each point of a SHAPE_LINE_CHAIN that is retrievable after an operation with Cli...
VECTOR2< int > VECTOR2I
Definition: vector2d.h:618

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

◆ booleanOp() [3/4]

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

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

614{
615 booleanOp( aType, *this, aOtherShape, aFastMode );
616}

References SHAPE_POLY_SET::booleanOp().

Referenced by SHAPE_POLY_SET::BooleanAdd(), SHAPE_POLY_SET::BooleanIntersection(), SHAPE_POLY_SET::booleanOp(), SHAPE_POLY_SET::BooleanSubtract(), and SHAPE_POLY_SET::Simplify().

◆ booleanOp() [4/4]

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

Definition at line 619 of file shape_poly_set.cpp.

621{
622 if( ( aShape.OutlineCount() > 1 || aOtherShape.OutlineCount() > 0 )
623 && ( aShape.ArcCount() > 0 || aOtherShape.ArcCount() > 0 ) )
624 {
625 wxFAIL_MSG( wxT( "Boolean ops on curved polygons are not supported. You should call "
626 "ClearArcs() before carrying out the boolean operation." ) );
627 }
628
629 ClipperLib::Clipper c;
630
631 c.StrictlySimple( aFastMode == PM_STRICTLY_SIMPLE );
632
633 std::vector<CLIPPER_Z_VALUE> zValues;
634 std::vector<SHAPE_ARC> arcBuffer;
635 std::map<VECTOR2I, CLIPPER_Z_VALUE> newIntersectPoints;
636
637 for( const POLYGON& poly : aShape.m_polys )
638 {
639 for( size_t i = 0; i < poly.size(); i++ )
640 {
641 c.AddPath( poly[i].convertToClipper( i == 0, zValues, arcBuffer ),
642 ClipperLib::ptSubject, true );
643 }
644 }
645
646 for( const POLYGON& poly : aOtherShape.m_polys )
647 {
648 for( size_t i = 0; i < poly.size(); i++ )
649 {
650 c.AddPath( poly[i].convertToClipper( i == 0, zValues, arcBuffer ),
651 ClipperLib::ptClip, true );
652 }
653 }
654
655 ClipperLib::PolyTree solution;
656
657 ClipperLib::ZFillCallback callback =
658 [&]( ClipperLib::IntPoint & e1bot, ClipperLib::IntPoint & e1top,
659 ClipperLib::IntPoint & e2bot, ClipperLib::IntPoint & e2top,
660 ClipperLib::IntPoint & pt )
661 {
662 auto arcIndex =
663 [&]( const ssize_t& aZvalue, const ssize_t& aCompareVal = -1 ) -> ssize_t
664 {
665 ssize_t retval;
666
667 retval = zValues.at( aZvalue ).m_SecondArcIdx;
668
669 if( retval == -1 || ( aCompareVal > 0 && retval != aCompareVal ) )
670 retval = zValues.at( aZvalue ).m_FirstArcIdx;
671
672 return retval;
673 };
674
675 auto arcSegment =
676 [&]( const ssize_t& aBottomZ, const ssize_t aTopZ ) -> ssize_t
677 {
678 ssize_t retval = arcIndex( aBottomZ );
679
680 if( retval != -1 )
681 {
682 if( retval != arcIndex( aTopZ, retval ) )
683 retval = -1; // Not an arc segment as the two indices do not match
684 }
685
686 return retval;
687 };
688
689 ssize_t e1ArcSegmentIndex = arcSegment( e1bot.Z, e1top.Z );
690 ssize_t e2ArcSegmentIndex = arcSegment( e2bot.Z, e2top.Z );
691
692 CLIPPER_Z_VALUE newZval;
693
694 if( e1ArcSegmentIndex != -1 )
695 {
696 newZval.m_FirstArcIdx = e1ArcSegmentIndex;
697 newZval.m_SecondArcIdx = e2ArcSegmentIndex;
698 }
699 else
700 {
701 newZval.m_FirstArcIdx = e2ArcSegmentIndex;
702 newZval.m_SecondArcIdx = -1;
703 }
704
705 size_t z_value_ptr = zValues.size();
706 zValues.push_back( newZval );
707
708 // Only worry about arc segments for later processing
709 if( newZval.m_FirstArcIdx != -1 )
710 newIntersectPoints.insert( { VECTOR2I( pt.X, pt.Y ), newZval } );
711
712 pt.Z = z_value_ptr;
713 //@todo amend X,Y values to true intersection between arcs or arc and segment
714 };
715
716 c.ZFillFunction( callback ); // register callback
717
718 c.Execute( aType, solution, ClipperLib::pftNonZero, ClipperLib::pftNonZero );
719
720 importTree( &solution, zValues, arcBuffer );
721}

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

◆ BooleanSubtract() [1/2]

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

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

Definition at line 875 of file shape_poly_set.cpp.

877{
878 if( ADVANCED_CFG::GetCfg().m_UseClipper2 )
879 booleanOp( Clipper2Lib::ClipType::Difference, a, b );
880 else
881 booleanOp( ClipperLib::ctDifference, a, b, aFastMode );
882}

References SHAPE_POLY_SET::booleanOp(), and ADVANCED_CFG::GetCfg().

◆ BooleanSubtract() [2/2]

◆ BoundingBox()

BOX2D OUTLINE_GLYPH::BoundingBox ( )
overridevirtual

Implements KIFONT::GLYPH.

Definition at line 114 of file glyph.cpp.

115{
116 BOX2I bbox = BBox();
117 return BOX2D( bbox.GetOrigin(), bbox.GetSize() );
118}
BOX2< VECTOR2D > BOX2D
Definition: box2.h:848
const Vec & GetOrigin() const
Definition: box2.h:183
const Vec & GetSize() const
Definition: box2.h:179

References SHAPE_POLY_SET::BBox(), BOX2< Vec >::GetOrigin(), and BOX2< Vec >::GetSize().

◆ BuildBBoxCaches()

void SHAPE_POLY_SET::BuildBBoxCaches ( ) const
inherited

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

2117{
2118 for( int polygonIdx = 0; polygonIdx < OutlineCount(); polygonIdx++ )
2119 {
2120 COutline( polygonIdx ).GenerateBBoxCache();
2121
2122 for( int holeIdx = 0; holeIdx < HoleCount( polygonIdx ); holeIdx++ )
2123 CHole( polygonIdx, holeIdx ).GenerateBBoxCache();
2124 }
2125}
void GenerateBBoxCache() const
const SHAPE_LINE_CHAIN & CHole(int aOutline, int aHole) const
const SHAPE_LINE_CHAIN & COutline(int aIndex) const

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

Referenced by ZONE_FILLER::fillCopperZone().

◆ BuildPolysetFromOrientedPaths()

const SHAPE_POLY_SET SHAPE_POLY_SET::BuildPolysetFromOrientedPaths ( const std::vector< SHAPE_LINE_CHAIN > &  aPaths,
bool  aReverseOrientation = false,
bool  aEvenOdd = false 
)
staticinherited

Build a SHAPE_POLY_SET from a bunch of outlines in provided in random order.

Parameters
aPathset of closed outlines forming the polygon. Positive orientation = outline, negative = hole
aReverseOrientationinverts the sign of the orientation of aPaths (so negative = outline)
aEvenOddforces the even-off fill rule (default is non zero)
Returns
the constructed poly set

Definition at line 2962 of file shape_poly_set.cpp.

2964{
2965 ClipperLib::Clipper clipper;
2966 ClipperLib::PolyTree tree;
2967
2968 // fixme: do we need aReverseOrientation?
2969
2970 for( const SHAPE_LINE_CHAIN& path : aPaths )
2971 {
2972 ClipperLib::Path lc;
2973
2974 for( int i = 0; i < path.PointCount(); i++ )
2975 {
2976 lc.emplace_back( path.CPoint( i ).x, path.CPoint( i ).y );
2977 }
2978
2979 clipper.AddPath( lc, ClipperLib::ptSubject, true );
2980 }
2981
2982 clipper.StrictlySimple( true );
2983 clipper.Execute( ClipperLib::ctUnion, tree,
2984 aEvenOdd ? ClipperLib::pftEvenOdd : ClipperLib::pftNonZero,
2985 ClipperLib::pftNonZero );
2986 SHAPE_POLY_SET result;
2987
2988 for( ClipperLib::PolyNode* n = tree.GetFirst(); n; n = n->GetNext() )
2989 {
2990 if( !n->IsHole() )
2991 {
2992 int outl = result.NewOutline();
2993
2994 for( unsigned int i = 0; i < n->Contour.size(); i++ )
2995 result.Outline( outl ).Append( n->Contour[i].X, n->Contour[i].Y );
2996
2997 for( unsigned int i = 0; i < n->Childs.size(); i++ )
2998 {
2999 int outh = result.NewHole( outl );
3000 for( unsigned int j = 0; j < n->Childs[i]->Contour.size(); j++ )
3001 {
3002 result.Hole( outl, outh )
3003 .Append( n->Childs[i]->Contour[j].X, n->Childs[i]->Contour[j].Y );
3004 }
3005 }
3006 }
3007 }
3008
3009 return result;
3010}
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
Represent a set of closed polygons.
int NewOutline()
Creates a new hole in a given outline.
int NewHole(int aOutline=-1)
Adds a new outline to the set and returns its index.

References SHAPE_LINE_CHAIN::Append(), SHAPE_POLY_SET::Hole(), SHAPE_POLY_SET::NewHole(), SHAPE_POLY_SET::NewOutline(), SHAPE_POLY_SET::Outline(), and path.

Referenced by convertPolygon().

◆ CacheTriangulation()

void SHAPE_POLY_SET::CacheTriangulation ( bool  aPartition = true,
bool  aSimplify = false 
)
inherited

Build a polygon triangulation, needed to draw a polygon on OpenGL and in some other calculations.

Parameters
aPartition= true to created a trinagulation in a partition on a grid false to create a more basic triangulation of the polygons Note in partition calculations the grid size is hard coded to 1e7. This is a good value for Pcbnew: 1cm, in internal units. But not good for Gerbview (1e7 = 10cm), however using a partition is not useful.
aSimplify= force the algorithm to simplify the POLY_SET before triangulating

Definition at line 2709 of file shape_poly_set.cpp.

2710{
2711 bool recalculate = !m_hash.IsValid();
2712 MD5_HASH hash;
2713
2715 recalculate = true;
2716
2717 if( !recalculate )
2718 {
2719 hash = checksum();
2720
2721 if( m_hash != hash )
2722 {
2723 m_hash = hash;
2724 recalculate = true;
2725 }
2726 }
2727
2728 if( !recalculate )
2729 return;
2730
2731 auto triangulate =
2732 []( SHAPE_POLY_SET& polySet, int forOutline,
2733 std::vector<std::unique_ptr<TRIANGULATED_POLYGON>>& dest )
2734 {
2735 bool triangulationValid = false;
2736 int pass = 0;
2737
2738 while( polySet.OutlineCount() > 0 )
2739 {
2740 if( !dest.empty() && dest.back()->GetTriangleCount() == 0 )
2741 dest.erase( dest.end() - 1 );
2742
2743 dest.push_back( std::make_unique<TRIANGULATED_POLYGON>( forOutline ) );
2744 PolygonTriangulation tess( *dest.back() );
2745
2746 // If the tessellation fails, we re-fracture the polygon, which will
2747 // first simplify the system before fracturing and removing the holes
2748 // This may result in multiple, disjoint polygons.
2749 if( !tess.TesselatePolygon( polySet.Polygon( 0 ).front() ) )
2750 {
2751 ++pass;
2752
2753 if( pass == 1 )
2754 polySet.Fracture( PM_FAST );
2755 else if( pass == 2 )
2756 polySet.Fracture( PM_STRICTLY_SIMPLE );
2757 else
2758 break;
2759
2760 triangulationValid = false;
2761 continue;
2762 }
2763
2764 polySet.DeletePolygon( 0 );
2765 triangulationValid = true;
2766 }
2767
2768 return triangulationValid;
2769 };
2770
2771 m_triangulatedPolys.clear();
2772 m_triangulationValid = true;
2773
2774 if( aPartition )
2775 {
2776 for( int ii = 0; ii < OutlineCount(); ++ii )
2777 {
2778 // This partitions into regularly-sized grids (1cm in Pcbnew)
2779 SHAPE_POLY_SET flattened( Outline( ii ) );
2780
2781 for( int jj = 0; jj < HoleCount( ii ); ++jj )
2782 flattened.AddHole( Hole( ii, jj ) );
2783
2784 flattened.ClearArcs();
2785
2786 if( flattened.HasHoles() || flattened.IsSelfIntersecting() )
2787 flattened.Fracture( PM_FAST );
2788 else if( aSimplify )
2789 flattened.Simplify( PM_FAST );
2790
2791 SHAPE_POLY_SET partitions = partitionPolyIntoRegularCellGrid( flattened, 1e7 );
2792
2793 // This pushes the triangulation for all polys in partitions
2794 // to be referenced to the ii-th polygon
2795 m_triangulationValid &= triangulate( partitions, ii , m_triangulatedPolys );
2796 }
2797 }
2798 else
2799 {
2800 SHAPE_POLY_SET tmpSet( *this );
2801
2802 tmpSet.ClearArcs();
2803
2804 if( tmpSet.HasHoles() || tmpSet.IsSelfIntersecting() )
2805 tmpSet.Fracture( PM_FAST );
2806 else if( aSimplify )
2807 tmpSet.Simplify( PM_FAST );
2808
2809 m_triangulationValid = triangulate( tmpSet, -1, m_triangulatedPolys );
2810 }
2811
2813 m_hash = checksum();
2814}
bool IsValid() const
Definition: md5_hash.h:24
void Fracture(POLYGON_MODE aFastMode)
Convert a single outline slitted ("fractured") polygon into a set ouf outlines with holes.
void DeletePolygon(int aIdx)
Delete aIdx-th polygon and its triangulation data from the set.
POLYGON & Polygon(int aIndex)
std::vector< std::unique_ptr< TRIANGULATED_POLYGON > > m_triangulatedPolys
MD5_HASH checksum() const
static SHAPE_POLY_SET partitionPolyIntoRegularCellGrid(const SHAPE_POLY_SET &aPoly, int aSize)

References SHAPE_POLY_SET::AddHole(), SHAPE_POLY_SET::checksum(), SHAPE_POLY_SET::ClearArcs(), SHAPE_POLY_SET::DeletePolygon(), SHAPE_POLY_SET::Fracture(), SHAPE_POLY_SET::HasHoles(), SHAPE_POLY_SET::Hole(), SHAPE_POLY_SET::HoleCount(), SHAPE_POLY_SET::IsSelfIntersecting(), MD5_HASH::IsValid(), SHAPE_POLY_SET::m_hash, SHAPE_POLY_SET::m_triangulatedPolys, SHAPE_POLY_SET::m_triangulationValid, SHAPE_POLY_SET::Outline(), SHAPE_POLY_SET::OutlineCount(), partitionPolyIntoRegularCellGrid(), SHAPE_POLY_SET::PM_FAST, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE, SHAPE_POLY_SET::Polygon(), SHAPE_POLY_SET::Simplify(), and PolygonTriangulation::TesselatePolygon().

Referenced by FOOTPRINT::BuildCourtyardCaches(), ZONE::CacheTriangulation(), SHAPE_POLY_SET::Collide(), KIGFX::PCB_PAINTER::draw(), KIGFX::GERBVIEW_PAINTER::draw(), SHAPE_POLY_SET::Mirror(), SHAPE_POLY_SET::Rotate(), PNS_KICAD_IFACE_BASE::syncZone(), and Triangulate().

◆ 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}
IFSG_COLORS is the wrapper for SGCOLORS.
Definition: ifsg_colors.h:42
IFSG_COORDINDEX is the wrapper for SGCOORDINDEX.
IFSG_COORDS is the wrapper for SGCOORDS.
Definition: ifsg_coords.h:41
IFSG_FACESET is the wrapper for the SGFACESET class.
Definition: ifsg_faceset.h:41
IFSG_NORMALS is the wrapper for the SGNORMALS class.
Definition: ifsg_normals.h:41
IFSG_SHAPE is the wrapper for the SGSHAPE class.
Definition: ifsg_shape.h:41
double z
Definition: sg_base.h:72
double x
Definition: sg_base.h:70
double y
Definition: sg_base.h:71
std::list< FACET * > facets
Definition: wrlfacet.h:143
SGLIB_API SGNODE * GetSGNodeParent(SGNODE *aNode)
Definition: ifsg_api.cpp:494

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 WRL2FACESET::TranslateToSG(), X3DIFACESET::TranslateToSG(), and WRL1FACESET::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 229 of file shape.h.

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

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

Referenced by Collide().

◆ Chamfer()

SHAPE_POLY_SET SHAPE_POLY_SET::Chamfer ( int  aDistance)
inherited

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

2414{
2415 SHAPE_POLY_SET chamfered;
2416
2417 for( unsigned int idx = 0; idx < m_polys.size(); idx++ )
2418 chamfered.m_polys.push_back( ChamferPolygon( aDistance, idx ) );
2419
2420 return chamfered;
2421}
POLYGON ChamferPolygon(unsigned int aDistance, int aIndex)
Return a chamfered version of the aIndex-th polygon.

References SHAPE_POLY_SET::ChamferPolygon(), and SHAPE_POLY_SET::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 
)
privateinherited

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

2438{
2439 // Null segments create serious issues in calculations. Remove them:
2441
2442 SHAPE_POLY_SET::POLYGON currentPoly = Polygon( aIndex );
2444
2445 // If the chamfering distance is zero, then the polygon remain intact.
2446 if( aDistance == 0 )
2447 {
2448 return currentPoly;
2449 }
2450
2451 // Iterate through all the contours (outline and holes) of the polygon.
2452 for( SHAPE_LINE_CHAIN& currContour : currentPoly )
2453 {
2454 // Generate a new contour in the new polygon
2455 SHAPE_LINE_CHAIN newContour;
2456
2457 // Iterate through the vertices of the contour
2458 for( int currVertex = 0; currVertex < currContour.PointCount(); currVertex++ )
2459 {
2460 // Current vertex
2461 int x1 = currContour.CPoint( currVertex ).x;
2462 int y1 = currContour.CPoint( currVertex ).y;
2463
2464 // Indices for previous and next vertices.
2465 int prevVertex;
2466 int nextVertex;
2467
2468 // Previous and next vertices indices computation. Necessary to manage the edge cases.
2469
2470 // Previous vertex is the last one if the current vertex is the first one
2471 prevVertex = currVertex == 0 ? currContour.PointCount() - 1 : currVertex - 1;
2472
2473 // next vertex is the first one if the current vertex is the last one.
2474 nextVertex = currVertex == currContour.PointCount() - 1 ? 0 : currVertex + 1;
2475
2476 // Previous vertex computation
2477 double xa = currContour.CPoint( prevVertex ).x - x1;
2478 double ya = currContour.CPoint( prevVertex ).y - y1;
2479
2480 // Next vertex computation
2481 double xb = currContour.CPoint( nextVertex ).x - x1;
2482 double yb = currContour.CPoint( nextVertex ).y - y1;
2483
2484 // Compute the new distances
2485 double lena = hypot( xa, ya );
2486 double lenb = hypot( xb, yb );
2487
2488 // Make the final computations depending on the mode selected, chamfered or filleted.
2489 if( aMode == CORNER_MODE::CHAMFERED )
2490 {
2491 double distance = aDistance;
2492
2493 // Chamfer one half of an edge at most
2494 if( 0.5 * lena < distance )
2495 distance = 0.5 * lena;
2496
2497 if( 0.5 * lenb < distance )
2498 distance = 0.5 * lenb;
2499
2500 int nx1 = KiROUND( distance * xa / lena );
2501 int ny1 = KiROUND( distance * ya / lena );
2502
2503 newContour.Append( x1 + nx1, y1 + ny1 );
2504
2505 int nx2 = KiROUND( distance * xb / lenb );
2506 int ny2 = KiROUND( distance * yb / lenb );
2507
2508 newContour.Append( x1 + nx2, y1 + ny2 );
2509 }
2510 else // CORNER_MODE = FILLETED
2511 {
2512 double cosine = ( xa * xb + ya * yb ) / ( lena * lenb );
2513
2514 double radius = aDistance;
2515 double denom = sqrt( 2.0 / ( 1 + cosine ) - 1 );
2516
2517 // Do nothing in case of parallel edges
2518 if( std::isinf( denom ) )
2519 continue;
2520
2521 // Limit rounding distance to one half of an edge
2522 if( 0.5 * lena * denom < radius )
2523 radius = 0.5 * lena * denom;
2524
2525 if( 0.5 * lenb * denom < radius )
2526 radius = 0.5 * lenb * denom;
2527
2528 // Calculate fillet arc absolute center point (xc, yx)
2529 double k = radius / sqrt( .5 * ( 1 - cosine ) );
2530 double lenab = sqrt( ( xa / lena + xb / lenb ) * ( xa / lena + xb / lenb ) +
2531 ( ya / lena + yb / lenb ) * ( ya / lena + yb / lenb ) );
2532 double xc = x1 + k * ( xa / lena + xb / lenb ) / lenab;
2533 double yc = y1 + k * ( ya / lena + yb / lenb ) / lenab;
2534
2535 // Calculate arc start and end vectors
2536 k = radius / sqrt( 2 / ( 1 + cosine ) - 1 );
2537 double xs = x1 + k * xa / lena - xc;
2538 double ys = y1 + k * ya / lena - yc;
2539 double xe = x1 + k * xb / lenb - xc;
2540 double ye = y1 + k * yb / lenb - yc;
2541
2542 // Cosine of arc angle
2543 double argument = ( xs * xe + ys * ye ) / ( radius * radius );
2544
2545 // Make sure the argument is in [-1,1], interval in which the acos function is
2546 // defined
2547 if( argument < -1 )
2548 argument = -1;
2549 else if( argument > 1 )
2550 argument = 1;
2551
2552 double arcAngle = acos( argument );
2553 int segments = GetArcToSegmentCount( radius, aErrorMax,
2554 EDA_ANGLE( arcAngle, RADIANS_T ) );
2555
2556 double deltaAngle = arcAngle / segments;
2557 double startAngle = atan2( -ys, xs );
2558
2559 // Flip arc for inner corners
2560 if( xa * yb - ya * xb <= 0 )
2561 deltaAngle *= -1;
2562
2563 double nx = xc + xs;
2564 double ny = yc + ys;
2565
2566 newContour.Append( KiROUND( nx ), KiROUND( ny ) );
2567
2568 // Store the previous added corner to make a sanity check
2569 int prevX = KiROUND( nx );
2570 int prevY = KiROUND( ny );
2571
2572 for( int j = 0; j < segments; j++ )
2573 {
2574 nx = xc + cos( startAngle + ( j + 1 ) * deltaAngle ) * radius;
2575 ny = yc - sin( startAngle + ( j + 1 ) * deltaAngle ) * radius;
2576
2577 // Sanity check: the rounding can produce repeated corners; do not add them.
2578 if( KiROUND( nx ) != prevX || KiROUND( ny ) != prevY )
2579 {
2580 newContour.Append( KiROUND( nx ), KiROUND( ny ) );
2581 prevX = KiROUND( nx );
2582 prevY = KiROUND( ny );
2583 }
2584 }
2585 }
2586 }
2587
2588 // Close the current contour and add it the new polygon
2589 newContour.SetClosed( true );
2590 newPoly.push_back( newContour );
2591 }
2592
2593 return newPoly;
2594}
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
int RemoveNullSegments()
Look for null segments; ie, segments whose ends are exactly the same and deletes them.
@ RADIANS_T
Definition: eda_angle.h:32
int GetArcToSegmentCount(int aRadius, int aErrorMax, const EDA_ANGLE &aArcAngle)
static float distance(const SFVEC2UI &a, const SFVEC2UI &b)
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:85

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

Referenced by SHAPE_POLY_SET::ChamferPolygon(), and SHAPE_POLY_SET::FilletPolygon().

◆ ChamferPolygon()

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

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

2265{
2266 return chamferFilletPolygon( CHAMFERED, aDistance, aIndex, 0 );
2267}
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 SHAPE_POLY_SET::CHAMFERED, and SHAPE_POLY_SET::chamferFilletPolygon().

Referenced by SHAPE_POLY_SET::Chamfer().

◆ checksum()

MD5_HASH SHAPE_POLY_SET::checksum ( ) const
privateinherited

Definition at line 2817 of file shape_poly_set.cpp.

2818{
2819 MD5_HASH hash;
2820
2821 hash.Hash( m_polys.size() );
2822
2823 for( const POLYGON& outline : m_polys )
2824 {
2825 hash.Hash( outline.size() );
2826
2827 for( const SHAPE_LINE_CHAIN& lc : outline )
2828 {
2829 hash.Hash( lc.PointCount() );
2830
2831 for( int i = 0; i < lc.PointCount(); i++ )
2832 {
2833 hash.Hash( lc.CPoint( i ).x );
2834 hash.Hash( lc.CPoint( i ).y );
2835 }
2836 }
2837 }
2838
2839 hash.Finalize();
2840
2841 return hash;
2842}
void Finalize()
Definition: md5_hash.cpp:78
void Hash(uint8_t *data, uint32_t length)
Definition: md5_hash.cpp:66

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

Referenced by SHAPE_POLY_SET::CacheTriangulation(), SHAPE_POLY_SET::DeletePolygonAndTriangulationData(), SHAPE_POLY_SET::GetHash(), SHAPE_POLY_SET::IsTriangulationUpToDate(), SHAPE_POLY_SET::Move(), and SHAPE_POLY_SET::UpdateTriangulationDataHash().

◆ CHole()

◆ CIterate() [1/3]

CONST_ITERATOR SHAPE_POLY_SET::CIterate ( ) const
inlineinherited

Definition at line 834 of file shape_poly_set.h.

835 {
836 return CIterate( 0, OutlineCount() - 1 );
837 }
CONST_ITERATOR CIterate() const

References SHAPE_POLY_SET::CIterate(), and SHAPE_POLY_SET::OutlineCount().

Referenced by SHAPE_POLY_SET::CIterate(), and SHAPE_POLY_SET::CIterateWithHoles().

◆ CIterate() [2/3]

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

Definition at line 810 of file shape_poly_set.h.

811 {
812 CONST_ITERATOR iter;
813
814 iter.m_poly = const_cast<SHAPE_POLY_SET*>( this );
815 iter.m_currentPolygon = aFirst;
816 iter.m_lastPolygon = aLast < 0 ? OutlineCount() - 1 : aLast;
817 iter.m_currentContour = 0;
818 iter.m_currentVertex = 0;
819 iter.m_iterateHoles = aIterateHoles;
820
821 return iter;
822 }
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 SHAPE_POLY_SET::OutlineCount().

Referenced by ConvertOutlineToPolygon(), EDA_SHAPE::DupPolyPointsList(), and EDA_SHAPE::getBoundingBox().

◆ CIterate() [3/3]

CONST_ITERATOR SHAPE_POLY_SET::CIterate ( int  aOutline) const
inlineinherited

Definition at line 824 of file shape_poly_set.h.

825 {
826 return CIterate( aOutline, aOutline );
827 }

References SHAPE_POLY_SET::CIterate().

◆ CIterateSegments() [1/3]

CONST_SEGMENT_ITERATOR SHAPE_POLY_SET::CIterateSegments ( ) const
inlineinherited

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

Definition at line 915 of file shape_poly_set.h.

References SHAPE_POLY_SET::CIterateSegments(), and SHAPE_POLY_SET::OutlineCount().

Referenced by SHAPE_POLY_SET::CIterateSegments(), and SHAPE_POLY_SET::CIterateSegmentsWithHoles().

◆ CIterateSegments() [2/3]

◆ CIterateSegments() [3/3]

CONST_SEGMENT_ITERATOR SHAPE_POLY_SET::CIterateSegments ( int  aPolygonIdx) const
inlineinherited

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

Definition at line 903 of file shape_poly_set.h.

References SHAPE_POLY_SET::CIterateSegments().

◆ CIterateSegmentsWithHoles() [1/2]

CONST_SEGMENT_ITERATOR SHAPE_POLY_SET::CIterateSegmentsWithHoles ( ) const
inlineinherited

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

Definition at line 933 of file shape_poly_set.h.

References SHAPE_POLY_SET::CIterateSegments(), and SHAPE_POLY_SET::OutlineCount().

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

◆ CIterateSegmentsWithHoles() [2/2]

CONST_SEGMENT_ITERATOR SHAPE_POLY_SET::CIterateSegmentsWithHoles ( int  aOutline) const
inlineinherited

Definition at line 939 of file shape_poly_set.h.

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

References SHAPE_POLY_SET::CIterateSegments().

◆ CIterateWithHoles() [1/2]

CONST_ITERATOR SHAPE_POLY_SET::CIterateWithHoles ( ) const
inlineinherited

Definition at line 839 of file shape_poly_set.h.

840 {
841 return CIterate( 0, OutlineCount() - 1, true );
842 }

References SHAPE_POLY_SET::CIterate(), and SHAPE_POLY_SET::OutlineCount().

Referenced by SHAPE_POLY_SET::CollideVertex().

◆ CIterateWithHoles() [2/2]

CONST_ITERATOR SHAPE_POLY_SET::CIterateWithHoles ( int  aOutline) const
inlineinherited

Definition at line 829 of file shape_poly_set.h.

830 {
831 return CIterate( aOutline, aOutline, true );
832 }

References SHAPE_POLY_SET::CIterate().

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

◆ ClearArcs()

void SHAPE_POLY_SET::ClearArcs ( )
inherited

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

Definition at line 602 of file shape_poly_set.cpp.

603{
604 for( POLYGON& poly : m_polys )
605 {
606 for( size_t i = 0; i < poly.size(); i++ )
607 poly[i].ClearArcs();
608 }
609}
void ClearArcs()
Appends a vertex at the end of the given outline/hole (default: the last outline)

References SHAPE_POLY_SET::ClearArcs(), and SHAPE_POLY_SET::m_polys.

Referenced by BOOST_AUTO_TEST_CASE(), ZONE::BuildSmoothedPoly(), SHAPE_POLY_SET::CacheTriangulation(), SHAPE_POLY_SET::ClearArcs(), CONVERT_TOOL::CreatePolys(), CADSTAR_PCB_ARCHIVE_LOADER::getPolySetFromCadstarShape(), CADSTAR_PCB_ARCHIVE_LOADER::loadCoppers(), and ZONE_FILLER::subtractHigherPriorityZones().

◆ Clone()

SHAPE * SHAPE_POLY_SET::Clone ( ) const
overridevirtualinherited

Return a dynamically allocated copy of the shape.

Return values
copyof the shape

Reimplemented from SHAPE.

Definition at line 133 of file shape_poly_set.cpp.

134{
135 return new SHAPE_POLY_SET( *this );
136}

References SHAPE_POLY_SET::SHAPE_POLY_SET().

◆ CloneDropTriangulation()

◆ Collide() [1/4]

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

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

1796{
1797 VECTOR2I nearest;
1798 ecoord dist_sq = SquaredDistance( aSeg, aLocation ? &nearest : nullptr );
1799
1800 if( dist_sq == 0 || dist_sq < SEG::Square( aClearance ) )
1801 {
1802 if( aLocation )
1803 *aLocation = nearest;
1804
1805 if( aActual )
1806 *aActual = sqrt( dist_sq );
1807
1808 return true;
1809 }
1810
1811 return false;
1812}
static SEG::ecoord Square(int a)
Definition: seg.h:123
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 SHAPE_POLY_SET::SquaredDistance().

◆ Collide() [2/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_COMPOUND, SHAPE_RECT, and SHAPE_SEGMENT.

Definition at line 1109 of file shape_collisions.cpp.

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

References collideShapes().

◆ Collide() [3/4]

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

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

1841{
1842 // A couple of simple cases are worth trying before we fall back on triangulation.
1843
1844 if( aShape->Type() == SH_SEGMENT )
1845 {
1846 const SHAPE_SEGMENT* segment = static_cast<const SHAPE_SEGMENT*>( aShape );
1847 int extra = segment->GetWidth() / 2;
1848
1849 if( Collide( segment->GetSeg(), aClearance + extra, aActual, aLocation ) )
1850 {
1851 if( aActual )
1852 *aActual = std::max( 0, *aActual - extra );
1853
1854 return true;
1855 }
1856
1857 return false;
1858 }
1859
1860 if( aShape->Type() == SH_CIRCLE )
1861 {
1862 const SHAPE_CIRCLE* circle = static_cast<const SHAPE_CIRCLE*>( aShape );
1863 int extra = circle->GetRadius();
1864
1865 if( Collide( circle->GetCenter(), aClearance + extra, aActual, aLocation ) )
1866 {
1867 if( aActual )
1868 *aActual = std::max( 0, *aActual - extra );
1869
1870 return true;
1871 }
1872
1873 return false;
1874 }
1875
1876 const_cast<SHAPE_POLY_SET*>( this )->CacheTriangulation( false );
1877
1878 int actual = INT_MAX;
1879 VECTOR2I location;
1880
1881 for( const std::unique_ptr<TRIANGULATED_POLYGON>& tpoly : m_triangulatedPolys )
1882 {
1883 for( const TRIANGULATED_POLYGON::TRI& tri : tpoly->Triangles() )
1884 {
1885 if( aActual || aLocation )
1886 {
1887 int triActual;
1888 VECTOR2I triLocation;
1889
1890 if( aShape->Collide( &tri, aClearance, &triActual, &triLocation ) )
1891 {
1892 if( triActual < actual )
1893 {
1894 actual = triActual;
1895 location = triLocation;
1896 }
1897 }
1898 }
1899 else // A much faster version of above
1900 {
1901 if( aShape->Collide( &tri, aClearance ) )
1902 return true;
1903 }
1904 }
1905 }
1906
1907 if( actual < INT_MAX )
1908 {
1909 if( aActual )
1910 *aActual = std::max( 0, actual );
1911
1912 if( aLocation )
1913 *aLocation = location;
1914
1915 return true;
1916 }
1917
1918 return false;
1919}
SHAPE_TYPE Type() const
Return the type of the shape.
Definition: shape.h:95
int GetRadius() const
Definition: shape_circle.h:108
const VECTOR2I GetCenter() const
Definition: shape_circle.h:113
void CacheTriangulation(bool aPartition=true, bool aSimplify=false)
Build a polygon triangulation, needed to draw a polygon on OpenGL and in some other calculations.
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,...
const SEG & GetSeg() const
int GetWidth() const
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:178
@ SH_CIRCLE
circle
Definition: shape.h:47
@ SH_SEGMENT
line segment
Definition: shape.h:45

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

Referenced by SHAPE_POLY_SET::Collide(), collidesWithArea(), collidesWithCourtyard(), DRAWING_TOOL::DrawVia(), ZONE_FILLER::Fill(), ZONE::GetInteractingZones(), EDA_SHAPE::hitTest(), DS_DRAW_ITEM_POLYPOLYGONS::HitTest(), FOOTPRINT::HitTestAccurate(), PCB_SELECTION_TOOL::hitTestDistance(), DIALOG_PAD_PROPERTIES::padValuesOK(), DRC_TEST_PROVIDER_ANNULAR_WIDTH::Run(), DRC_INTERACTIVE_COURTYARD_CLEARANCE::testCourtyardClearances(), DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testCourtyardClearances(), DRC_TEST_PROVIDER_PHYSICAL_CLEARANCE::testItemAgainstZones(), and PCB_TEXT::TextHitTest().

◆ Collide() [4/4]

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

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

1817{
1818 if( IsEmpty() || VertexCount() == 0 )
1819 return false;
1820
1821 VECTOR2I nearest;
1822 ecoord dist_sq = SquaredDistance( aP, aLocation ? &nearest : nullptr );
1823
1824 if( dist_sq == 0 || dist_sq < SEG::Square( aClearance ) )
1825 {
1826 if( aLocation )
1827 *aLocation = nearest;
1828
1829 if( aActual )
1830 *aActual = sqrt( dist_sq );
1831
1832 return true;
1833 }
1834
1835 return false;
1836}
int VertexCount(int aOutline=-1, int aHole=-1) const
Return the number of points in the shape poly set.
bool IsEmpty() const

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

◆ CollideEdge()

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

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

2086{
2087 // Shows whether there was a collision
2088 bool collision = false;
2089 ecoord clearance_squared = SEG::Square( aClearance );
2090
2091 for( CONST_SEGMENT_ITERATOR iterator = CIterateSegmentsWithHoles(); iterator; iterator++ )
2092 {
2093 const SEG currentSegment = *iterator;
2094 ecoord distance_squared = currentSegment.SquaredDistance( aPoint );
2095
2096 // Check for collisions
2097 if( distance_squared <= clearance_squared )
2098 {
2099 if( !aClosestVertex )
2100 return true;
2101
2102 collision = true;
2103
2104 // Update clearance to look for closer edges
2105 clearance_squared = distance_squared;
2106
2107 // Store the indices that identify the vertex
2108 *aClosestVertex = iterator.GetIndex();
2109 }
2110 }
2111
2112 return collision;
2113}
Definition: seg.h:42
ecoord SquaredDistance(const SEG &aSeg) const
Definition: seg.cpp:75
CONST_SEGMENT_ITERATOR CIterateSegmentsWithHoles() const
Return an iterator object, for the aOutline-th outline in the set (with holes).
SEGMENT_ITERATOR_TEMPLATE< const SEG > CONST_SEGMENT_ITERATOR

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

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

◆ CollideVertex()

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

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

2046{
2047 // Shows whether there was a collision
2048 bool collision = false;
2049
2050 // Difference vector between each vertex and aPoint.
2052 ecoord distance_squared;
2053 ecoord clearance_squared = SEG::Square( aClearance );
2054
2055 for( CONST_ITERATOR iterator = CIterateWithHoles(); iterator; iterator++ )
2056 {
2057 // Get the difference vector between current vertex and aPoint
2058 delta = *iterator - aPoint;
2059
2060 // Compute distance
2061 distance_squared = delta.SquaredEuclideanNorm();
2062
2063 // Check for collisions
2064 if( distance_squared <= clearance_squared )
2065 {
2066 if( !aClosestVertex )
2067 return true;
2068
2069 collision = true;
2070
2071 // Update clearance to look for closer vertices
2072 clearance_squared = distance_squared;
2073
2074 // Store the indices that identify the vertex
2075 *aClosestVertex = iterator.GetIndex();
2076 }
2077 }
2078
2079 return collision;
2080}
CONST_ITERATOR CIterateWithHoles() const
constexpr int delta

References SHAPE_POLY_SET::CIterateWithHoles(), delta, and SEG::Square().

Referenced by ZONE::HitTestForCorner().

◆ Contains()

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

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 point Return true if the set is empty (no polygons at all)

Definition at line 2128 of file shape_poly_set.cpp.

2130{
2131 if( m_polys.empty() )
2132 return false;
2133
2134 // If there is a polygon specified, check the condition against that polygon
2135 if( aSubpolyIndex >= 0 )
2136 return containsSingle( aP, aSubpolyIndex, aAccuracy, aUseBBoxCaches );
2137
2138 // In any other case, check it against all polygons in the set
2139 for( int polygonIdx = 0; polygonIdx < OutlineCount(); polygonIdx++ )
2140 {
2141 if( containsSingle( aP, polygonIdx, aAccuracy, aUseBBoxCaches ) )
2142 return true;
2143 }
2144
2145 return false;
2146}
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 SHAPE_POLY_SET::containsSingle(), SHAPE_POLY_SET::m_polys, and SHAPE_POLY_SET::OutlineCount().

Referenced by ZONE_FILLER::Fill(), ZONE_FILLER::fillCopperZone(), 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
privateinherited

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

2186{
2187 // Check that the point is inside the outline
2188 if( m_polys[aSubpolyIndex][0].PointInside( aP, aAccuracy ) )
2189 {
2190 // Check that the point is not in any of the holes
2191 for( int holeIdx = 0; holeIdx < HoleCount( aSubpolyIndex ); holeIdx++ )
2192 {
2193 const SHAPE_LINE_CHAIN& hole = CHole( aSubpolyIndex, holeIdx );
2194
2195 // If the point is inside a hole it is outside of the polygon. Do not use aAccuracy
2196 // here as it's meaning would be inverted.
2197 if( hole.PointInside( aP, 1, aUseBBoxCaches ) )
2198 return false;
2199 }
2200
2201 return true;
2202 }
2203
2204 return false;
2205}
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.

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

Referenced by SHAPE_POLY_SET::Contains(), and SHAPE_POLY_SET::SquaredDistanceToPolygon().

◆ COutline()

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

◆ CPolygon()

◆ CVertex() [1/3]

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

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

Definition at line 399 of file shape_poly_set.cpp.

400{
402
403 // Assure the passed index references a legal position; abort otherwise
404 if( !GetRelativeIndices( aGlobalIndex, &index ) )
405 throw( std::out_of_range( "aGlobalIndex-th vertex does not exist" ) );
406
407 return m_polys[index.m_polygon][index.m_contour].CPoint( index.m_vertex );
408}
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...
Structure to hold the necessary information in order to index a vertex on a SHAPE_POLY_SET object: th...

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

◆ CVertex() [2/3]

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

Return the aGlobalIndex-th vertex in the poly set.

Definition at line 380 of file shape_poly_set.cpp.

381{
382 if( aOutline < 0 )
383 aOutline += m_polys.size();
384
385 int idx;
386
387 if( aHole < 0 )
388 idx = 0;
389 else
390 idx = aHole + 1;
391
392 assert( aOutline < (int) m_polys.size() );
393 assert( idx < (int) m_polys[aOutline].size() );
394
395 return m_polys[aOutline][idx].CPoint( aIndex );
396}

References SHAPE_POLY_SET::m_polys.

Referenced by PCB_POINT_EDITOR::addCorner(), EDA_SHAPE::Compare(), SHAPE_POLY_SET::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(), FOOTPRINT::cmp_drawings::operator()(), FOOTPRINT::cmp_zones::operator()(), SCH_EDITOR_CONTROL::Paste(), ZONE::SetCornerPosition(), shapesNeedUpdate(), PCB_POINT_EDITOR::updateItem(), PCB_POINT_EDITOR::updatePoints(), and zonesNeedUpdate().

◆ CVertex() [3/3]

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

Definition at line 411 of file shape_poly_set.cpp.

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

References SHAPE_POLY_SET::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 
)
inlineinherited

◆ DeletePolygon()

void SHAPE_POLY_SET::DeletePolygon ( int  aIdx)
inherited

Delete aIdx-th polygon and its triangulation data from the set.

If called with aUpdateHash false, caller must call UpdateTriangulationDataHash().

Definition at line 1997 of file shape_poly_set.cpp.

1998{
1999 m_polys.erase( m_polys.begin() + aIdx );
2000}

References SHAPE_POLY_SET::m_polys.

Referenced by ZONE_FILLER::addHatchFillTypeOnZone(), BOOST_AUTO_TEST_CASE(), SHAPE_POLY_SET::CacheTriangulation(), ZONE_FILLER::fillCopperZone(), and PlotStandardLayer().

◆ DeletePolygonAndTriangulationData()

void SHAPE_POLY_SET::DeletePolygonAndTriangulationData ( int  aIdx,
bool  aUpdateHash = true 
)
inherited

Definition at line 2003 of file shape_poly_set.cpp.

2004{
2005 m_polys.erase( m_polys.begin() + aIdx );
2006
2008 {
2009 for( int ii = m_triangulatedPolys.size() - 1; ii >= 0; --ii )
2010 {
2011 std::unique_ptr<TRIANGULATED_POLYGON>& triangleSet = m_triangulatedPolys[ii];
2012
2013 if( triangleSet->GetSourceOutlineIndex() == aIdx )
2014 m_triangulatedPolys.erase( m_triangulatedPolys.begin() + ii );
2015 else if( triangleSet->GetSourceOutlineIndex() > aIdx )
2016 triangleSet->SetSourceOutlineIndex( triangleSet->GetSourceOutlineIndex() - 1 );
2017 }
2018
2019 if( aUpdateHash )
2020 m_hash = checksum();
2021 }
2022}

References SHAPE_POLY_SET::checksum(), SHAPE_POLY_SET::m_hash, SHAPE_POLY_SET::m_polys, SHAPE_POLY_SET::m_triangulatedPolys, and SHAPE_POLY_SET::m_triangulationValid.

◆ Fillet()

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

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

2425{
2426 SHAPE_POLY_SET filleted;
2427
2428 for( size_t idx = 0; idx < m_polys.size(); idx++ )
2429 filleted.m_polys.push_back( FilletPolygon( aRadius, aErrorMax, idx ) );
2430
2431 return filleted;
2432}
POLYGON FilletPolygon(unsigned int aRadius, int aErrorMax, int aIndex)
Return a filleted version of the aIndex-th polygon.

References SHAPE_POLY_SET::FilletPolygon(), and SHAPE_POLY_SET::m_polys.

Referenced by ZONE_FILLER::addHatchFillTypeOnZone().

◆ FilletPolygon()

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

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

2272{
2273 return chamferFilletPolygon( FILLETED, aRadius, aIndex, aErrorMax );
2274}

References SHAPE_POLY_SET::chamferFilletPolygon(), and SHAPE_POLY_SET::FILLETED.

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

◆ Format()

const std::string SHAPE_POLY_SET::Format ( bool  aCplusPlus = true) const
overridevirtualinherited

Reimplemented from SHAPE.

Definition at line 1654 of file shape_poly_set.cpp.

1655{
1656 std::stringstream ss;
1657
1658 ss << "SHAPE_LINE_CHAIN poly; \n";
1659
1660 for( unsigned i = 0; i < m_polys.size(); i++ )
1661 {
1662 for( unsigned j = 0; j < m_polys[i].size(); j++ )
1663 {
1664
1665 ss << "{ auto tmp = " << m_polys[i][j].Format() << ";\n";
1666
1667 SHAPE_POLY_SET poly;
1668
1669 if( j == 0 )
1670 {
1671 ss << " poly.AddOutline(tmp); } \n";
1672 }
1673 else
1674 {
1675 ss << " poly.AddHole(tmp); } \n";
1676 }
1677
1678 }
1679 }
1680
1681 return ss.str();
1682}

References SHAPE_POLY_SET::m_polys.

◆ Fracture()

void SHAPE_POLY_SET::Fracture ( POLYGON_MODE  aFastMode)
inherited

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

Definition at line 1408 of file shape_poly_set.cpp.

1409{
1410 Simplify( aFastMode ); // remove overlapping holes/degeneracy
1411
1412 for( POLYGON& paths : m_polys )
1413 fractureSingle( paths );
1414}
void fractureSingle(POLYGON &paths)
void Simplify(POLYGON_MODE aFastMode)

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

Referenced by addHoleToPolygon(), PAD::addPadPrimitivesToPolygon(), PAD::AddPrimitivePoly(), BOARD_ADAPTER::addText(), SHAPE_POLY_SET::CacheTriangulation(), convertPolygon(), BITMAPCONV_INFO::createOutputData(), KIGFX::PCB_PAINTER::draw(), CADSTAR_PCB_ARCHIVE_LOADER::drawCadstarShape(), CALLBACK_GAL::DrawGlyph(), AR_AUTOPLACER::drawPlacementRoutingMatrix(), EXPORTER_PCB_VRML::ExportStandardLayers(), EXPORTER_PCB_VRML::ExportVrmlSolderMask(), ZONE_FILLER::fillCopperZone(), AR_AUTOPLACER::fillMatrix(), ZONE_FILLER::fillNonCopperZone(), APERTURE_MACRO::GetApertureMacroShape(), FP_TEXT::GetEffectiveShape(), PCB_TEXT::GetEffectiveShape(), SHAPE_POLY_SET::InflateWithLinkedHoles(), CADSTAR_PCB_ARCHIVE_LOADER::loadCoppers(), FABMASTER::loadFootprints(), EAGLE_PLUGIN::loadPolygon(), FABMASTER::loadShapePolySet(), ALTIUM_PCB::ParseRegions6Data(), BRDITEMS_PLOTTER::PlotFootprintShape(), BRDITEMS_PLOTTER::PlotPcbShape(), BRDITEMS_PLOTTER::PlotPcbText(), DXF_PLOTTER::PlotPoly(), PlotSolderMaskLayer(), RENDER_3D_RAYTRACE::Reload(), DRC_TEST_PROVIDER_DISALLOW::Run(), EDA_SHAPE::SetPolyShape(), TransformRingToPolygon(), PAD::TransformShapeToPolygon(), and ZONE::TransformSmoothedOutlineToPolygon().

◆ fractureSingle()

void SHAPE_POLY_SET::fractureSingle ( POLYGON paths)
privateinherited

Definition at line 1292 of file shape_poly_set.cpp.

1293{
1294 FractureEdgeSet edges;
1295 FractureEdgeSet border_edges;
1296 FractureEdge* root = nullptr;
1297
1298 bool first = true;
1299
1300 if( paths.size() == 1 )
1301 return;
1302
1303 int num_unconnected = 0;
1304
1305 for( const SHAPE_LINE_CHAIN& path : paths )
1306 {
1307 const std::vector<VECTOR2I>& points = path.CPoints();
1308 int pointCount = points.size();
1309
1310 FractureEdge* prev = nullptr, * first_edge = nullptr;
1311
1312 int x_min = std::numeric_limits<int>::max();
1313
1314 for( int i = 0; i < pointCount; i++ )
1315 {
1316 if( points[i].x < x_min )
1317 x_min = points[i].x;
1318
1319 // Do not use path.CPoint() here; open-coding it using the local variables "points"
1320 // and "pointCount" gives a non-trivial performance boost to zone fill times.
1321 FractureEdge* fe = new FractureEdge( first, points[ i ],
1322 points[ i+1 == pointCount ? 0 : i+1 ] );
1323
1324 if( !root )
1325 root = fe;
1326
1327 if( !first_edge )
1328 first_edge = fe;
1329
1330 if( prev )
1331 prev->m_next = fe;
1332
1333 if( i == pointCount - 1 )
1334 fe->m_next = first_edge;
1335
1336 prev = fe;
1337 edges.push_back( fe );
1338
1339 if( !first )
1340 {
1341 if( fe->m_p1.x == x_min )
1342 border_edges.push_back( fe );
1343 }
1344
1345 if( !fe->m_connected )
1346 num_unconnected++;
1347 }
1348
1349 first = false; // first path is always the outline
1350 }
1351
1352 // keep connecting holes to the main outline, until there's no holes left...
1353 while( num_unconnected > 0 )
1354 {
1355 int x_min = std::numeric_limits<int>::max();
1356 auto it = border_edges.begin();
1357
1358 FractureEdge* smallestX = nullptr;
1359
1360 // find the left-most hole edge and merge with the outline
1361 for( ; it != border_edges.end(); ++it )
1362 {
1363 FractureEdge* border_edge = *it;
1364 int xt = border_edge->m_p1.x;
1365
1366 if( ( xt <= x_min ) && !border_edge->m_connected )
1367 {
1368 x_min = xt;
1369 smallestX = border_edge;
1370 }
1371 }
1372
1373 int num_processed = processEdge( edges, smallestX );
1374
1375 // If we can't handle the edge, the zone is broken (maybe)
1376 if( !num_processed )
1377 {
1378 wxLogWarning( wxT( "Broken polygon, dropping path" ) );
1379
1380 for( FractureEdge* edge : edges )
1381 delete edge;
1382
1383 return;
1384 }
1385
1386 num_unconnected -= num_processed;
1387 }
1388
1389 paths.clear();
1390 SHAPE_LINE_CHAIN newPath;
1391
1392 newPath.SetClosed( true );
1393
1394 FractureEdge* e;
1395
1396 for( e = root; e->m_next != root; e = e->m_next )
1397 newPath.Append( e->m_p1 );
1398
1399 newPath.Append( e->m_p1 );
1400
1401 for( FractureEdge* edge : edges )
1402 delete edge;
1403
1404 paths.push_back( std::move( newPath ) );
1405}
static int processEdge(FractureEdgeSet &edges, FractureEdge *edge)
std::vector< FractureEdge * > FractureEdgeSet
FractureEdge * m_next

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 SHAPE_POLY_SET::Fracture().

◆ FullPointCount()

int SHAPE_POLY_SET::FullPointCount ( ) const
inherited

Returns the number of holes in a given outline.

Definition at line 346 of file shape_poly_set.cpp.

347{
348 int full_count = 0;
349
350 if( m_polys.size() == 0 ) // Empty poly set
351 return full_count;
352
353 for( int ii = 0; ii < OutlineCount(); ii++ )
354 {
355 // the first polygon in m_polys[ii] is the main contour,
356 // only others are holes:
357 for( int idx = 0; idx <= HoleCount( ii ); idx++ )
358 {
359 full_count += m_polys[ii][idx].PointCount();
360 }
361 }
362
363 return full_count;
364}

References SHAPE_POLY_SET::HoleCount(), SHAPE_POLY_SET::m_polys, and SHAPE_POLY_SET::OutlineCount().

Referenced by SHAPE_POLY_SET::IsPolygonSelfIntersecting().

◆ GetArcs()

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

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

Definition at line 589 of file shape_poly_set.cpp.

590{
591 for( const POLYGON& poly : m_polys )
592 {
593 for( size_t i = 0; i < poly.size(); i++ )
594 {
595 for( SHAPE_ARC arc : poly[i].m_arcs )
596 aArcBuffer.push_back( arc );
597 }
598 }
599}

References SHAPE_POLY_SET::m_polys.

Referenced by BOOST_AUTO_TEST_CASE().

◆ GetClearance()

int SHAPE::GetClearance ( const SHAPE aOther) const
inherited

Return the actual minimum distance between two shapes.

Return values
distancein IU

Definition at line 49 of file shape.cpp.

50{
51 int actual_clearance = std::numeric_limits<int>::max();
52 std::vector<const SHAPE*> a_shapes;
53 std::vector<const SHAPE*> b_shapes;
54
55 GetIndexableSubshapes( a_shapes );
56 aOther->GetIndexableSubshapes( b_shapes );
57
58 if( GetIndexableSubshapeCount() == 0 )
59 a_shapes.push_back( this );
60
61 if( aOther->GetIndexableSubshapeCount() == 0 )
62 b_shapes.push_back( aOther );
63
64 for( const SHAPE* a : a_shapes )
65 {
66 for( const SHAPE* b : b_shapes )
67 {
68 int temp_dist = 0;
69 a->Collide( b, std::numeric_limits<int>::max() / 2, &temp_dist );
70
71 if( temp_dist < actual_clearance )
72 actual_clearance = temp_dist;
73 }
74 }
75
76 return actual_clearance;
77}
virtual size_t GetIndexableSubshapeCount() const
Definition: shape.h:110
virtual void GetIndexableSubshapes(std::vector< const SHAPE * > &aSubshapes) const
Definition: shape.h:112
An abstract shape on 2D plane.
Definition: shape.h:123

References SHAPE_BASE::GetIndexableSubshapeCount(), and SHAPE_BASE::GetIndexableSubshapes().

◆ GetGlobalIndex()

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

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

187{
188 int selectedVertex = aRelativeIndices.m_vertex;
189 unsigned int selectedContour = aRelativeIndices.m_contour;
190 unsigned int selectedPolygon = aRelativeIndices.m_polygon;
191
192 // Check whether the vertex indices make sense in this poly set
193 if( selectedPolygon < m_polys.size() && selectedContour < m_polys[selectedPolygon].size()
194 && selectedVertex < m_polys[selectedPolygon][selectedContour].PointCount() )
195 {
196 POLYGON currentPolygon;
197
198 aGlobalIdx = 0;
199
200 for( unsigned int polygonIdx = 0; polygonIdx < selectedPolygon; polygonIdx++ )
201 {
202 currentPolygon = Polygon( polygonIdx );
203
204 for( unsigned int contourIdx = 0; contourIdx < currentPolygon.size(); contourIdx++ )
205 aGlobalIdx += currentPolygon[contourIdx].PointCount();
206 }
207
208 currentPolygon = Polygon( selectedPolygon );
209
210 for( unsigned int contourIdx = 0; contourIdx < selectedContour; contourIdx++ )
211 aGlobalIdx += currentPolygon[contourIdx].PointCount();
212
213 aGlobalIdx += selectedVertex;
214
215 return true;
216 }
217 else
218 {
219 return false;
220 }
221}

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

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

◆ GetHash()

MD5_HASH SHAPE_POLY_SET::GetHash ( ) const
inherited

◆ GetIndexableSubshapeCount()

size_t SHAPE_POLY_SET::GetIndexableSubshapeCount ( ) const
overridevirtualinherited

Reimplemented from SHAPE_BASE.

Definition at line 2884 of file shape_poly_set.cpp.

2885{
2886 size_t n = 0;
2887
2888 for( const std::unique_ptr<TRIANGULATED_POLYGON>& t : m_triangulatedPolys )
2889 n += t->GetTriangleCount();
2890
2891 return n;
2892}

References SHAPE_POLY_SET::m_triangulatedPolys.

Referenced by SHAPE_POLY_SET::GetIndexableSubshapes().

◆ GetIndexableSubshapes()

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

Reimplemented from SHAPE_BASE.

Definition at line 2895 of file shape_poly_set.cpp.

2896{
2897 aSubshapes.reserve( GetIndexableSubshapeCount() );
2898
2899 for( const std::unique_ptr<TRIANGULATED_POLYGON>& tpoly : m_triangulatedPolys )
2900 {
2901 for( TRIANGULATED_POLYGON::TRI& tri : tpoly->Triangles() )
2902 aSubshapes.push_back( &tri );
2903 }
2904}
virtual size_t GetIndexableSubshapeCount() const override

References SHAPE_POLY_SET::GetIndexableSubshapeCount(), and SHAPE_POLY_SET::m_triangulatedPolys.

◆ GetNeighbourIndexes()

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

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

418{
420
421 // If the edge does not exist, throw an exception, it is an illegal access memory error
422 if( !GetRelativeIndices( aGlobalIndex, &index ) )
423 return false;
424
425 // Calculate the previous and next index of aGlobalIndex, corresponding to
426 // the same contour;
427 VERTEX_INDEX inext = index;
428 int lastpoint = m_polys[index.m_polygon][index.m_contour].SegmentCount();
429
430 if( index.m_vertex == 0 )
431 {
432 index.m_vertex = lastpoint;
433 inext.m_vertex = 1;
434 }
435 else if( index.m_vertex == lastpoint )
436 {
437 index.m_vertex--;
438 inext.m_vertex = 0;
439 }
440 else
441 {
442 inext.m_vertex++;
443 index.m_vertex--;
444 }
445
446 if( aPrevious )
447 {
448 int previous;
449 GetGlobalIndex( index, previous );
450 *aPrevious = previous;
451 }
452
453 if( aNext )
454 {
455 int next;
456 GetGlobalIndex( inext, next );
457 *aNext = next;
458 }
459
460 return true;
461}
bool GetGlobalIndex(VERTEX_INDEX aRelativeIndices, int &aGlobalIdx) const
Compute the global index of a vertex from the relative indices of polygon, contour and vertex.
CITER next(CITER it)
Definition: ptree.cpp:126

References SHAPE_POLY_SET::GetGlobalIndex(), SHAPE_POLY_SET::GetRelativeIndices(), SHAPE_POLY_SET::VERTEX_INDEX::m_contour, SHAPE_POLY_SET::VERTEX_INDEX::m_polygon, SHAPE_POLY_SET::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
inherited

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

147{
148 int polygonIdx = 0;
149 unsigned int contourIdx = 0;
150 int vertexIdx = 0;
151
152 int currentGlobalIdx = 0;
153
154 for( polygonIdx = 0; polygonIdx < OutlineCount(); polygonIdx++ )
155 {
156 const POLYGON& currentPolygon = CPolygon( polygonIdx );
157
158 for( contourIdx = 0; contourIdx < currentPolygon.size(); contourIdx++ )
159 {
160 const SHAPE_LINE_CHAIN& currentContour = currentPolygon[contourIdx];
161 int totalPoints = currentContour.PointCount();
162
163 for( vertexIdx = 0; vertexIdx < totalPoints; vertexIdx++ )
164 {
165 // Check if the current vertex is the globally indexed as aGlobalIdx
166 if( currentGlobalIdx == aGlobalIdx )
167 {
168 aRelativeIndices->m_polygon = polygonIdx;
169 aRelativeIndices->m_contour = contourIdx;
170 aRelativeIndices->m_vertex = vertexIdx;
171
172 return true;
173 }
174
175 // Advance
176 currentGlobalIdx++;
177 }
178 }
179 }
180
181 return false;
182}
int PointCount() const
Return the number of points (vertices) in this line chain.
const POLYGON & CPolygon(int aIndex) const

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

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

◆ HasHoles()

bool SHAPE_POLY_SET::HasHoles ( ) const
inherited

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

Definition at line 1584 of file shape_poly_set.cpp.

1585{
1586 // Iterate through all the polygons on the set
1587 for( const POLYGON& paths : m_polys )
1588 {
1589 // If any of them has more than one contour, it is a hole.
1590 if( paths.size() > 1 )
1591 return true;
1592 }
1593
1594 // Return false if and only if every polygon has just one outline, without holes.
1595 return false;
1596}

References SHAPE_POLY_SET::m_polys.

Referenced by PAD::AddPrimitivePoly(), SHAPE_POLY_SET::CacheTriangulation(), and CALLBACK_GAL::DrawGlyph().

◆ HasIndexableSubshapes()

bool SHAPE_POLY_SET::HasIndexableSubshapes ( ) const
overridevirtualinherited

Reimplemented from SHAPE_BASE.

Definition at line 2878 of file shape_poly_set.cpp.

2879{
2880 return IsTriangulationUpToDate();
2881}
bool IsTriangulationUpToDate() const

References SHAPE_POLY_SET::IsTriangulationUpToDate().

◆ HasTouchingHoles()

bool SHAPE_POLY_SET::HasTouchingHoles ( ) const
inherited

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

Definition at line 2845 of file shape_poly_set.cpp.

2846{
2847 for( int i = 0; i < OutlineCount(); i++ )
2848 {
2849 if( hasTouchingHoles( CPolygon( i ) ) )
2850 return true;
2851 }
2852
2853 return false;
2854}
bool hasTouchingHoles(const POLYGON &aPoly) const

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

◆ hasTouchingHoles()

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

Definition at line 2857 of file shape_poly_set.cpp.

2858{
2859 std::set<long long> ptHashes;
2860
2861 for( const SHAPE_LINE_CHAIN& lc : aPoly )
2862 {
2863 for( const VECTOR2I& pt : lc.CPoints() )
2864 {
2865 const long long ptHash = (long long) pt.x << 32 | pt.y;
2866
2867 if( ptHashes.count( ptHash ) > 0 )
2868 return true;
2869
2870 ptHashes.insert( ptHash );
2871 }
2872 }
2873
2874 return false;
2875}

Referenced by SHAPE_POLY_SET::HasTouchingHoles().

◆ Hole()

◆ HoleCount()

◆ importPaths()

void SHAPE_POLY_SET::importPaths ( Clipper2Lib::Paths64 &  paths,
const std::vector< CLIPPER_Z_VALUE > &  aZValueBuffer,
const std::vector< SHAPE_ARC > &  aArcBuffe 
)
privateinherited

Definition at line 1157 of file shape_poly_set.cpp.

1160{
1161 m_polys.clear();
1162 POLYGON path;
1163
1164 for( const Clipper2Lib::Path64& n : aPath )
1165 {
1166 if( Clipper2Lib::Area( n ) > 0 )
1167 {
1168 if( !path.empty() )
1169 m_polys.emplace_back( path );
1170
1171 path.clear();
1172 }
1173 else
1174 {
1175 wxCHECK2_MSG( !path.empty(), continue, wxT( "Cannot add a hole before an outline" ) );
1176 }
1177
1178 path.emplace_back( n, aZValueBuffer, aArcBuffer );
1179 }
1180
1181 if( !path.empty() )
1182 m_polys.emplace_back( path );
1183}

References SHAPE_POLY_SET::m_polys, and path.

◆ importPolyPath()

void SHAPE_POLY_SET::importPolyPath ( Clipper2Lib::PolyPath64 *  aPolyPath,
const std::vector< CLIPPER_Z_VALUE > &  aZValueBuffer,
const std::vector< SHAPE_ARC > &  aArcBuffer 
)
privateinherited

Definition at line 1123 of file shape_poly_set.cpp.

1126{
1127 if( !aPolyPath->IsHole() )
1128 {
1129 POLYGON paths;
1130 paths.reserve( aPolyPath->Count() + 1 );
1131 paths.emplace_back( aPolyPath->Polygon(), aZValueBuffer, aArcBuffer );
1132
1133 for( Clipper2Lib::PolyPath64* child : *aPolyPath )
1134 {
1135 paths.emplace_back( child->Polygon(), aZValueBuffer, aArcBuffer );
1136
1137 for( Clipper2Lib::PolyPath64* grandchild : *child )
1138 importPolyPath( grandchild, aZValueBuffer, aArcBuffer );
1139 }
1140
1141 m_polys.push_back( paths );
1142 }
1143}
void importPolyPath(Clipper2Lib::PolyPath64 *aPolyPath, const std::vector< CLIPPER_Z_VALUE > &aZValueBuffer, const std::vector< SHAPE_ARC > &aArcBuffer)

References SHAPE_POLY_SET::importPolyPath(), and SHAPE_POLY_SET::m_polys.

Referenced by SHAPE_POLY_SET::importPolyPath(), and SHAPE_POLY_SET::importTree().

◆ importTree() [1/2]

void SHAPE_POLY_SET::importTree ( Clipper2Lib::PolyTree64 &  tree,
const std::vector< CLIPPER_Z_VALUE > &  aZValueBuffer,
const std::vector< SHAPE_ARC > &  aArcBuffe 
)
privateinherited

Definition at line 1146 of file shape_poly_set.cpp.

1149{
1150 m_polys.clear();
1151
1152 for( Clipper2Lib::PolyPath64* n : tree )
1153 importPolyPath( n, aZValueBuffer, aArcBuffer );
1154}

References SHAPE_POLY_SET::importPolyPath(), and SHAPE_POLY_SET::m_polys.

◆ importTree() [2/2]

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

Definition at line 1099 of file shape_poly_set.cpp.

1102{
1103 m_polys.clear();
1104
1105 for( ClipperLib::PolyNode* n = tree->GetFirst(); n; n = n->GetNext() )
1106 {
1107 if( !n->IsHole() )
1108 {
1109 POLYGON paths;
1110 paths.reserve( n->Childs.size() + 1 );
1111
1112 paths.emplace_back( n->Contour, aZValueBuffer, aArcBuffer );
1113
1114 for( unsigned int i = 0; i < n->Childs.size(); i++ )
1115 paths.emplace_back( n->Childs[i]->Contour, aZValueBuffer, aArcBuffer );
1116
1117 m_polys.push_back( paths );
1118 }
1119 }
1120}

References SHAPE_POLY_SET::m_polys.

Referenced by SHAPE_POLY_SET::booleanOp(), SHAPE_POLY_SET::inflate1(), and SHAPE_POLY_SET::inflate2().

◆ Inflate()

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

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

1091{
1092 if( ADVANCED_CFG::GetCfg().m_UseClipper2 )
1093 inflate2( aAmount, aCircleSegCount, aCornerStrategy );
1094 else
1095 inflate1( aAmount, aCircleSegCount, aCornerStrategy );
1096}
void inflate2(int aAmount, int aCircleSegCount, CORNER_STRATEGY aCornerStrategy)
void inflate1(int aAmount, int aCircleSegCount, CORNER_STRATEGY aCornerStrategy)

References ADVANCED_CFG::GetCfg(), SHAPE_POLY_SET::inflate1(), and SHAPE_POLY_SET::inflate2().

Referenced by FOOTPRINT::BuildCourtyardCaches(), ZONE::BuildSmoothedPoly(), CADSTAR_PCB_ARCHIVE_LOADER::calculateZonePriorities(), BOARD_ADAPTER::createPadWithMargin(), SHAPE_POLY_SET::Deflate(), ZONE_FILLER::fillCopperZone(), ZONE_FILLER::fillNonCopperZone(), CADSTAR_PCB_ARCHIVE_LOADER::getPolySetFromCadstarShape(), SHAPE_POLY_SET::InflateWithLinkedHoles(), CADSTAR_PCB_ARCHIVE_LOADER::loadCoppers(), EAGLE_PLUGIN::loadPolygon(), EAGLE_PLUGIN::packagePolygon(), PlotSolderMaskLayer(), DRC_TEST_PROVIDER_TEXT_DIMS::Run(), TEARDROP_MANAGER::SetTeardrops(), PAD::TransformShapeToPolygon(), and ZONE::TransformSmoothedOutlineToPolygon().

◆ inflate1()

void SHAPE_POLY_SET::inflate1 ( int  aAmount,
int  aCircleSegCount,
CORNER_STRATEGY  aCornerStrategy 
)
privateinherited

Definition at line 904 of file shape_poly_set.cpp.

905{
906 using namespace ClipperLib;
907 // A static table to avoid repetitive calculations of the coefficient
908 // 1.0 - cos( M_PI / aCircleSegCount )
909 // aCircleSegCount is most of time <= 64 and usually 8, 12, 16, 32
910 #define SEG_CNT_MAX 64
911 static double arc_tolerance_factor[SEG_CNT_MAX + 1];
912
913 ClipperOffset c;
914
915 // N.B. see the Clipper documentation for jtSquare/jtMiter/jtRound. They are poorly named
916 // and are not what you'd think they are.
917 // http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Types/JoinType.htm
918 JoinType joinType = jtRound; // The way corners are offsetted
919 double miterLimit = 2.0; // Smaller value when using jtMiter for joinType
920 JoinType miterFallback = jtSquare;
921
922 switch( aCornerStrategy )
923 {
925 joinType = jtMiter;
926 miterLimit = 10; // Allows large spikes
927 miterFallback = jtSquare;
928 break;
929
930 case CHAMFER_ACUTE_CORNERS: // Acute angles are chamfered
931 joinType = jtMiter;
932 miterFallback = jtRound;
933 break;
934
935 case ROUND_ACUTE_CORNERS: // Acute angles are rounded
936 joinType = jtMiter;
937 miterFallback = jtSquare;
938 break;
939
940 case CHAMFER_ALL_CORNERS: // All angles are chamfered.
941 joinType = jtSquare;
942 miterFallback = jtSquare;
943 break;
944
945 case ROUND_ALL_CORNERS: // All angles are rounded.
946 joinType = jtRound;
947 miterFallback = jtSquare;
948 break;
949 }
950
951 std::vector<CLIPPER_Z_VALUE> zValues;
952 std::vector<SHAPE_ARC> arcBuffer;
953
954 for( const POLYGON& poly : m_polys )
955 {
956 for( size_t i = 0; i < poly.size(); i++ )
957 {
958 c.AddPath( poly[i].convertToClipper( i == 0, zValues, arcBuffer ),
959 joinType, etClosedPolygon );
960 }
961 }
962
963 PolyTree solution;
964
965 // Calculate the arc tolerance (arc error) from the seg count by circle. The seg count is
966 // nn = M_PI / acos(1.0 - c.ArcTolerance / abs(aAmount))
967 // http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Classes/ClipperOffset/Properties/ArcTolerance.htm
968
969 if( aCircleSegCount < 6 ) // avoid incorrect aCircleSegCount values
970 aCircleSegCount = 6;
971
972 double coeff;
973
974 if( aCircleSegCount > SEG_CNT_MAX || arc_tolerance_factor[aCircleSegCount] == 0 )
975 {
976 coeff = 1.0 - cos( M_PI / aCircleSegCount );
977
978 if( aCircleSegCount <= SEG_CNT_MAX )
979 arc_tolerance_factor[aCircleSegCount] = coeff;
980 }
981 else
982 {
983 coeff = arc_tolerance_factor[aCircleSegCount];
984 }
985
986 c.ArcTolerance = std::abs( aAmount ) * coeff;
987 c.MiterLimit = miterLimit;
988 c.MiterFallback = miterFallback;
989 c.Execute( solution, aAmount );
990
991 importTree( &solution, zValues, arcBuffer );
992}
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:401
#define SEG_CNT_MAX

References std::abs(), SHAPE_POLY_SET::ALLOW_ACUTE_CORNERS, SHAPE_POLY_SET::CHAMFER_ACUTE_CORNERS, SHAPE_POLY_SET::CHAMFER_ALL_CORNERS, SHAPE_POLY_SET::importTree(), SHAPE_POLY_SET::m_polys, SHAPE_POLY_SET::ROUND_ACUTE_CORNERS, SHAPE_POLY_SET::ROUND_ALL_CORNERS, and SEG_CNT_MAX.

Referenced by SHAPE_POLY_SET::Inflate().

◆ inflate2()

void SHAPE_POLY_SET::inflate2 ( int  aAmount,
int  aCircleSegCount,
CORNER_STRATEGY  aCornerStrategy 
)
privateinherited

Definition at line 995 of file shape_poly_set.cpp.

996{
997 using namespace Clipper2Lib;
998 // A static table to avoid repetitive calculations of the coefficient
999 // 1.0 - cos( M_PI / aCircleSegCount )
1000 // aCircleSegCount is most of time <= 64 and usually 8, 12, 16, 32
1001 #define SEG_CNT_MAX 64
1002 static double arc_tolerance_factor[SEG_CNT_MAX + 1];
1003
1004 ClipperOffset c;
1005
1006 // N.B. see the Clipper documentation for jtSquare/jtMiter/jtRound. They are poorly named
1007 // and are not what you'd think they are.
1008 // http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Types/JoinType.htm
1009 JoinType joinType = JoinType::Round; // The way corners are offsetted
1010 double miterLimit = 2.0; // Smaller value when using jtMiter for joinType
1011 JoinType miterFallback = JoinType::Square;
1012
1013 switch( aCornerStrategy )
1014 {
1016 joinType = JoinType::Miter;
1017 miterLimit = 10; // Allows large spikes
1018 break;
1019
1020 case CHAMFER_ACUTE_CORNERS: // Acute angles are chamfered
1021 joinType = JoinType::Miter;
1022 break;
1023
1024 case ROUND_ACUTE_CORNERS: // Acute angles are rounded
1025 joinType = JoinType::Miter;
1026 break;
1027
1028 case CHAMFER_ALL_CORNERS: // All angles are chamfered.
1029 joinType = JoinType::Square;
1030 break;
1031
1032 case ROUND_ALL_CORNERS: // All angles are rounded.
1033 joinType = JoinType::Round;
1034 break;
1035 }
1036
1037 std::vector<CLIPPER_Z_VALUE> zValues;
1038 std::vector<SHAPE_ARC> arcBuffer;
1039
1040 for( const POLYGON& poly : m_polys )
1041 {
1042 Paths64 paths;
1043
1044 for( size_t i = 0; i < poly.size(); i++ )
1045 paths.push_back( poly[i].convertToClipper2( i == 0, zValues, arcBuffer ) );
1046
1047 c.AddPaths( paths, joinType, EndType::Polygon );
1048 }
1049
1050 // Calculate the arc tolerance (arc error) from the seg count by circle. The seg count is
1051 // nn = M_PI / acos(1.0 - c.ArcTolerance / abs(aAmount))
1052 // http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Classes/ClipperOffset/Properties/ArcTolerance.htm
1053
1054 if( aCircleSegCount < 6 ) // avoid incorrect aCircleSegCount values
1055 aCircleSegCount = 6;
1056
1057 double coeff;
1058
1059 if( aCircleSegCount > SEG_CNT_MAX || arc_tolerance_factor[aCircleSegCount] == 0 )
1060 {
1061 coeff = 1.0 - cos( M_PI / aCircleSegCount );
1062
1063 if( aCircleSegCount <= SEG_CNT_MAX )
1064 arc_tolerance_factor[aCircleSegCount] = coeff;
1065 }
1066 else
1067 {
1068 coeff = arc_tolerance_factor[aCircleSegCount];
1069 }
1070
1071 c.ArcTolerance( std::abs( aAmount ) * coeff );
1072 c.MiterLimit( miterLimit );
1073 c.MergeGroups( true );
1074 Paths64 solution = c.Execute( aAmount );
1075
1076 // We get paths back but we need the tree to assign the holes to the correct
1077 // outlines
1078 Clipper64 c2;
1079 PolyTree64 tree;
1080 c2.PreserveCollinear = false;
1081 c2.ReverseSolution = false;
1082 c2.AddSubject( solution );
1083 c2.Execute(ClipType::Union, FillRule::Positive, tree);
1084
1085 importTree( tree, zValues, arcBuffer );
1086 tree.Clear();
1087}

References std::abs(), SHAPE_POLY_SET::ALLOW_ACUTE_CORNERS, SHAPE_POLY_SET::CHAMFER_ACUTE_CORNERS, SHAPE_POLY_SET::CHAMFER_ALL_CORNERS, SHAPE_POLY_SET::importTree(), SHAPE_POLY_SET::m_polys, SHAPE_POLY_SET::ROUND_ACUTE_CORNERS, SHAPE_POLY_SET::ROUND_ALL_CORNERS, and SEG_CNT_MAX.

Referenced by SHAPE_POLY_SET::Inflate().

◆ InflateWithLinkedHoles()

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

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

897{
898 Unfracture( aFastMode );
899 Inflate( aFactor, aCircleSegmentsCount );
900 Fracture( aFastMode );
901}
void Unfracture(POLYGON_MODE aFastMode)
Return true if the polygon set has any holes.

References SHAPE_POLY_SET::Fracture(), SHAPE_POLY_SET::Inflate(), and SHAPE_POLY_SET::Unfracture().

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

◆ InsertVertex()

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

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

300{
301 VERTEX_INDEX index;
302
303 if( aGlobalIndex < 0 )
304 aGlobalIndex = 0;
305
306 if( aGlobalIndex >= TotalVertices() )
307 {
308 Append( aNewVertex );
309 }
310 else
311 {
312 // Assure the position to be inserted exists; throw an exception otherwise
313 if( GetRelativeIndices( aGlobalIndex, &index ) )
314 m_polys[index.m_polygon][index.m_contour].Insert( index.m_vertex, aNewVertex );
315 else
316 throw( std::out_of_range( "aGlobalIndex-th vertex does not exist" ) );
317 }
318}
int TotalVertices() const
Delete aIdx-th polygon from the set.

References SHAPE_POLY_SET::Append(), SHAPE_POLY_SET::GetRelativeIndices(), SHAPE_POLY_SET::VERTEX_INDEX::m_contour, SHAPE_POLY_SET::VERTEX_INDEX::m_polygon, SHAPE_POLY_SET::m_polys, SHAPE_POLY_SET::VERTEX_INDEX::m_vertex, and SHAPE_POLY_SET::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 163 of file shape.h.

164 {
165 return m_type == SH_NULL;
166 }
SHAPE_TYPE m_type
< type of our shape
Definition: shape.h:116
@ SH_NULL
empty shape (no shape...),
Definition: shape.h:52

References SHAPE_BASE::m_type, and SH_NULL.

◆ IsOutline()

bool KIFONT::OUTLINE_GLYPH::IsOutline ( ) const
inlineoverridevirtual

Reimplemented from KIFONT::GLYPH.

Definition at line 73 of file glyph.h.

73{ return true; }

◆ IsPolygonSelfIntersecting()

bool SHAPE_POLY_SET::IsPolygonSelfIntersecting ( int  aPolygonIndex) const
inherited

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

465{
466 std::vector<SEG> segments;
467 segments.reserve( FullPointCount() );
468
469 for( CONST_SEGMENT_ITERATOR it = CIterateSegmentsWithHoles( aPolygonIndex ); it; it++ )
470 segments.emplace_back( *it );
471
472 std::sort( segments.begin(), segments.end(), []( const SEG& a, const SEG& b )
473 {
474 int min_a_x = std::min( a.A.x, a.B.x );
475 int min_b_x = std::min( b.A.x, b.B.x );
476
477 return min_a_x < min_b_x || ( min_a_x == min_b_x && std::min( a.A.y, a.B.y ) < std::min( b.A.y, b.B.y ) );
478 } );
479
480 for( auto it = segments.begin(); it != segments.end(); ++it )
481 {
482 SEG& firstSegment = *it;
483
484 // Iterate through all remaining segments.
485 auto innerIterator = it;
486 int max_x = std::max( firstSegment.A.x, firstSegment.B.x );
487 int max_y = std::max( firstSegment.A.y, firstSegment.B.y );
488
489 // Start in the next segment, we don't want to check collision between a segment and itself
490 for( innerIterator++; innerIterator != segments.end(); innerIterator++ )
491 {
492 SEG& secondSegment = *innerIterator;
493 int min_x = std::min( secondSegment.A.x, secondSegment.B.x );
494 int min_y = std::min( secondSegment.A.y, secondSegment.B.y );
495
496 // We are ordered in minimum point order, so checking the static max (first segment) against
497 // the ordered min will tell us if any of the following segments are withing the BBox
498 if( max_x < min_x || ( max_x == min_x && max_y < min_y ) )
499 break;
500
501 int index_diff = std::abs( firstSegment.Index() - secondSegment.Index() );
502 bool adjacent = ( index_diff == 1) || (index_diff == (segments.size() - 1) );
503
504 // Check whether the two segments built collide, only when they are not adjacent.
505 if( !adjacent && firstSegment.Collide( secondSegment, 0 ) )
506 return true;
507 }
508 }
509
510 return false;
511}
VECTOR2I A
Definition: seg.h:49
VECTOR2I B
Definition: seg.h:50
int Index() const
Return the index of this segment in its parent shape (applicable only to non-local segments).
Definition: seg.h:344
bool Collide(const SEG &aSeg, int aClearance, int *aActual=nullptr) const
Definition: seg.cpp:223
int FullPointCount() const
Returns the number of holes in a given outline.

References SEG::A, std::abs(), SEG::B, SHAPE_POLY_SET::CIterateSegmentsWithHoles(), SEG::Collide(), SHAPE_POLY_SET::FullPointCount(), SEG::Index(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by SHAPE_POLY_SET::IsSelfIntersecting().

◆ IsSelfIntersecting()

bool SHAPE_POLY_SET::IsSelfIntersecting ( ) const
inherited

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

515{
516 for( unsigned int polygon = 0; polygon < m_polys.size(); polygon++ )
517 {
518 if( IsPolygonSelfIntersecting( polygon ) )
519 return true;
520 }
521
522 return false;
523}
bool IsPolygonSelfIntersecting(int aPolygonIndex) const
Check whether the aPolygonIndex-th polygon in the set is self intersecting.

References SHAPE_POLY_SET::IsPolygonSelfIntersecting(), and SHAPE_POLY_SET::m_polys.

Referenced by SHAPE_POLY_SET::CacheTriangulation().

◆ IsSolid()

bool SHAPE_POLY_SET::IsSolid ( ) const
inlineoverridevirtualinherited

Implements SHAPE.

Definition at line 1086 of file shape_poly_set.h.

1087 {
1088 return true;
1089 }

◆ IsStroke()

virtual bool KIFONT::GLYPH::IsStroke ( ) const
inlinevirtualinherited

Reimplemented in KIFONT::STROKE_GLYPH.

Definition at line 52 of file glyph.h.

52{ return false; }

Referenced by CALLBACK_GAL::DrawGlyph(), KIGFX::OPENGL_GAL::DrawGlyph(), and KIGFX::CAIRO_GAL_BASE::DrawGlyph().

◆ IsTriangulationUpToDate()

bool SHAPE_POLY_SET::IsTriangulationUpToDate ( ) const
inherited

◆ IsVertexInHole()

bool SHAPE_POLY_SET::IsVertexInHole ( int  aGlobalIdx)
inherited

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

2401{
2402 VERTEX_INDEX index;
2403
2404 // Get the polygon and contour where the vertex is. If the vertex does not exist, return false
2405 if( !GetRelativeIndices( aGlobalIdx, &index ) )
2406 return false;
2407
2408 // The contour is a hole if its index is greater than zero
2409 return index.m_contour > 0;
2410}

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

◆ Iterate() [1/3]

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

Definition at line 795 of file shape_poly_set.h.

796 {
797 return Iterate( 0, OutlineCount() - 1 );
798 }
ITERATOR Iterate()

References SHAPE_POLY_SET::Iterate(), and SHAPE_POLY_SET::OutlineCount().

Referenced by SHAPE_POLY_SET::Iterate(), and SHAPE_POLY_SET::IterateWithHoles().

◆ Iterate() [2/3]

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

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 757 of file shape_poly_set.h.

758 {
759 ITERATOR iter;
760
761 iter.m_poly = this;
762 iter.m_currentPolygon = aFirst;
763 iter.m_lastPolygon = aLast < 0 ? OutlineCount() - 1 : aLast;
764 iter.m_currentContour = 0;
765 iter.m_currentVertex = 0;
766 iter.m_iterateHoles = aIterateHoles;
767
768 return iter;
769 }
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 SHAPE_POLY_SET::OutlineCount().

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

◆ Iterate() [3/3]

ITERATOR SHAPE_POLY_SET::Iterate ( int  aOutline)
inlineinherited
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 776 of file shape_poly_set.h.

777 {
778 return Iterate( aOutline, aOutline );
779 }

References SHAPE_POLY_SET::Iterate().

◆ IterateFromVertexWithHoles()

ITERATOR SHAPE_POLY_SET::IterateFromVertexWithHoles ( int  aGlobalIdx)
inlineinherited

◆ IterateSegments() [1/3]

SEGMENT_ITERATOR SHAPE_POLY_SET::IterateSegments ( )
inlineinherited

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

Definition at line 909 of file shape_poly_set.h.

References SHAPE_POLY_SET::IterateSegments(), and SHAPE_POLY_SET::OutlineCount().

Referenced by SHAPE_POLY_SET::IterateSegments(), and SHAPE_POLY_SET::IterateSegmentsWithHoles().

◆ IterateSegments() [2/3]

◆ IterateSegments() [3/3]

SEGMENT_ITERATOR SHAPE_POLY_SET::IterateSegments ( int  aPolygonIdx)
inlineinherited

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

Definition at line 897 of file shape_poly_set.h.

References SHAPE_POLY_SET::IterateSegments().

◆ IterateSegmentsWithHoles() [1/2]

SEGMENT_ITERATOR SHAPE_POLY_SET::IterateSegmentsWithHoles ( )
inlineinherited

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

Definition at line 921 of file shape_poly_set.h.

References SHAPE_POLY_SET::IterateSegments(), and SHAPE_POLY_SET::OutlineCount().

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

◆ IterateSegmentsWithHoles() [2/2]

SEGMENT_ITERATOR SHAPE_POLY_SET::IterateSegmentsWithHoles ( int  aOutline)
inlineinherited

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

Definition at line 927 of file shape_poly_set.h.

References SHAPE_POLY_SET::IterateSegments().

◆ IterateWithHoles() [1/2]

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

Definition at line 804 of file shape_poly_set.h.

805 {
806 return Iterate( 0, OutlineCount() - 1, true );
807 }

References SHAPE_POLY_SET::Iterate(), and SHAPE_POLY_SET::OutlineCount().

Referenced by SHAPE_POLY_SET::IterateFromVertexWithHoles(), and SHAPE_POLY_SET::RemoveNullSegments().

◆ IterateWithHoles() [2/2]

ITERATOR SHAPE_POLY_SET::IterateWithHoles ( int  aOutline)
inlineinherited
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 786 of file shape_poly_set.h.

787 {
788 return Iterate( aOutline, aOutline, true );
789 }

References SHAPE_POLY_SET::Iterate().

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

◆ Mirror()

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

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

2224{
2225 for( POLYGON& poly : m_polys )
2226 {
2227 for( SHAPE_LINE_CHAIN& path : poly )
2228 path.Mirror( aX, aY, aRef );
2229 }
2230
2233}

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

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

◆ Move()

◆ 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:43

References SHAPE::facets.

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

◆ NewHole()

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

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

Definition at line 236 of file shape_poly_set.cpp.

237{
238 SHAPE_LINE_CHAIN empty_path;
239
240 empty_path.SetClosed( true );
241
242 // Default outline is the last one
243 if( aOutline < 0 )
244 aOutline += m_polys.size();
245
246 // Add hole to the selected outline
247 m_polys[aOutline].push_back( empty_path );
248
249 return m_polys.back().size() - 2;
250}

References SHAPE_POLY_SET::m_polys, and SHAPE_LINE_CHAIN::SetClosed().

Referenced by SHAPE_POLY_SET::BuildPolysetFromOrientedPaths(), ZONE::NewHole(), and TransformRingToPolygon().

◆ NewOutline()

int SHAPE_POLY_SET::NewOutline ( )
inherited

Creates a new hole in a given outline.

Definition at line 224 of file shape_poly_set.cpp.

225{
226 SHAPE_LINE_CHAIN empty_path;
227 POLYGON poly;
228
229 empty_path.SetClosed( true );
230 poly.push_back( empty_path );
231 m_polys.push_back( poly );
232 return m_polys.size() - 1;
233}

References SHAPE_POLY_SET::m_polys, and SHAPE_LINE_CHAIN::SetClosed().

Referenced by AR_AUTOPLACER::addFpBody(), addHoleToPolygon(), ZONE_FILLER::addKnockout(), AR_AUTOPLACER::addPad(), LIB_SHAPE::AddPoint(), SCH_SHAPE::AddPoint(), ZONE::AppendCorner(), EDA_SHAPE::beginEdit(), BOARD::BOARD(), BOOST_AUTO_TEST_CASE(), BuildBoardPolygonOutlines(), BuildFootprintPolygonOutlines(), SHAPE_POLY_SET::BuildPolysetFromOrientedPaths(), KI_TEST::CommonTestData::CommonTestData(), TEARDROP_MANAGER::ComputePointsOnPadVia(), GERBER_DRAW_ITEM::ConvertSegmentToPolygon(), D_CODE::ConvertShapeToPolygon(), CornerListToPolygon(), BITMAPCONV_INFO::createOutputData(), BOARD_ADAPTER::createPadWithMargin(), TEARDROP_MANAGER::createTeardrop(), KIGFX::PCB_PAINTER::draw(), KIGFX::GERBVIEW_PAINTER::drawPolygon(), GERBER_FILE_IMAGE::Execute_DCODE_Command(), fillArcPOLY(), PCB_BASE_FRAME::FocusOnItems(), 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::SHAPE_POLY_SET(), DS_DATA_ITEM_POLYGONS::SyncDrawItems(), TransformArcToPolygon(), EDA_TEXT::TransformBoundingBoxToPolygon(), TransformCircleToPolygon(), TransformOvalToPolygon(), EDA_SHAPE::TransformShapeToPolygon(), FP_TEXTBOX::TransformShapeToPolygon(), PCB_TEXTBOX::TransformShapeToPolygon(), FP_TEXT::TransformTextToPolySet(), FP_TEXTBOX::TransformTextToPolySet(), PCB_TEXT::TransformTextToPolySet(), PCB_TEXTBOX::TransformTextToPolySet(), PCB_DIM_ALIGNED::updateGeometry(), PCB_DIM_ORTHOGONAL::updateGeometry(), PCB_DIM_RADIAL::updateGeometry(), PCB_DIM_LEADER::updateGeometry(), and EE_POINT_EDITOR::updateParentItem().

◆ NormalizeAreaOutlines()

int SHAPE_POLY_SET::NormalizeAreaOutlines ( )
inherited

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

1620{
1621 // We are expecting only one main outline, but this main outline can have holes
1622 // if holes: combine holes and remove them from the main outline.
1623 // Note also we are using SHAPE_POLY_SET::PM_STRICTLY_SIMPLE in polygon
1624 // calculations, but it is not mandatory. It is used mainly
1625 // because there is usually only very few vertices in area outlines
1626 SHAPE_POLY_SET::POLYGON& outline = Polygon( 0 );
1627 SHAPE_POLY_SET holesBuffer;
1628
1629 // Move holes stored in outline to holesBuffer:
1630 // The first SHAPE_LINE_CHAIN is the main outline, others are holes
1631 while( outline.size() > 1 )
1632 {
1633 holesBuffer.AddOutline( outline.back() );
1634 outline.pop_back();
1635 }
1636
1638
1639 // If any hole, subtract it to main outline
1640 if( holesBuffer.OutlineCount() )
1641 {
1642 holesBuffer.Simplify( SHAPE_POLY_SET::PM_FAST );
1644 }
1645
1646 // In degenerate cases, simplify might return no outlines
1647 if( OutlineCount() > 0 )
1649
1650 return OutlineCount();
1651}
void BooleanSubtract(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Perform boolean polyset intersection For aFastMode meaning, see function booleanOp.
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new hole to the given outline (default: last) and returns its index.

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

Referenced by BITMAPCONV_INFO::createOutputData().

◆ Outline() [1/2]

SHAPE_LINE_CHAIN & SHAPE_POLY_SET::Outline ( int  aIndex)
inlineinherited

Definition at line 684 of file shape_poly_set.h.

685 {
686 return m_polys[aIndex][0];
687 }

References SHAPE_POLY_SET::m_polys.

Referenced by EE_POINT_EDITOR::addCorner(), ZONE_FILLER::addHatchFillTypeOnZone(), LIB_SHAPE::AddPoint(), SCH_SHAPE::AddPoint(), SHAPE_POLY_SET::Area(), EDA_SHAPE::beginEdit(), BOOST_AUTO_TEST_CASE(), BuildBoardPolygonOutlines(), BuildFootprintPolygonOutlines(), SHAPE_POLY_SET::BuildPolysetFromOrientedPaths(), ZONE::BuildSmoothedPoly(), SHAPE_POLY_SET::CacheTriangulation(), EDA_SHAPE::calcEdit(), FOOTPRINT::CheckNetTies(), collidesWithArea(), TEARDROP_MANAGER::ComputePointsOnPadVia(), EDA_SHAPE::continueEdit(), ConvertOutlineToPolygon(), ConvertPolygonToBlocks(), FOOTPRINT::CoverageRatio(), BITMAPCONV_INFO::createOutputData(), PLACEFILE_GERBER_WRITER::CreatePlaceFile(), DIALOG_PAD_PRIMITIVE_POLY_PROPS::DIALOG_PAD_PRIMITIVE_POLY_PROPS(), KIGFX::DS_PAINTER::draw(), KIGFX::PCB_PAINTER::draw(), CALLBACK_GAL::DrawGlyph(), EDA_SHAPE::endEdit(), GBR_TO_PCB_EXPORTER::export_flashed_copper_item(), DSN::SPECCTRA_DB::fillBOUNDARY(), AR_AUTOPLACER::fillMatrix(), TEARDROP_MANAGER::findAnchorPointsOnTrack(), CADSTAR_SCH_ARCHIVE_LOADER::fixUpLibraryPins(), GERBER_PLOTTER::FlashPadChamferRoundRect(), DXF_PLOTTER::FlashPadCustom(), HPGL_PLOTTER::FlashPadCustom(), PSLIKE_PLOTTER::FlashPadCustom(), GERBER_PLOTTER::FlashPadCustom(), DXF_PLOTTER::FlashPadRoundRect(), GERBER_PLOTTER::FlashPadRoundRect(), HPGL_PLOTTER::FlashPadRoundRect(), PSLIKE_PLOTTER::FlashPadRoundRect(), PCB_PLUGIN::format(), formatPoly(), PCB_PLUGIN::formatRenderCache(), PCB_SHAPE::GetCorners(), DIALOG_BOARD_STATISTICS::getDataFromPCB(), PCB_SHAPE::GetFocusPosition(), LIB_SHAPE::GetItemDescription(), SCH_SHAPE::GetItemDescription(), CADSTAR_PCB_ARCHIVE_LOADER::getPolySetFromCadstarShape(), CADSTAR_SCH_ARCHIVE_LOADER::getScaledLibPart(), EDA_SHAPE::hitTest(), PNS::SOLID::HoleHull(), PNS::SOLID::Hull(), EDA_SHAPE::IsClosed(), GEOM_TEST::IsPolySetValid(), FABMASTER::loadFootprints(), FABMASTER::loadZone(), EDIT_POINTS_FACTORY::Make(), DSN::SPECCTRA_DB::makeIMAGE(), DSN::SPECCTRA_DB::makePADSTACK(), SCH_SEXPR_PARSER::ParseSchematic(), PCB_PARSER::parseZONE(), ZONE_CREATE_HELPER::performZoneCutout(), SCH_SHAPE::Plot(), LIB_SHAPE::Plot(), PlotDrawingSheet(), BRDITEMS_PLOTTER::PlotFilledAreas(), BRDITEMS_PLOTTER::PlotFootprintShape(), BRDITEMS_PLOTTER::PlotPcbShape(), BRDITEMS_PLOTTER::PlotPcbText(), polygonArea(), SCH_SHAPE::Print(), LIB_SHAPE::print(), SCH_SHAPE::PrintBackground(), GERBER_DRAW_ITEM::PrintGerberPoly(), DS_DRAW_ITEM_POLYPOLYGONS::PrintWsItem(), DRC_RTREE::QueryColliding(), RENDER_3D_OPENGL::reload(), EE_POINT_EDITOR::removeCorner(), EE_POINT_EDITOR::removeCornerCondition(), DRC_TEST_PROVIDER_ANNULAR_WIDTH::Run(), DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run(), DRC_TEST_PROVIDER_SLIVER_CHECKER::Run(), SCH_LEGACY_PLUGIN_CACHE::savePolyLine(), EDA_SHAPE::scale(), TEARDROP_MANAGER::SetTeardrops(), SHAPE_POLY_SET::SHAPE_POLY_SET(), ZONE_FILLER::subtractHigherPriorityZones(), PNS_KICAD_IFACE_BASE::syncTextItem(), DRC_INTERACTIVE_COURTYARD_CLEARANCE::testCourtyardClearances(), DRC_TEST_PROVIDER_ZONE_CONNECTIONS::testZoneLayer(), DRC_TEST_PROVIDER_PHYSICAL_CLEARANCE::testZoneLayer(), TransformArcToPolygon(), EE_POINT_EDITOR::updatePoints(), and GBR_TO_PCB_EXPORTER::writePcbZoneItem().

◆ Outline() [2/2]

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

Definition at line 689 of file shape_poly_set.h.

690 {
691 return m_polys[aIndex][0];
692 }

References SHAPE_POLY_SET::m_polys.

◆ OutlineCount()

int SHAPE_POLY_SET::OutlineCount ( ) const
inlineinherited

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

Definition at line 662 of file shape_poly_set.h.

References SHAPE_POLY_SET::m_polys.

Referenced by PCB_POINT_EDITOR::addCorner(), ZONE_FILLER::addHatchFillTypeOnZone(), STEP_PCB_MODEL::AddPadHole(), PAD::addPadPrimitivesToPolygon(), ZONE::AddPolygon(), PAD::AddPrimitivePoly(), TRIANGLE_DISPLAY_LIST::AddToMiddleContourns(), ZONE::AppendCorner(), SHAPE_POLY_SET::Area(), SHAPE_POLY_SET::booleanOp(), BOOST_AUTO_TEST_CASE(), BOOST_FIXTURE_TEST_CASE(), SHAPE_POLY_SET::BuildBBoxCaches(), BuildBoardPolygonOutlines(), BuildConvexHull(), BuildFootprintPolygonOutlines(), SHAPE_POLY_SET::CacheTriangulation(), FOOTPRINT::CheckNetTies(), KI_TEST::CheckShapePolySet(), SHAPE_POLY_SET::CIterate(), SHAPE_POLY_SET::CIterateSegments(), SHAPE_POLY_SET::CIterateSegmentsWithHoles(), SHAPE_POLY_SET::CIterateWithHoles(), collidesWithArea(), SHAPE_POLY_SET::Contains(), ConvertOutlineToPolygon(), convertPolygon(), ConvertPolygonToBlocks(), RENDER_3D_OPENGL::createBoard(), BITMAPCONV_INFO::createOutputData(), CreatePadsShapesSection(), STEP_PCB_MODEL::CreatePCB(), PLACEFILE_GERBER_WRITER::CreatePlaceFile(), CONVERT_TOOL::CreatePolys(), KIGFX::DS_PAINTER::draw(), KIGFX::PCB_PAINTER::draw(), KIGFX::GERBVIEW_PAINTER::draw(), KIGFX::GERBVIEW_PAINTER::drawApertureMacro(), D_CODE::DrawFlashedPolygon(), D_CODE::DrawFlashedShape(), KIGFX::GERBVIEW_PAINTER::drawFlashedShape(), CALLBACK_GAL::DrawGlyph(), 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(), fillArcPOLY(), DSN::SPECCTRA_DB::fillBOUNDARY(), ZONE_FILLER::fillCopperZone(), GEOM_TEST::FilletPolySet(), DXF_PLOTTER::FlashPadCustom(), HPGL_PLOTTER::FlashPadCustom(), PSLIKE_PLOTTER::FlashPadCustom(), GERBER_PLOTTER::FlashPadCustom(), PCB_PLUGIN::formatRenderCache(), SHAPE_POLY_SET::FullPointCount(), RENDER_3D_OPENGL::generateHoles(), RENDER_3D_OPENGL::generateLayerList(), RENDER_3D_OPENGL::generateViasAndPads(), APERTURE_MACRO::GetApertureMacroShape(), PAD::GetBestAnchorPosition(), GERBER_DRAW_ITEM::GetBoundingBox(), FOOTPRINT::GetBoundingHull(), PCB_SHAPE::GetCorners(), DIALOG_BOARD_STATISTICS::getDataFromPCB(), FOOTPRINT::GetEffectiveShape(), CADSTAR_PCB_ARCHIVE_LOADER::getPolySetFromCadstarShape(), SHAPE_POLY_SET::GetRelativeIndices(), D_CODE::GetShapeDim(), SHAPE_POLY_SET::HasTouchingHoles(), EDA_SHAPE::hitTest(), DS_DRAW_ITEM_POLYPOLYGONS::HitTest(), ZONE::HitTestCutout(), isCopperOutside(), GEOM_TEST::IsPolySetValid(), SHAPE_POLY_SET::Iterate(), SHAPE_POLY_SET::IterateSegments(), SHAPE_POLY_SET::IterateSegmentsWithHoles(), SHAPE_POLY_SET::IterateWithHoles(), FABMASTER::loadFootprints(), FABMASTER::loadGraphics(), FABMASTER::loadPolygon(), EDA_SHAPE::makeEffectiveShapes(), SHAPE_POLY_SET::NormalizeAreaOutlines(), SHAPE_POLY_SET::ITERATOR_TEMPLATE< T >::operator bool(), DIALOG_PAD_PROPERTIES::padValuesOK(), PCB_PARSER::parseRenderCache(), ZONE_CREATE_HELPER::performZoneCutout(), BRDITEMS_PLOTTER::PlotFilledAreas(), BRDITEMS_PLOTTER::PlotFootprintShape(), PlotLayerOutlines(), BRDITEMS_PLOTTER::PlotPcbShape(), BRDITEMS_PLOTTER::PlotPcbText(), DXF_PLOTTER::PlotPoly(), PlotSolderMaskLayer(), PlotStandardLayer(), polygonArea(), GERBER_DRAW_ITEM::Print(), DS_DRAW_ITEM_POLYPOLYGONS::PrintWsItem(), DRC_RTREE::QueryColliding(), RENDER_3D_RAYTRACE::Reload(), ZONE::RemoveCutout(), DRC_TEST_PROVIDER_SLIVER_CHECKER::Run(), DRC_TEST_PROVIDER_TEXT_DIMS::Run(), EDA_SHAPE::scale(), EDA_SHAPE::SetPolyShape(), SHAPE_POLY_SET::Subset(), PNS_KICAD_IFACE_BASE::syncZone(), TestConcaveSquareFillet(), DRC_INTERACTIVE_COURTYARD_CLEARANCE::testCourtyardClearances(), DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testCourtyardClearances(), TestSquareFillet(), DRC_TEST_PROVIDER_PHYSICAL_CLEARANCE::testZoneLayer(), 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)
overridevirtualinherited

Reimplemented from SHAPE.

Definition at line 1685 of file shape_poly_set.cpp.

1686{
1687 std::string tmp;
1688
1689 aStream >> tmp;
1690
1691 if( tmp != "polyset" )
1692 return false;
1693
1694 aStream >> tmp;
1695
1696 int n_polys = atoi( tmp.c_str() );
1697
1698 if( n_polys < 0 )
1699 return false;
1700
1701 for( int i = 0; i < n_polys; i++ )
1702 {
1703 POLYGON paths;
1704
1705 aStream >> tmp;
1706
1707 if( tmp != "poly" )
1708 return false;
1709
1710 aStream >> tmp;
1711 int n_outlines = atoi( tmp.c_str() );
1712
1713 if( n_outlines < 0 )
1714 return false;
1715
1716 for( int j = 0; j < n_outlines; j++ )
1717 {
1718 SHAPE_LINE_CHAIN outline;
1719
1720 outline.SetClosed( true );
1721
1722 aStream >> tmp;
1723 int n_vertices = atoi( tmp.c_str() );
1724
1725 for( int v = 0; v < n_vertices; v++ )
1726 {
1727 VECTOR2I p;
1728
1729 aStream >> tmp; p.x = atoi( tmp.c_str() );
1730 aStream >> tmp; p.y = atoi( tmp.c_str() );
1731 outline.Append( p );
1732 }
1733
1734 paths.push_back( outline );
1735 }
1736
1737 m_polys.push_back( paths );
1738 }
1739
1740 return true;
1741}

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

◆ PointOnEdge()

bool SHAPE_POLY_SET::PointOnEdge ( const VECTOR2I aP) const
inherited

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

1778{
1779 // Iterate through all the polygons in the set
1780 for( const POLYGON& polygon : m_polys )
1781 {
1782 // Iterate through all the line chains in the polygon
1783 for( const SHAPE_LINE_CHAIN& lineChain : polygon )
1784 {
1785 if( lineChain.PointOnEdge( aP ) )
1786 return true;
1787 }
1788 }
1789
1790 return false;
1791}

References SHAPE_POLY_SET::m_polys.

◆ Polygon() [1/2]

◆ Polygon() [2/2]

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

Definition at line 722 of file shape_poly_set.h.

723 {
724 return m_polys[aIndex];
725 }

References SHAPE_POLY_SET::m_polys.

◆ RemoveAllContours()

◆ RemoveContour()

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

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

1929{
1930 // Default polygon is the last one
1931 if( aPolygonIdx < 0 )
1932 aPolygonIdx += m_polys.size();
1933
1934 m_polys[aPolygonIdx].erase( m_polys[aPolygonIdx].begin() + aContourIdx );
1935}

References SHAPE_POLY_SET::m_polys.

Referenced by PCB_POINT_EDITOR::removeCorner().

◆ RemoveNullSegments()

int SHAPE_POLY_SET::RemoveNullSegments ( )
inherited

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

Returns
the number of deleted segments.

Definition at line 1938 of file shape_poly_set.cpp.

1939{
1940 int removed = 0;
1941
1942 ITERATOR iterator = IterateWithHoles();
1943
1944 VECTOR2I contourStart = *iterator;
1945 VECTOR2I segmentStart, segmentEnd;
1946
1947 VERTEX_INDEX indexStart;
1948 std::vector<VERTEX_INDEX> indices_to_remove;
1949
1950 while( iterator )
1951 {
1952 // Obtain first point and its index
1953 segmentStart = *iterator;
1954 indexStart = iterator.GetIndex();
1955
1956 // Obtain last point
1957 if( iterator.IsEndContour() )
1958 {
1959 segmentEnd = contourStart;
1960
1961 // Advance
1962 iterator++;
1963
1964 // If we have rolled into the next contour, remember its position
1965 // segmentStart and segmentEnd remain valid for comparison here
1966 if( iterator )
1967 contourStart = *iterator;
1968 }
1969 else
1970 {
1971 // Advance
1972 iterator++;
1973
1974 // If we have reached the end of the SHAPE_POLY_SET, something is broken here
1975 wxCHECK_MSG( iterator, removed, wxT( "Invalid polygon. Reached end without noticing. Please report this error" ) );
1976
1977 segmentEnd = *iterator;
1978 }
1979
1980 // Remove segment start if both points are equal
1981 if( segmentStart == segmentEnd )
1982 {
1983 indices_to_remove.push_back( indexStart );
1984 removed++;
1985 }
1986 }
1987
1988 // Proceed in reverse direction to remove the vertices because they are stored as absolute indices in a vector
1989 // Removing in reverse order preserves the remaining index values
1990 for( auto it = indices_to_remove.rbegin(); it != indices_to_remove.rend(); ++it )
1991 RemoveVertex( *it );
1992
1993 return removed;
1994}
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(), SHAPE_POLY_SET::IterateWithHoles(), and SHAPE_POLY_SET::RemoveVertex().

Referenced by BOOST_AUTO_TEST_CASE(), SHAPE_POLY_SET::chamferFilletPolygon(), and SHAPE_POLY_SET::NormalizeAreaOutlines().

◆ RemoveVertex() [1/2]

void SHAPE_POLY_SET::RemoveVertex ( int  aGlobalIndex)
inherited

Delete the aGlobalIndex-th vertex.

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

Definition at line 2149 of file shape_poly_set.cpp.

2150{
2151 VERTEX_INDEX index;
2152
2153 // Assure the to be removed vertex exists, abort otherwise
2154 if( GetRelativeIndices( aGlobalIndex, &index ) )
2155 RemoveVertex( index );
2156 else
2157 throw( std::out_of_range( "aGlobalIndex-th vertex does not exist" ) );
2158}

References SHAPE_POLY_SET::GetRelativeIndices(), and SHAPE_POLY_SET::RemoveVertex().

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

◆ RemoveVertex() [2/2]

void SHAPE_POLY_SET::RemoveVertex ( VERTEX_INDEX  aRelativeIndices)
inherited

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

2162{
2163 m_polys[aIndex.m_polygon][aIndex.m_contour].Remove( aIndex.m_vertex );
2164}

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

◆ Rotate()

void SHAPE_POLY_SET::Rotate ( const EDA_ANGLE aAngle,
const VECTOR2I aCenter = { 0, 0 } 
)
overridevirtualinherited

◆ SetVertex() [1/2]

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

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

2179{
2180 m_polys[aIndex.m_polygon][aIndex.m_contour].SetPoint( aIndex.m_vertex, aPos );
2181}

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

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

◆ SetVertex() [2/2]

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

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 vertex Return total number of vertices stored in the set.

Definition at line 2167 of file shape_poly_set.cpp.

2168{
2169 VERTEX_INDEX index;
2170
2171 if( GetRelativeIndices( aGlobalIndex, &index ) )
2172 SetVertex( index, aPos );
2173 else
2174 throw( std::out_of_range( "aGlobalIndex-th vertex does not exist" ) );
2175}
void SetVertex(const VERTEX_INDEX &aIndex, const VECTOR2I &aPos)
Accessor function to set the position of a specific point.

References SHAPE_POLY_SET::GetRelativeIndices(), and SHAPE_POLY_SET::SetVertex().

◆ Simplify()

void SHAPE_POLY_SET::Simplify ( POLYGON_MODE  aFastMode)
inherited

◆ SquaredDistance() [1/2]

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

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

2376{
2377 SEG::ecoord currentDistance_sq;
2378 SEG::ecoord minDistance_sq = VECTOR2I::ECOORD_MAX;
2379 VECTOR2I nearest;
2380
2381 // Iterate through all the polygons and get the minimum distance.
2382 for( unsigned int polygonIdx = 0; polygonIdx < m_polys.size(); polygonIdx++ )
2383 {
2384 currentDistance_sq = SquaredDistanceToPolygon( aSegment, polygonIdx,
2385 aNearest ? &nearest : nullptr );
2386
2387 if( currentDistance_sq < minDistance_sq )
2388 {
2389 if( aNearest )
2390 *aNearest = nearest;
2391
2392 minDistance_sq = currentDistance_sq;
2393 }
2394 }
2395
2396 return minDistance_sq;
2397}
VECTOR2I::extended_type ecoord
Definition: seg.h:44
SEG::ecoord SquaredDistanceToPolygon(VECTOR2I aPoint, int aIndex, VECTOR2I *aNearest) const
Compute the minimum distance between the aIndex-th polygon and aPoint.
static constexpr extended_type ECOORD_MAX
Definition: vector2d.h:79

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

◆ SquaredDistance() [2/2]

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

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

2351{
2352 SEG::ecoord currentDistance_sq;
2353 SEG::ecoord minDistance_sq = VECTOR2I::ECOORD_MAX;
2354 VECTOR2I nearest;
2355
2356 // Iterate through all the polygons and get the minimum distance.
2357 for( unsigned int polygonIdx = 0; polygonIdx < m_polys.size(); polygonIdx++ )
2358 {
2359 currentDistance_sq = SquaredDistanceToPolygon( aPoint, polygonIdx,
2360 aNearest ? &nearest : nullptr );
2361
2362 if( currentDistance_sq < minDistance_sq )
2363 {
2364 if( aNearest )
2365 *aNearest = nearest;
2366
2367 minDistance_sq = currentDistance_sq;
2368 }
2369 }
2370
2371 return minDistance_sq;
2372}

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

Referenced by BOOST_AUTO_TEST_CASE(), SHAPE_POLY_SET::Collide(), and DRC_TEST_PROVIDER_ANNULAR_WIDTH::Run().

◆ SquaredDistanceToPolygon() [1/2]

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

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

2315{
2316 // Check if the segment is fully-contained. If so, its midpoint is a good-enough nearest point.
2317 if( containsSingle( aSegment.A, aPolygonIndex, 1 ) &&
2318 containsSingle( aSegment.B, aPolygonIndex, 1 ) )
2319 {
2320 if( aNearest )
2321 *aNearest = ( aSegment.A + aSegment.B ) / 2;
2322
2323 return 0;
2324 }
2325
2326 CONST_SEGMENT_ITERATOR iterator = CIterateSegmentsWithHoles( aPolygonIndex );
2327 SEG::ecoord minDistance = (*iterator).SquaredDistance( aSegment );
2328
2329 if( aNearest && minDistance == 0 )
2330 *aNearest = ( *iterator ).NearestPoint( aSegment );
2331
2332 for( iterator++; iterator && minDistance > 0; iterator++ )
2333 {
2334 SEG::ecoord currentDistance = (*iterator).SquaredDistance( aSegment );
2335
2336 if( currentDistance < minDistance )
2337 {
2338 if( aNearest )
2339 *aNearest = (*iterator).NearestPoint( aSegment );
2340
2341 minDistance = currentDistance;
2342 }
2343 }
2344
2345 // Return the maximum of minDistance and zero
2346 return minDistance < 0 ? 0 : minDistance;
2347}

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

◆ SquaredDistanceToPolygon() [2/2]

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

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

2279{
2280 // We calculate the min dist between the segment and each outline segment. However, if the
2281 // segment to test is inside the outline, and does not cross any edge, it can be seen outside
2282 // the polygon. Therefore test if a segment end is inside (testing only one end is enough).
2283 // Use an accuracy of "1" to say that we don't care if it's exactly on the edge or not.
2284 if( containsSingle( aPoint, aPolygonIndex, 1 ) )
2285 {
2286 if( aNearest )
2287 *aNearest = aPoint;
2288
2289 return 0;
2290 }
2291
2292 CONST_SEGMENT_ITERATOR iterator = CIterateSegmentsWithHoles( aPolygonIndex );
2293
2294 SEG::ecoord minDistance = (*iterator).SquaredDistance( aPoint );
2295
2296 for( iterator++; iterator && minDistance > 0; iterator++ )
2297 {
2298 SEG::ecoord currentDistance = (*iterator).SquaredDistance( aPoint );
2299
2300 if( currentDistance < minDistance )
2301 {
2302 if( aNearest )
2303 *aNearest = (*iterator).NearestPoint( aPoint );
2304
2305 minDistance = currentDistance;
2306 }
2307 }
2308
2309 return minDistance;
2310}

References SHAPE_POLY_SET::CIterateSegmentsWithHoles(), and SHAPE_POLY_SET::containsSingle().

Referenced by SHAPE_POLY_SET::SquaredDistance().

◆ Subset()

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

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

368{
369 assert( aFirstPolygon >= 0 && aLastPolygon <= OutlineCount() );
370
371 SHAPE_POLY_SET newPolySet;
372
373 for( int index = aFirstPolygon; index < aLastPolygon; index++ )
374 newPolySet.m_polys.push_back( Polygon( index ) );
375
376 return newPolySet;
377}

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

Referenced by SHAPE_POLY_SET::UnitSet().

◆ TotalVertices()

int SHAPE_POLY_SET::TotalVertices ( ) const
inherited

Delete aIdx-th polygon from the set.

Definition at line 2250 of file shape_poly_set.cpp.

2251{
2252 int c = 0;
2253
2254 for( const POLYGON& poly : m_polys )
2255 {
2256 for( const SHAPE_LINE_CHAIN& path : poly )
2257 c += path.PointCount();
2258 }
2259
2260 return c;
2261}

References SHAPE_POLY_SET::m_polys, and path.

Referenced by PCB_POINT_EDITOR::buildForPolyOutline(), KI_TEST::CheckShapePolySet(), EDA_SHAPE::Compare(), ZONE::GetNumCorners(), ZONE::HitTest(), SHAPE_POLY_SET::InsertVertex(), FOOTPRINT::cmp_drawings::operator()(), FOOTPRINT::cmp_zones::operator()(), shapesNeedUpdate(), PCB_POINT_EDITOR::updateItem(), PCB_POINT_EDITOR::updatePoints(), and zonesNeedUpdate().

◆ Triangulate()

void OUTLINE_GLYPH::Triangulate ( std::function< void(const VECTOR2I &aPt1, const VECTOR2I &aPt2, const VECTOR2I &aPt3)>  aCallback) const

Definition at line 121 of file glyph.cpp.

124{
125 // Only call CacheTriangulation if it has never been done before. Otherwise we'll hash
126 // the triangulation to see if it has been edited, and glyphs after creation are read-only.
127 if( TriangulatedPolyCount() == 0 )
128 const_cast<OUTLINE_GLYPH*>( this )->CacheTriangulation( false );
129
130 for( unsigned int i = 0; i < TriangulatedPolyCount(); i++ )
131 {
133
134 for( size_t j = 0; j < polygon->GetTriangleCount(); j++ )
135 {
136 VECTOR2I a, b, c;
137 polygon->GetTriangle( j, a, b, c );
138 aCallback( a, b, c );
139 }
140 }
141}
void GetTriangle(int index, VECTOR2I &a, VECTOR2I &b, VECTOR2I &c) const
const TRIANGULATED_POLYGON * TriangulatedPolygon(int aIndex) const
unsigned int TriangulatedPolyCount() const
Return the number of outlines in the set.

References SHAPE_POLY_SET::CacheTriangulation(), SHAPE_POLY_SET::TRIANGULATED_POLYGON::GetTriangle(), SHAPE_POLY_SET::TRIANGULATED_POLYGON::GetTriangleCount(), SHAPE_POLY_SET::TriangulatedPolyCount(), and SHAPE_POLY_SET::TriangulatedPolygon().

Referenced by CALLBACK_GAL::DrawGlyph(), and KIGFX::CAIRO_GAL_BASE::DrawGlyph().

◆ TriangulatedPolyCount()

unsigned int SHAPE_POLY_SET::TriangulatedPolyCount ( ) const
inlineinherited

◆ TriangulatedPolygon()

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

◆ Type()

◆ TypeName()

wxString SHAPE_BASE::TypeName ( ) const
inlineinherited

Definition at line 100 of file shape.h.

101 {
102 return SHAPE_TYPE_asString( m_type );
103 }
static wxString SHAPE_TYPE_asString(SHAPE_TYPE a)
Definition: shape.h:56

References SHAPE_BASE::m_type, and SHAPE_TYPE_asString().

Referenced by Collide().

◆ Unfracture()

void SHAPE_POLY_SET::Unfracture ( POLYGON_MODE  aFastMode)
inherited

Return true if the polygon set has any holes.

Definition at line 1599 of file shape_poly_set.cpp.

1600{
1601 for( POLYGON& path : m_polys )
1603
1604 Simplify( aFastMode ); // remove overlapping holes/degeneracy
1605}
void unfractureSingle(POLYGON &path)

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

Referenced by SHAPE_POLY_SET::InflateWithLinkedHoles().

◆ unfractureSingle()

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

Definition at line 1417 of file shape_poly_set.cpp.

1418{
1419 assert( aPoly.size() == 1 );
1420
1421 struct EDGE
1422 {
1423 int m_index = 0;
1424 SHAPE_LINE_CHAIN* m_poly = nullptr;
1425 bool m_duplicate = false;
1426
1427 EDGE( SHAPE_LINE_CHAIN* aPolygon, int aIndex ) :
1428 m_index( aIndex ),
1429 m_poly( aPolygon )
1430 {}
1431
1432 bool compareSegs( const SEG& s1, const SEG& s2 ) const
1433 {
1434 return (s1.A == s2.B && s1.B == s2.A);
1435 }
1436
1437 bool operator==( const EDGE& aOther ) const
1438 {
1439 return compareSegs( m_poly->CSegment( m_index ),
1440 aOther.m_poly->CSegment( aOther.m_index ) );
1441 }
1442
1443 bool operator!=( const EDGE& aOther ) const
1444 {
1445 return !compareSegs( m_poly->CSegment( m_index ),
1446 aOther.m_poly->CSegment( aOther.m_index ) );
1447 }
1448
1449 struct HASH
1450 {
1451 std::size_t operator()( const EDGE& aEdge ) const
1452 {
1453 const SEG& a = aEdge.m_poly->CSegment( aEdge.m_index );
1454 std::size_t seed = 0xa82de1c0;
1455 hash_combine( seed, a.A.x, a.B.x, a.A.y, a.B.y );
1456 return seed;
1457 }
1458 };
1459 };
1460
1461 struct EDGE_LIST_ENTRY
1462 {
1463 int index;
1464 EDGE_LIST_ENTRY* next;
1465 };
1466
1467 std::unordered_set<EDGE, EDGE::HASH> uniqueEdges;
1468
1469 SHAPE_LINE_CHAIN lc = aPoly[0];
1470 lc.Simplify();
1471
1472 auto edgeList = std::make_unique<EDGE_LIST_ENTRY[]>( lc.SegmentCount() );
1473
1474 for( int i = 0; i < lc.SegmentCount(); i++ )
1475 {
1476 edgeList[i].index = i;
1477 edgeList[i].next = &edgeList[ (i != lc.SegmentCount() - 1) ? i + 1 : 0 ];
1478 }
1479
1480 std::unordered_set<EDGE_LIST_ENTRY*> queue;
1481
1482 for( int i = 0; i < lc.SegmentCount(); i++ )
1483 {
1484 EDGE e( &lc, i );
1485 uniqueEdges.insert( e );
1486 }
1487
1488 for( int i = 0; i < lc.SegmentCount(); i++ )
1489 {
1490 EDGE e( &lc, i );
1491 auto it = uniqueEdges.find( e );
1492
1493 if( it != uniqueEdges.end() && it->m_index != i )
1494 {
1495 int e1 = it->m_index;
1496 int e2 = i;
1497
1498 if( e1 > e2 )
1499 std::swap( e1, e2 );
1500
1501 int e1_prev = e1 - 1;
1502
1503 if( e1_prev < 0 )
1504 e1_prev = lc.SegmentCount() - 1;
1505
1506 int e2_prev = e2 - 1;
1507
1508 if( e2_prev < 0 )
1509 e2_prev = lc.SegmentCount() - 1;
1510
1511 int e1_next = e1 + 1;
1512
1513 if( e1_next == lc.SegmentCount() )
1514 e1_next = 0;
1515
1516 int e2_next = e2 + 1;
1517
1518 if( e2_next == lc.SegmentCount() )
1519 e2_next = 0;
1520
1521 edgeList[e1_prev].next = &edgeList[ e2_next ];
1522 edgeList[e2_prev].next = &edgeList[ e1_next ];
1523 edgeList[i].next = nullptr;
1524 edgeList[it->m_index].next = nullptr;
1525 }
1526 }
1527
1528 for( int i = 0; i < lc.SegmentCount(); i++ )
1529 {
1530 if( edgeList[i].next )
1531 queue.insert( &edgeList[i] );
1532 }
1533
1534 auto edgeBuf = std::make_unique<EDGE_LIST_ENTRY* []>( lc.SegmentCount() );
1535
1536 int n = 0;
1537 int outline = -1;
1538
1539 POLYGON result;
1540 double max_poly = 0.0;
1541
1542 while( queue.size() )
1543 {
1544 EDGE_LIST_ENTRY* e_first = *queue.begin();
1545 EDGE_LIST_ENTRY* e = e_first;
1546 int cnt = 0;
1547
1548 do
1549 {
1550 edgeBuf[cnt++] = e;
1551 e = e->next;
1552 } while( e && e != e_first );
1553
1554 SHAPE_LINE_CHAIN outl;
1555
1556 for( int i = 0; i < cnt; i++ )
1557 {
1558 VECTOR2I p = lc.CPoint( edgeBuf[i]->index );
1559 outl.Append( p );
1560 queue.erase( edgeBuf[i] );
1561 }
1562
1563 outl.SetClosed( true );
1564
1565 double area = std::fabs( outl.Area() );
1566
1567 if( area > max_poly )
1568 {
1569 outline = n;
1570 max_poly = area;
1571 }
1572
1573 result.push_back( outl );
1574 n++;
1575 }
1576
1577 if( outline > 0 )
1578 std::swap( result[0], result[outline] );
1579
1580 aPoly = result;
1581}
SHAPE_LINE_CHAIN & Simplify(bool aRemoveColinear=true)
Simplify the line chain by removing colinear adjacent segments and duplicate vertices.
int SegmentCount() const
Return the number of segments in this line chain.
const SEG CSegment(int aIndex) const
Return a constant copy of the aIndex segment in the line chain.
static void hash_combine(std::size_t &seed)
This is a dummy function to take the final case of hash_combine below.
Definition: hash.h:34
const bool operator==(const COLOR4D &lhs, const COLOR4D &rhs)
Equality operator, are two colors equal.
Definition: color4d.cpp:268
const bool operator!=(const COLOR4D &lhs, const COLOR4D &rhs)
Not equality operator, are two colors not equal.
Definition: color4d.cpp:274

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

Referenced by SHAPE_POLY_SET::Unfracture().

◆ UnitSet()

SHAPE_POLY_SET SHAPE_POLY_SET::UnitSet ( int  aPolygonIndex)
inlineinherited

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

Definition at line 705 of file shape_poly_set.h.

References SHAPE_POLY_SET::Subset().

◆ UpdateTriangulationDataHash()

void SHAPE_POLY_SET::UpdateTriangulationDataHash ( )
inherited

Definition at line 2025 of file shape_poly_set.cpp.

2026{
2027 m_hash = checksum();
2028}

References SHAPE_POLY_SET::checksum(), and SHAPE_POLY_SET::m_hash.

◆ VertexCount()

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

Return the number of points in the shape poly set.

mainly for reports

Definition at line 321 of file shape_poly_set.cpp.

322{
323 if( m_polys.size() == 0 ) // Empty poly set
324 return 0;
325
326 if( aOutline < 0 ) // Use last outline
327 aOutline += m_polys.size();
328
329 int idx;
330
331 if( aHole < 0 )
332 idx = 0;
333 else
334 idx = aHole + 1;
335
336 if( aOutline >= (int) m_polys.size() ) // not existing outline
337 return 0;
338
339 if( idx >= (int) m_polys[aOutline].size() ) // not existing hole
340 return 0;
341
342 return m_polys[aOutline][idx].PointCount();
343}

References SHAPE_POLY_SET::m_polys.

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

Member Data Documentation

◆ facets

std::list< FACET* > SHAPE::facets
privateinherited

Definition at line 143 of file wrlfacet.h.

Referenced by SHAPE::CalcShape(), and SHAPE::NewFacet().

◆ m_hash

◆ m_polys

std::vector<POLYGON> SHAPE_POLY_SET::m_polys
privateinherited

Definition at line 1480 of file shape_poly_set.h.

Referenced by SHAPE_POLY_SET::AddHole(), SHAPE_POLY_SET::AddOutline(), SHAPE_POLY_SET::Append(), SHAPE_POLY_SET::ArcCount(), SHAPE_POLY_SET::BBox(), SHAPE_POLY_SET::BBoxFromCaches(), SHAPE_POLY_SET::booleanOp(), SHAPE_POLY_SET::Chamfer(), SHAPE_POLY_SET::checksum(), SHAPE_POLY_SET::CHole(), SHAPE_POLY_SET::ClearArcs(), SHAPE_POLY_SET::Contains(), SHAPE_POLY_SET::containsSingle(), SHAPE_POLY_SET::COutline(), SHAPE_POLY_SET::CPolygon(), SHAPE_POLY_SET::CVertex(), SHAPE_POLY_SET::DeletePolygon(), SHAPE_POLY_SET::DeletePolygonAndTriangulationData(), SHAPE_POLY_SET::Fillet(), SHAPE_POLY_SET::Format(), SHAPE_POLY_SET::Fracture(), SHAPE_POLY_SET::FullPointCount(), SHAPE_POLY_SET::GetArcs(), SHAPE_POLY_SET::GetGlobalIndex(), SHAPE_POLY_SET::GetNeighbourIndexes(), SHAPE_POLY_SET::HasHoles(), SHAPE_POLY_SET::Hole(), SHAPE_POLY_SET::HoleCount(), SHAPE_POLY_SET::importPaths(), SHAPE_POLY_SET::importPolyPath(), SHAPE_POLY_SET::importTree(), SHAPE_POLY_SET::inflate1(), SHAPE_POLY_SET::inflate2(), SHAPE_POLY_SET::InsertVertex(), SHAPE_POLY_SET::IsEmpty(), SHAPE_POLY_SET::IsSelfIntersecting(), SHAPE_POLY_SET::Mirror(), SHAPE_POLY_SET::Move(), SHAPE_POLY_SET::NewHole(), SHAPE_POLY_SET::NewOutline(), SHAPE_POLY_SET::operator=(), SHAPE_POLY_SET::Outline(), SHAPE_POLY_SET::OutlineCount(), SHAPE_POLY_SET::Parse(), SHAPE_POLY_SET::PointOnEdge(), SHAPE_POLY_SET::Polygon(), SHAPE_POLY_SET::RemoveAllContours(), SHAPE_POLY_SET::RemoveContour(), SHAPE_POLY_SET::RemoveVertex(), SHAPE_POLY_SET::Rotate(), SHAPE_POLY_SET::SetVertex(), SHAPE_POLY_SET::SquaredDistance(), SHAPE_POLY_SET::Subset(), SHAPE_POLY_SET::TotalVertices(), SHAPE_POLY_SET::Unfracture(), and SHAPE_POLY_SET::VertexCount().

◆ m_triangulatedPolys

◆ m_triangulationValid

◆ m_type

SHAPE_TYPE SHAPE_BASE::m_type
protectedinherited

< type of our shape

Definition at line 116 of file shape.h.

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

◆ 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 128 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: