62 return ( aLeft - aRight ).SquaredEuclideanNorm() <=
SEG::Square( aLimit );
76 return ( aRef - aFirst ).SquaredEuclideanNorm() < ( aRef - aSecond ).SquaredEuclideanNorm();
90 const std::vector<PCB_SHAPE*>& aList,
unsigned aLimit )
95 if( graphic == aShape || ( graphic->GetFlags() &
SKIP_STRUCT ) != 0 )
98 if( aPoint == graphic->GetStart() || aPoint == graphic->GetEnd() )
111 if( graphic == aShape )
114 d_sq = ( pt - graphic->GetStart() ).SquaredEuclideanNorm();
116 if( d_sq < closest_dist_sq )
118 closest_dist_sq = d_sq;
119 closest_graphic = graphic;
122 d_sq = ( pt - graphic->GetEnd() ).SquaredEuclideanNorm();
124 if( d_sq < closest_dist_sq )
126 closest_dist_sq = d_sq;
127 closest_graphic = graphic;
131 return closest_graphic;
147 int aErrorMax,
int aChainingEpsilon,
150 if( aSegList.size() == 0 )
153 bool polygonComplete =
false;
154 bool selfIntersecting =
false;
159 std::set<PCB_SHAPE*> startCandidates( aSegList.begin(), aSegList.end() );
163 wxPoint xmin = wxPoint( INT_MAX, 0 );
166 for(
size_t i = 0; i < aSegList.size(); i++ )
176 if( graphic->
GetStart().x < xmin.x )
182 if( graphic->
GetEnd().x < xmin.x )
192 wxPoint pstart = graphic->
GetStart();
199 for(
int step = 1; step<=steps; ++step )
201 double rotation = (
angle * step ) / steps;
224 if( graphic->
GetRadius() > 0 && pt.x < xmin.x )
250 double orientation = 0.0;
259 for(
auto iter = poly.
CIterate(); iter; iter++ )
282 std::map<std::pair<VECTOR2I, VECTOR2I>,
PCB_SHAPE*> segOwners;
287 auto it = segOwners.find( std::make_pair( seg.A, seg.B ) );
288 return it == segOwners.end() ? nullptr : it->second;
299 startCandidates.erase( graphic );
306 polygonComplete =
true;
314 for(
const wxPoint& pt : pts )
317 segOwners[ std::make_pair( pts[0], pts[1] ) ] = graphic;
318 segOwners[ std::make_pair( pts[1], pts[2] ) ] = graphic;
319 segOwners[ std::make_pair( pts[2], pts[3] ) ] = graphic;
320 segOwners[ std::make_pair( pts[3], pts[0] ) ] = graphic;
322 polygonComplete =
true;
326 double orientation = 0.0;
348 segOwners[ std::make_pair( prevPt, pt ) ] = graphic;
350 prevPt = (wxPoint) pt;
353 polygonComplete =
true;
360 wxPoint startPt = graphic->
GetEnd();
364 aPolygons.
Append( prevPt );
380 wxASSERT( prevGraphic );
381 (*aErrorHandler)(
_(
"(self-intersecting)" ), prevGraphic, graphic, prevPt );
384 selfIntersecting =
true;
398 nextPt = graphic->
GetEnd();
402 aPolygons.
Append( nextPt );
403 segOwners[ std::make_pair( prevPt, nextPt ) ] = graphic;
413 wxPoint pstart = graphic->
GetStart();
414 wxPoint pend = graphic->
GetEnd();
425 std::swap( pstart, pend );
429 for(
int step = 1; step < steps; ++step )
431 double rotation = (
angle * step ) / steps;
436 segOwners[ std::make_pair( prevPt, pt ) ] = graphic;
442 segOwners[ std::make_pair( prevPt, pend ) ] = graphic;
454 bool reverse =
false;
462 nextPt = graphic->
GetEnd();
480 segOwners[ std::make_pair( prevPt, pt ) ] = graphic;
494 segOwners[ std::make_pair( prevPt, pt ) ] = graphic;
511 PCB_SHAPE* nextGraphic =
findNext( graphic, prevPt, aSegList, aChainingEpsilon );
515 prevGraphic = graphic;
516 graphic = nextGraphic;
518 startCandidates.erase( graphic );
526 polygonComplete =
true;
529 else if( nextGraphic )
532 (*aErrorHandler)(
_(
"(self-intersecting)" ), graphic, nextGraphic, prevPt );
534 polygonComplete =
false;
540 (*aErrorHandler)(
_(
"(not a closed shape)" ), graphic,
nullptr, prevPt );
542 polygonComplete =
false;
550 while( startCandidates.size() )
552 int hole = aPolygons.
NewHole();
556 graphic = (
PCB_SHAPE*) *startCandidates.begin();
558 startCandidates.erase( startCandidates.begin() );
564 double orientation = 0.0;
579 aPolygons.
Append( pt, -1, hole );
584 segOwners[ std::make_pair( prevPt, pt ) ] = graphic;
586 prevPt = (wxPoint) pt;
593 double angle = 3600.0;
594 wxPoint start = center;
601 for(
int step = 0; step < steps; ++step )
603 double rotation = (
angle * step ) / steps;
605 RotatePoint( &nextPt.x, &nextPt.y, center.x, center.y, rotation );
606 aPolygons.
Append( nextPt, -1, hole );
611 segOwners[ std::make_pair( prevPt, nextPt ) ] = graphic;
620 for(
const wxPoint& pt : pts )
622 aPolygons.
Append( pt, -1, hole );
627 segOwners[ std::make_pair( prevPt, pt ) ] = graphic;
629 prevPt = (wxPoint) pt;
637 wxPoint startPt = graphic->
GetEnd();
639 aPolygons.
Append( prevPt, -1, hole );
654 nextPt = graphic->
GetEnd();
658 aPolygons.
Append( nextPt, -1, hole );
659 segOwners[ std::make_pair( prevPt, nextPt ) ] = graphic;
668 wxPoint pstart = graphic->
GetStart();
669 wxPoint pend = graphic->
GetEnd();
680 std::swap( pstart, pend );
684 for(
int step = 1; step < steps; ++step )
686 double rotation = (
angle * step ) / steps;
691 aPolygons.
Append( pt, -1, hole );
692 segOwners[ std::make_pair( prevPt, pt ) ] = graphic;
697 aPolygons.
Append( pend, -1, hole );
698 segOwners[ std::make_pair( prevPt, pend ) ] = graphic;
708 bool reverse =
false;
715 nextPt = graphic->
GetEnd();
728 aPolygons.
Append( pt, -1, hole );
729 segOwners[ std::make_pair( prevPt, pt ) ] = graphic;
737 aPolygons.
Append( pt, -1, hole );
738 segOwners[ std::make_pair( prevPt, pt ) ] = graphic;
748 wxFAIL_MSG( wxT(
"ConvertOutlineToPolygon not implemented for " )
755 PCB_SHAPE* nextGraphic =
findNext( graphic, prevPt, aSegList, aChainingEpsilon );
759 graphic = nextGraphic;
761 startCandidates.erase( graphic );
771 else if( nextGraphic )
774 (*aErrorHandler)(
_(
"(self-intersecting)" ), graphic, nextGraphic, prevPt );
776 polygonComplete =
false;
782 (*aErrorHandler)(
_(
"(not a closed shape)" ), graphic,
nullptr, prevPt );
784 polygonComplete =
false;
791 if( !polygonComplete )
802 for( ++seg2; seg2; seg2++ )
805 if( *seg1 == *seg2 || ( ( *seg1 ).A == ( *seg2 ).B && ( *seg1 ).B == ( *seg2 ).A ) )
813 (*aErrorHandler)(
_(
"(self-intersecting)" ), a, b, (wxPoint) ( *seg1 ).A );
816 selfIntersecting =
true;
819 if( boost::optional<VECTOR2I> pt = seg1.Get().Intersect( seg2.Get(), true ) )
827 (*aErrorHandler)(
_(
"(self-intersecting)" ), a, b, (wxPoint) pt.get() );
830 selfIntersecting =
true;
835 return !selfIntersecting;
850 bool success =
false;
854 items.
Collect( aBoard, scan_graphics );
857 std::vector<PCB_SHAPE*> segList;
859 for(
int ii = 0; ii < items.
GetCount(); ii++ )
862 segList.push_back( static_cast<PCB_SHAPE*>( items[ii] ) );
894 corner.y = bbbox.
GetEnd().y;
895 aOutlines.
Append( corner );
899 corner.x = bbbox.
GetEnd().x;
901 aOutlines.
Append( corner );
949 bool padOutside =
false;
959 wxPoint padPos =
pad->GetPosition();
961 padPos.x, padPos.y );
966 wxPoint padPos =
pad->GetPosition();
968 padPos.x, padPos.y );
976 int aOutlineNum = 0 )
978 int minDistance = -1;
984 int dis = seg.Distance( aEndPoint );
986 if( minDistance < 0 || ( dis < minDistance ) )
989 projPoint = seg.NearestPoint( aEndPoint );
1005 bool foundA =
false;
1006 bool foundB =
false;
1024 if( foundA && foundB )
1027 if( foundSegs == 0 )
1031 seg.
A.
x, seg.
A.
y, seg.
B.
x, seg.
B.
y );
1039 seg.
A.
x, seg.
A.
y, seg.
B.
x, seg.
B.
y );
1076 bool success =
false;
1080 items.
Collect( aBoard, scan_graphics );
1083 std::vector<PCB_SHAPE*> segList;
1085 for(
int ii = 0; ii < items.
GetCount(); ii++ )
1087 if( items[ii]->GetLayer() ==
Edge_Cuts )
1088 segList.push_back( static_cast<PCB_SHAPE*>( items[ii] ) );
1091 if( !segList.empty() )
1117 for(
int j = 0; j < outlines.
HoleCount( i ); j++ )
1122 aOutlines.
AddHole( hole, -1 );
1130 aOutlines = outlines;
1148 std::vector<SHAPE_LINE_CHAIN> closedChains;
1149 std::vector<SHAPE_LINE_CHAIN> openChains;
1153 openChains.push_back( outlines.
Outline( 0 ) );
1155 for(
int j = 0; j < outlines.
HoleCount( 0 ); j++ )
1162 closedChains.push_back( hole );
1167 openChains.push_back( hole );
1201 wxLogTrace(
traceBoardOutline, wxT(
"Only 1 line segment in provided outline" ) );
1203 startSeg = chain.
Segment( 0 );
1211 if( inter0 && inter2 && !inter1 && !inter3 )
1231 else if( inter1 && inter3 && !inter0 && !inter2 )
1254 wxLogTrace(
traceBoardOutline, wxT(
"Segment intersects two perpendicular bbox " 1283 else if( hit1 && hit2 )
1302 else if( hit2 && hit3 )
1377 aOutlines.
AddHole( closedChain, -1 );
int NewHole(int aOutline=-1)
Adds a new outline to the set and returns its index.
const EDA_RECT GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
const std::vector< wxPoint > & GetBezierPoints() const
bool BuildFootprintPolygonOutlines(BOARD *aBoard, SHAPE_POLY_SET &aOutlines, int aErrorMax, int aChainingEpsilon, OUTLINE_ERROR_HANDLER *aErrorHandler)
This function is used to extract a board outline for a footprint view.
int OutlineCount() const
Return the number of vertices in a given outline/hole.
static PCB_SHAPE * findNext(PCB_SHAPE *aShape, const wxPoint &aPoint, const std::vector< PCB_SHAPE * > &aList, unsigned aLimit)
Searches for a PCB_SHAPE matching a given end point or start point in a list.
SEGMENT_ITERATOR IterateSegmentsWithHoles()
Return an iterator object, for the aOutline-th outline in the set (with holes).
Implementation of conversion functions that require both schematic and board internal units.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
const wxPoint & GetStart() const
Return the starting point of the graphic.
const EDA_RECT GetBoardEdgesBoundingBox() const
Return the board bounding box calculated using exclusively the board edges (graphics on Edge....
VECTOR2I::extended_type ecoord
void SetFlags(EDA_ITEM_FLAGS aMask)
double GetArcAngle() const
SHAPE_LINE_CHAIN & Hole(int aOutline, int aHole)
Return the aIndex-th subpolygon in the set.
class FP_SHAPE, a footprint edge
bool closer_to_first(VECTOR2I aRef, VECTOR2I aFirst, VECTOR2I aSecond)
Function closer_to_first Local method which qualifies whether the start or end point of a segment is ...
OPT_VECTOR2I IntersectLines(const SEG &aSeg) const
Compute the intersection point of lines passing through ends of (this) and aSeg.
void RotatePoint(int *pX, int *pY, double angle)
static SEG::ecoord Square(int a)
search types array terminator (End Of Types)
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
const wxChar * traceBoardOutline
Flag to enable debug tracing for the board outline creation.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
This file contains miscellaneous commonly used macros and functions.
std::vector< wxPoint > GetRectCorners() const
int GetCount() const
Return the number of objects in the list.
const wxPoint GetEnd() const
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
const wxPoint & GetEnd() const
Return the ending point of the graphic.
bool BuildBoardPolygonOutlines(BOARD *aBoard, SHAPE_POLY_SET &aOutlines, int aErrorMax, int aChainingEpsilon, OUTLINE_ERROR_HANDLER *aErrorHandler)
Extracts the board outlines and build a closed polygon from lines, arcs and circle items on edge cut ...
FOOTPRINT * GetFirstFootprint() const
Get the first footprint on the board or nullptr.
bool IsClosed() const override
OPT< VECTOR2I > OPT_VECTOR2I
Represent a set of closed polygons.
SHAPE_LINE_CHAIN & Outline(int aIndex)
const wxPoint GetOrigin() const
wxPoint GetCenter() const override
This defaults to the center of the bounding box if not overridden.
void TransformCircleToPolygon(SHAPE_LINE_CHAIN &aCornerBuffer, const wxPoint &aCenter, int aRadius, int aError, ERROR_LOC aErrorLoc, int aMinSegCount=0)
Convert a circle to a polygon, using multiple straight lines.
#define UNIMPLEMENTED_FOR(type)
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
a few functions useful in geometry calculations.
bool isCopperOutside(const FOOTPRINT *aMod, SHAPE_POLY_SET &aShape)
wxString SHAPE_T_asString() const
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,...
int NewOutline()
Creates a new hole in a given outline.
int HoleCount(int aOutline) const
Return the reference to aIndex-th outline in the set.
CONST_ITERATOR CIterate(int aFirst, int aLast, bool aIterateHoles=false) const
int SegmentCount() const
Return the number of segments in this line chain.
VECTOR2I projectPointOnSegment(const VECTOR2I &aEndPoint, const SHAPE_POLY_SET &aOutline, int aOutlineNum=0)
virtual const VECTOR2I GetPoint(int aIndex) const override
void Collect(BOARD_ITEM *aBoard, const KICAD_T aScanList[])
Collect BOARD_ITEM objects using this class's Inspector method, which does the collection.
int AddHole(const SHAPE_LINE_CHAIN &aHole, int aOutline=-1)
Return the area of this poly set.
SHAPE_POLY_SET & GetPolyShape()
EDA_ITEM_FLAGS GetFlags() const
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new hole to the given outline (default: last) and returns its index.
void RebuildBezierToSegmentsPointsList(int aMinSegLen)
Rebuild the m_bezierPoints vertex list that approximate the Bezier curve by a list of segments.
int findEndSegments(SHAPE_LINE_CHAIN &aChain, SEG &aStartSeg, SEG &aEndSeg)
SEG Segment(int aIndex)
Return a copy of the aIndex-th segment in the line chain.
bool close_enough(VECTOR2I aLeft, VECTOR2I aRight, unsigned aLimit)
Function close_enough is a local and tunable method of qualifying the proximity of two points.
#define SKIP_STRUCT
flag indicating that the structure should be ignored
FOOTPRINT * GetParentFootprint() const
Return the parent footprint or NULL if PCB_SHAPE does not belong to a footprint.
Information pertinent to a Pcbnew printed circuit board.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
Handle the component boundary box.
EDA_RECT ComputeBoundingBox(bool aBoardEdgesOnly=false) const
Calculate the bounding box containing all board items (or board edge segments).
const std::function< void(const wxString &msg, BOARD_ITEM *itemA, BOARD_ITEM *itemB, const wxPoint &pt)> OUTLINE_ERROR_HANDLER
CONST_SEGMENT_ITERATOR CIterateSegments(int aFirst, int aLast, bool aIterateHoles=false) const
Return an iterator object, for iterating aPolygonIdx-th polygon edges.
bool ConvertOutlineToPolygon(std::vector< PCB_SHAPE * > &aSegList, SHAPE_POLY_SET &aPolygons, int aErrorMax, int aChainingEpsilon, OUTLINE_ERROR_HANDLER *aErrorHandler)
Function ConvertOutlineToPolygon Build a polygon (with holes) from a PCB_SHAPE list,...
Collect all BOARD_ITEM objects of a given set of KICAD_T type(s).
class PCB_SHAPE, a segment not on copper layers
static constexpr int Millimeter2iu(double mm)
int GetArcToSegmentCount(int aRadius, int aErrorMax, double aArcAngleDegree)
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Inflate the rectangle horizontally by dx and vertically by dy.
bool Contains(const SEG &aSeg) const
void buildBoardBoundingBoxPoly(const BOARD *aBoard, SHAPE_POLY_SET &aOutline)
Get the complete bounding box of the board (including all items).
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...