KiCad PCB EDA Suite
Loading...
Searching...
No Matches
convert_shape_list_to_polygon.cpp File Reference
#include <unordered_set>
#include <deque>
#include <trigo.h>
#include <macros.h>
#include <math/vector2d.h>
#include <pcb_shape.h>
#include <footprint.h>
#include <pad.h>
#include <base_units.h>
#include <convert_basic_shapes_to_polygon.h>
#include <geometry/shape_poly_set.h>
#include <geometry/geometry_utils.h>
#include <geometry/roundrect.h>
#include <geometry/shape_ellipse.h>
#include <convert_shape_list_to_polygon.h>
#include <board.h>
#include <board_design_settings.h>
#include <collectors.h>
#include <set>
#include <nanoflann.hpp>
#include <wx/log.h>

Go to the source code of this file.

Classes

class  SCOPED_FLAGS_CLEANER
 
struct  PCB_SHAPE_ENDPOINTS_ADAPTOR
 
struct  CHAIN_NEIGHBOURS
 

Typedefs

using KDTree
 

Functions

static bool close_enough (VECTOR2I aLeft, VECTOR2I aRight, unsigned aLimit)
 Local and tunable method of qualifying the proximity of two points.
 
static bool closer_to_first (VECTOR2I aRef, VECTOR2I aFirst, VECTOR2I aSecond)
 Local method which qualifies whether the start or end point of a segment is closest to a point.
 
static VECTOR2I free_end (const PCB_SHAPE *aFirst, const PCB_SHAPE *aSecond)
 Return the end of aFirst that does not join aSecond.
 
static bool isCopperOutside (const FOOTPRINT *aFootprint, SHAPE_POLY_SET &aShape)
 
static void processClosedShape (PCB_SHAPE *aShape, SHAPE_LINE_CHAIN &aContour, std::map< std::pair< VECTOR2I, VECTOR2I >, PCB_SHAPE * > &aShapeOwners, int aErrorMax, bool aAllowUseArcsInPolygons)
 
static void processShapeSegment (PCB_SHAPE *aShape, SHAPE_LINE_CHAIN &aContour, VECTOR2I &aPrevPt, std::map< std::pair< VECTOR2I, VECTOR2I >, PCB_SHAPE * > &aShapeOwners, int aErrorMax, int aChainingEpsilon, bool aAllowUseArcsInPolygons)
 
static std::map< int, std::vector< int > > buildContourHierarchy (const std::vector< SHAPE_LINE_CHAIN > &aContours)
 
static bool addOutlinesToPolygon (const std::vector< SHAPE_LINE_CHAIN > &aContours, const std::map< int, std::vector< int > > &aContourHierarchy, const std::set< int > &aCrossingContours, SHAPE_POLY_SET &aPolygons, bool aAllowDisjoint, OUTLINE_ERROR_HANDLER *aErrorHandler, const std::function< PCB_SHAPE *(const SEG &)> &aFetchOwner, std::map< int, int > &aContourToOutlineIdxMap)
 
static void addHolesToPolygon (const std::vector< SHAPE_LINE_CHAIN > &aContours, const std::map< int, std::vector< int > > &aContourHierarchy, const std::map< int, int > &aContourToOutlineIdxMap, SHAPE_POLY_SET &aPolygons, bool aAllowUseArcsInPolygons, const std::set< int > &aCrossingContours)
 
static bool checkSelfIntersections (SHAPE_POLY_SET &aPolygons, OUTLINE_ERROR_HANDLER *aErrorHandler, const std::function< PCB_SHAPE *(const SEG &)> &aFetchOwner)
 
static bool closerEndpoint (const nanoflann::ResultItem< uint32_t, double > &aLeft, const nanoflann::ResultItem< uint32_t, double > &aRight)
 
template<typename CONSUMED_FUNC>
static CHAIN_NEIGHBOURS findNeighbours (PCB_SHAPE *aShape, const VECTOR2I &aPoint, const KDTree &aKdTree, const PCB_SHAPE_ENDPOINTS_ADAPTOR &aAdaptor, double aChainingEpsilon, CONSUMED_FUNC aIsConsumed)
 Find the shapes that could continue a chain at aPoint.
 
static std::set< int > findCrossingContours (const std::vector< SHAPE_LINE_CHAIN > &aContours)
 
static bool buildChainedClosedContour (PCB_SHAPE *aStart, std::set< PCB_SHAPE * > &aRemaining, const KDTree &aKdTree, const PCB_SHAPE_ENDPOINTS_ADAPTOR &aAdaptor, int aErrorMax, int aChainingEpsilon, SHAPE_LINE_CHAIN &aContour, PCB_SHAPE *&aOwnerShape)
 
bool doConvertOutlineToPolygon (std::vector< PCB_SHAPE * > &aShapeList, SHAPE_POLY_SET &aPolygons, int aErrorMax, int aChainingEpsilon, bool aAllowDisjoint, OUTLINE_ERROR_HANDLER *aErrorHandler, bool aAllowUseArcsInPolygons, SCOPED_FLAGS_CLEANER &aCleaner)
 
bool ConvertOutlineToPolygon (std::vector< PCB_SHAPE * > &aShapeList, SHAPE_POLY_SET &aPolygons, int aErrorMax, int aChainingEpsilon, bool aAllowDisjoint, OUTLINE_ERROR_HANDLER *aErrorHandler, bool aAllowUseArcsInPolygons)
 Build a polygon set with holes from a PCB_SHAPE list.
 
bool TestBoardOutlinesGraphicItems (BOARD *aBoard, int aMinDist, OUTLINE_ERROR_HANDLER *aErrorHandler)
 Test a board graphic items on edge cut layer for validity.
 
bool BuildBoardPolygonOutlines (BOARD *aBoard, SHAPE_POLY_SET &aOutlines, int aErrorMax, int aChainingEpsilon, bool aInferOutlineIfNecessary, OUTLINE_ERROR_HANDLER *aErrorHandler, bool aAllowUseArcsInPolygons)
 Extract the board outlines and build a closed polygon from lines, arcs and circle items on edge cut layer.
 
void buildBoardBoundingBoxPoly (const BOARD *aBoard, SHAPE_POLY_SET &aOutline)
 Get the complete bounding box of the board (including all items).
 
VECTOR2I projectPointOnSegment (const VECTOR2I &aEndPoint, const SHAPE_POLY_SET &aOutline, int aOutlineNum=0)
 
int findEndSegments (SHAPE_LINE_CHAIN &aChain, SEG &aStartSeg, SEG &aEndSeg)
 
bool BuildFootprintPolygonOutlines (BOARD *aBoard, SHAPE_POLY_SET &aOutlines, int aErrorMax, int aChainingEpsilon, OUTLINE_ERROR_HANDLER *aErrorHandler)
 Extract a board outline for a footprint view.
 

Variables

const wxChar * traceBoardOutline = wxT( "KICAD_BOARD_OUTLINE" )
 Flag to enable debug tracing for the board outline creation.
 

Typedef Documentation

◆ KDTree

using KDTree
Initial value:
nanoflann::KDTreeSingleIndexAdaptor<nanoflann::L2_Simple_Adaptor<double, PCB_SHAPE_ENDPOINTS_ADAPTOR>,
2 >

Definition at line 189 of file convert_shape_list_to_polygon.cpp.

Function Documentation

◆ addHolesToPolygon()

static void addHolesToPolygon ( const std::vector< SHAPE_LINE_CHAIN > & aContours,
const std::map< int, std::vector< int > > & aContourHierarchy,
const std::map< int, int > & aContourToOutlineIdxMap,
SHAPE_POLY_SET & aPolygons,
bool aAllowUseArcsInPolygons,
const std::set< int > & aCrossingContours )
static

◆ addOutlinesToPolygon()

static bool addOutlinesToPolygon ( const std::vector< SHAPE_LINE_CHAIN > & aContours,
const std::map< int, std::vector< int > > & aContourHierarchy,
const std::set< int > & aCrossingContours,
SHAPE_POLY_SET & aPolygons,
bool aAllowDisjoint,
OUTLINE_ERROR_HANDLER * aErrorHandler,
const std::function< PCB_SHAPE *(const SEG &)> & aFetchOwner,
std::map< int, int > & aContourToOutlineIdxMap )
static

◆ buildBoardBoundingBoxPoly()

void buildBoardBoundingBoxPoly ( const BOARD * aBoard,
SHAPE_POLY_SET & aOutline )

Get the complete bounding box of the board (including all items).

The vertex numbers and segment numbers of the rectangle returned. 1 ------------— |1 2| 0| |2 |0 3| ------------— 3

Definition at line 1537 of file convert_shape_list_to_polygon.cpp.

References SHAPE_POLY_SET::AddOutline(), chain, BOARD::ComputeBoundingBox(), BOARD::GetBoundingBox(), BOX2< Vec >::GetEnd(), BOX2< Vec >::GetHeight(), BOX2< Vec >::GetOrigin(), BOX2< Vec >::GetWidth(), BOX2< Vec >::Inflate(), pcbIUScale, SHAPE_POLY_SET::RemoveAllContours(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by BuildFootprintPolygonOutlines(), and RENDER_3D_RAYTRACE_BASE::Reload().

◆ BuildBoardPolygonOutlines()

bool BuildBoardPolygonOutlines ( BOARD * aBoard,
SHAPE_POLY_SET & aOutlines,
int aErrorMax,
int aChainingEpsilon,
bool aInferOutlineIfNecessary,
OUTLINE_ERROR_HANDLER * aErrorHandler = nullptr,
bool aAllowUseArcsInPolygons = false )

Extract the board outlines and build a closed polygon from lines, arcs and circle items on edge cut layer.

Any closed outline inside the main outline is a hole. All contours should be closed, i.e. are valid vertices for a closed polygon.

Parameters
aBoardis the board to build outlines.
aOutlineswill contain the outlines ( complex polygons ).
aErrorMaxis the max error distance when polygonizing a curve (internal units).
aChainingEpsilonis the max distance from one endPt to the next startPt (internal units)
aInferOutlineIfNecessaryif the edges do not define a closed shape then we'll approximate the bounding box outline based on the edges, or failing that, any other items on the board
aErrorHandler= an optional error handler.
aAllowUseArcsInPolygonsis an option to allow adding arcs in SHAPE_LINE_CHAIN polylines/polygons when building outlines from aShapeList This is mainly for export to STEP files.
Returns
true if success, false if a contour is not valid.

Definition at line 1386 of file convert_shape_list_to_polygon.cpp.

References SHAPE_POLY_SET::AddHole(), SHAPE_POLY_SET::Append(), SHAPE_POLY_SET::BooleanSubtract(), PCB_TYPE_COLLECTOR::Collect(), BOARD::ComputeBoundingBox(), SHAPE_LINE_CHAIN::CPoint(), doConvertOutlineToPolygon(), Edge_Cuts, BOARD::Footprints(), BOARD::GetBoardEdgesBoundingBox(), COLLECTOR::GetCount(), BOX2< Vec >::GetEnd(), EDA_ITEM::GetFlags(), BOX2< Vec >::GetHeight(), PCB_SHAPE::GetLayer(), BOX2< Vec >::GetOrigin(), BOX2< Vec >::GetWidth(), BOX2< Vec >::Inflate(), isCopperOutside(), SHAPE_POLY_SET::NewOutline(), SHAPE_POLY_SET::Outline(), SHAPE_POLY_SET::OutlineCount(), PCB_SHAPE_T, pcbIUScale, SHAPE_LINE_CHAIN::PointInside(), SHAPE_POLY_SET::RemoveAllContours(), SHAPE_POLY_SET::Simplify(), SKIP_STRUCT, VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by BOARD::GetBoardPolygonOutlines(), DIALOG_EXPORT_STEP::onExportButton(), and DRC_TEST_PROVIDER_MISC::testOutline().

◆ buildChainedClosedContour()

◆ buildContourHierarchy()

static std::map< int, std::vector< int > > buildContourHierarchy ( const std::vector< SHAPE_LINE_CHAIN > & aContours)
static

◆ BuildFootprintPolygonOutlines()

bool BuildFootprintPolygonOutlines ( BOARD * aBoard,
SHAPE_POLY_SET & aOutlines,
int aErrorMax,
int aChainingEpsilon,
OUTLINE_ERROR_HANDLER * aErrorHandler = nullptr )

Extract a board outline for a footprint view.

  • Incomplete outlines will be closed by joining the end of the outline onto the bounding box (by simply projecting the end points) and then take the area that contains the copper.
  • If all copper lies inside a closed outline, than that outline will be treated as an external board outline.
  • If copper is located outside a closed outline, then that outline will be treated as a hole, and the outer edge will be formed using the bounding box.

Definition at line 1639 of file convert_shape_list_to_polygon.cpp.

References SHAPE_POLY_SET::AddHole(), SHAPE_LINE_CHAIN::Append(), SHAPE_POLY_SET::Append(), buildBoardBoundingBoxPoly(), chain, PCB_TYPE_COLLECTOR::Collect(), SEG::Contains(), doConvertOutlineToPolygon(), Edge_Cuts, findEndSegments(), COLLECTOR::GetCount(), BOARD::GetFirstFootprint(), SHAPE_LINE_CHAIN::GetPoint(), SHAPE_POLY_SET::Hole(), SHAPE_POLY_SET::HoleCount(), SEG::IntersectLines(), SHAPE_LINE_CHAIN::IsClosed(), isCopperOutside(), SHAPE_POLY_SET::NewOutline(), SHAPE_POLY_SET::Outline(), SHAPE_POLY_SET::OutlineCount(), PCB_SHAPE_T, SHAPE_LINE_CHAIN::Segment(), SHAPE_LINE_CHAIN::SetClosed(), SKIP_STRUCT, and traceBoardOutline.

Referenced by BOARD_ADAPTER::createBoardPolygon().

◆ checkSelfIntersections()

◆ close_enough()

static bool close_enough ( VECTOR2I aLeft,
VECTOR2I aRight,
unsigned aLimit )
static

Local and tunable method of qualifying the proximity of two points.

Parameters
aLeftis the first point.
aRightis the second point.
aLimitis a measure of proximity that the caller knows about.
Returns
true if the two points are close enough, else false.

Definition at line 82 of file convert_shape_list_to_polygon.cpp.

References SEG::Square().

Referenced by buildChainedClosedContour(), doConvertOutlineToPolygon(), and processShapeSegment().

◆ closer_to_first()

static bool closer_to_first ( VECTOR2I aRef,
VECTOR2I aFirst,
VECTOR2I aSecond )
static

Local method which qualifies whether the start or end point of a segment is closest to a point.

Parameters
aRefis the reference point
aFirstis the first point
aSecondis the second point
Returns
true if the first point is closest to the reference, otherwise false.

Definition at line 96 of file convert_shape_list_to_polygon.cpp.

Referenced by buildChainedClosedContour(), ConnectBoardShapes(), doConvertOutlineToPolygon(), and processShapeSegment().

◆ closerEndpoint()

static bool closerEndpoint ( const nanoflann::ResultItem< uint32_t, double > & aLeft,
const nanoflann::ResultItem< uint32_t, double > & aRight )
static

Definition at line 658 of file convert_shape_list_to_polygon.cpp.

Referenced by findNeighbours().

◆ ConvertOutlineToPolygon()

bool ConvertOutlineToPolygon ( std::vector< PCB_SHAPE * > & aShapeList,
SHAPE_POLY_SET & aPolygons,
int aErrorMax,
int aChainingEpsilon,
bool aAllowDisjoint,
OUTLINE_ERROR_HANDLER * aErrorHandler,
bool aAllowUseArcsInPolygons = false )

Build a polygon set with holes from a PCB_SHAPE list.

The shape list is expected to be one or more top-level closed outlines with zero or more holes in each. Optionally, it can be limited to a single top-level closed outline.

Parameters
aShapeListthe initial list of drawsegments (only lines, circles and arcs).
aPolygonswill contain the complex polygon.
aErrorMaxis the max error distance when polygonizing a curve (internal units).
aChainingEpsilonis the max distance from one endPt to the next startPt (internal units).
aAllowDisjointindicates multiple top-level outlines are allowed.
aErrorHandleris an optional error handler.
aAllowUseArcsInPolygonsis an option to allow adding arcs in SHAPE_LINE_CHAIN polylines/polygons when building outlines from aShapeList This is mainly for export to STEP files.
Returns
true if success, false if a contour is not valid (self intersecting).

Definition at line 1142 of file convert_shape_list_to_polygon.cpp.

References doConvertOutlineToPolygon(), and SKIP_STRUCT.

Referenced by FOOTPRINT::BuildCourtyardCaches(), and buildFilledPolygonFromShapes().

◆ doConvertOutlineToPolygon()

bool doConvertOutlineToPolygon ( std::vector< PCB_SHAPE * > & aShapeList,
SHAPE_POLY_SET & aPolygons,
int aErrorMax,
int aChainingEpsilon,
bool aAllowDisjoint,
OUTLINE_ERROR_HANDLER * aErrorHandler,
bool aAllowUseArcsInPolygons,
SCOPED_FLAGS_CLEANER & aCleaner )

◆ findCrossingContours()

static std::set< int > findCrossingContours ( const std::vector< SHAPE_LINE_CHAIN > & aContours)
static

Definition at line 709 of file convert_shape_list_to_polygon.cpp.

Referenced by doConvertOutlineToPolygon().

◆ findEndSegments()

◆ findNeighbours()

template<typename CONSUMED_FUNC>
static CHAIN_NEIGHBOURS findNeighbours ( PCB_SHAPE * aShape,
const VECTOR2I & aPoint,
const KDTree & aKdTree,
const PCB_SHAPE_ENDPOINTS_ADAPTOR & aAdaptor,
double aChainingEpsilon,
CONSUMED_FUNC aIsConsumed )
static

Find the shapes that could continue a chain at aPoint.

Exlcuding the existing chain elements

Parameters
aIsConsumedwhether a shape is already chained.

Definition at line 675 of file convert_shape_list_to_polygon.cpp.

References closerEndpoint(), PCB_SHAPE_ENDPOINTS_ADAPTOR::endpoints, result, VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by buildChainedClosedContour(), and doConvertOutlineToPolygon().

◆ free_end()

static VECTOR2I free_end ( const PCB_SHAPE * aFirst,
const PCB_SHAPE * aSecond )
static

Return the end of aFirst that does not join aSecond.

Definition at line 105 of file convert_shape_list_to_polygon.cpp.

References EDA_SHAPE::GetEnd(), and EDA_SHAPE::GetStart().

Referenced by buildChainedClosedContour(), and doConvertOutlineToPolygon().

◆ isCopperOutside()

◆ processClosedShape()

◆ processShapeSegment()

◆ projectPointOnSegment()

VECTOR2I projectPointOnSegment ( const VECTOR2I & aEndPoint,
const SHAPE_POLY_SET & aOutline,
int aOutlineNum = 0 )

◆ TestBoardOutlinesGraphicItems()

bool TestBoardOutlinesGraphicItems ( BOARD * aBoard,
int aMinDist,
OUTLINE_ERROR_HANDLER * aErrorHandler )