Coding policy, Doxygen comment, and spelling fixes.

This commit is contained in:
Wayne Stambaugh 2023-10-12 12:27:30 -04:00
parent 50ec069a01
commit e3c491424b
2 changed files with 158 additions and 187 deletions

View File

@ -50,28 +50,28 @@
*/ */
const wxChar* traceBoardOutline = wxT( "KICAD_BOARD_OUTLINE" ); const wxChar* traceBoardOutline = wxT( "KICAD_BOARD_OUTLINE" );
/** /**
* Function close_enough * Local and tunable method of qualifying the proximity of two points.
* is a local and tunable method of qualifying the proximity of two points.
* *
* @param aLeft is the first point * @param aLeft is the first point.
* @param aRight is the second point * @param aRight is the second point.
* @param aLimit is a measure of proximity that the caller knows about. * @param aLimit is a measure of proximity that the caller knows about.
* @return bool - true if the two points are close enough, else false. * @return true if the two points are close enough, else false.
*/ */
static bool close_enough( VECTOR2I aLeft, VECTOR2I aRight, unsigned aLimit ) static bool close_enough( VECTOR2I aLeft, VECTOR2I aRight, unsigned aLimit )
{ {
return ( aLeft - aRight ).SquaredEuclideanNorm() <= SEG::Square( aLimit ); return ( aLeft - aRight ).SquaredEuclideanNorm() <= SEG::Square( aLimit );
} }
/** /**
* Function closer_to_first
* Local method which qualifies whether the start or end point of a segment is closest to a point. * Local method which qualifies whether the start or end point of a segment is closest to a point.
* *
* @param aRef is the reference point * @param aRef is the reference point
* @param aFirst is the first point * @param aFirst is the first point
* @param aSecond is the second point * @param aSecond is the second point
* @return bool - true if the first point is closest to the reference, otherwise false. * @return true if the first point is closest to the reference, otherwise false.
*/ */
static bool closer_to_first( VECTOR2I aRef, VECTOR2I aFirst, VECTOR2I aSecond ) static bool closer_to_first( VECTOR2I aRef, VECTOR2I aFirst, VECTOR2I aSecond )
{ {
@ -80,13 +80,13 @@ static bool closer_to_first( VECTOR2I aRef, VECTOR2I aFirst, VECTOR2I aSecond )
/** /**
* Searches for a PCB_SHAPE matching a given end point or start point in a list. * Search for a #PCB_SHAPE matching a given end point or start point in a list.
*
* @param aShape The starting shape. * @param aShape The starting shape.
* @param aPoint The starting or ending point to search for. * @param aPoint The starting or ending point to search for.
* @param aList The list to remove from. * @param aList The list to remove from.
* @param aLimit is the distance from \a aPoint that still constitutes a valid find. * @param aLimit is the distance from \a aPoint that still constitutes a valid find.
* @return PCB_SHAPE* - The first PCB_SHAPE that has a start or end point matching * @return The first #PCB_SHAPE that has a start or end point matching aPoint, otherwise nullptr.
* aPoint, otherwise NULL if none.
*/ */
static PCB_SHAPE* findNext( PCB_SHAPE* aShape, const VECTOR2I& aPoint, static PCB_SHAPE* findNext( PCB_SHAPE* aShape, const VECTOR2I& aPoint,
const std::vector<PCB_SHAPE*>& aList, unsigned aLimit ) const std::vector<PCB_SHAPE*>& aList, unsigned aLimit )
@ -162,18 +162,6 @@ static bool isCopperOutside( const FOOTPRINT* aFootprint, SHAPE_POLY_SET& aShape
} }
/* Build a polygon (with holes) from a PCB_SHAPE list, which is expected to be a closed main
* outline with perhaps closed inner outlines. These closed inner outlines are considered as
* holes in the main outline.
* @param aShapeList the initial list of SHAPEs (only lines, circles and arcs).
* @param aPolygons will contain the complex polygon.
* @param aErrorMax is the max error distance when polygonizing a curve (internal units)
* @param aChainingEpsilon is the max error distance when polygonizing a curve (internal units)
* @param aAllowDisjoint indicates multiple top-level outlines are allowed
* @param aErrorHandler = an optional error handler
* @param aAllowUseArcsInPolygons = an optional option to allow adding arcs in
* SHAPE_LINE_CHAIN polylines/polygons when building outlines from aShapeList
*/
bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aShapeList, SHAPE_POLY_SET& aPolygons, bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aShapeList, SHAPE_POLY_SET& aPolygons,
int aErrorMax, int aChainingEpsilon, bool aAllowDisjoint, int aErrorMax, int aChainingEpsilon, bool aAllowDisjoint,
OUTLINE_ERROR_HANDLER* aErrorHandler, bool aAllowUseArcsInPolygons ) OUTLINE_ERROR_HANDLER* aErrorHandler, bool aAllowUseArcsInPolygons )
@ -282,7 +270,6 @@ bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aShapeList, SHAPE_POLY_SE
{ {
// Polygon start point. Arbitrarily chosen end of the segment and build the poly // Polygon start point. Arbitrarily chosen end of the segment and build the poly
// from here. // from here.
VECTOR2I startPt = graphic->GetEnd(); VECTOR2I startPt = graphic->GetEnd();
prevPt = startPt; prevPt = startPt;
currContour.Append( prevPt ); currContour.Append( prevPt );
@ -296,11 +283,11 @@ bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aShapeList, SHAPE_POLY_SE
case SHAPE_T::CIRCLE: case SHAPE_T::CIRCLE:
{ {
// As a non-first item, closed shapes can't be anything but self-intersecting // As a non-first item, closed shapes can't be anything but self-intersecting
if( aErrorHandler ) if( aErrorHandler )
{ {
wxASSERT( prevGraphic ); wxASSERT( prevGraphic );
(*aErrorHandler)( _( "(self-intersecting)" ), prevGraphic, graphic, prevPt ); (*aErrorHandler)( _( "(self-intersecting)" ), prevGraphic, graphic,
prevPt );
} }
selfIntersecting = true; selfIntersecting = true;
@ -310,113 +297,112 @@ bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aShapeList, SHAPE_POLY_SE
} }
case SHAPE_T::SEGMENT: case SHAPE_T::SEGMENT:
{ {
VECTOR2I nextPt; VECTOR2I nextPt;
// Use the line segment end point furthest away from prevPt as we assume // Use the line segment end point furthest away from prevPt as we assume
// the other end to be ON prevPt or very close to it. // the other end to be ON prevPt or very close to it.
if( closer_to_first( prevPt, graphic->GetStart(), graphic->GetEnd()) )
nextPt = graphic->GetEnd();
else
nextPt = graphic->GetStart();
if( closer_to_first( prevPt, graphic->GetStart(), graphic->GetEnd()) ) currContour.Append( nextPt );
nextPt = graphic->GetEnd(); shapeOwners[ std::make_pair( prevPt, nextPt ) ] = graphic;
else prevPt = nextPt;
nextPt = graphic->GetStart(); }
break;
currContour.Append( nextPt );
shapeOwners[ std::make_pair( prevPt, nextPt ) ] = graphic;
prevPt = nextPt;
}
break;
case SHAPE_T::ARC: case SHAPE_T::ARC:
{
VECTOR2I pstart = graphic->GetStart();
VECTOR2I pmid = graphic->GetArcMid();
VECTOR2I pend = graphic->GetEnd();
if( !close_enough( prevPt, pstart, aChainingEpsilon ) )
{ {
VECTOR2I pstart = graphic->GetStart(); wxASSERT( close_enough( prevPt, graphic->GetEnd(), aChainingEpsilon ) );
VECTOR2I pmid = graphic->GetArcMid();
VECTOR2I pend = graphic->GetEnd();
if( !close_enough( prevPt, pstart, aChainingEpsilon ) ) std::swap( pstart, pend );
{
wxASSERT( close_enough( prevPt, graphic->GetEnd(), aChainingEpsilon ) );
std::swap( pstart, pend );
}
SHAPE_ARC sarc( pstart, pmid, pend, 0 );
SHAPE_LINE_CHAIN arcChain;
arcChain.Append( sarc, aErrorMax );
if( !aAllowUseArcsInPolygons )
arcChain.ClearArcs();
// set shapeOwners for arcChain points created by appending the sarc:
for( int ii = 1; ii < arcChain.PointCount(); ++ii )
{
shapeOwners[std::make_pair( arcChain.CPoint( ii - 1 ),
arcChain.CPoint( ii ) )] = graphic;
}
currContour.Append( arcChain );
prevPt = pend;
} }
break;
SHAPE_ARC sarc( pstart, pmid, pend, 0 );
SHAPE_LINE_CHAIN arcChain;
arcChain.Append( sarc, aErrorMax );
if( !aAllowUseArcsInPolygons )
arcChain.ClearArcs();
// set shapeOwners for arcChain points created by appending the sarc:
for( int ii = 1; ii < arcChain.PointCount(); ++ii )
{
shapeOwners[std::make_pair( arcChain.CPoint( ii - 1 ),
arcChain.CPoint( ii ) )] = graphic;
}
currContour.Append( arcChain );
prevPt = pend;
}
break;
case SHAPE_T::BEZIER: case SHAPE_T::BEZIER:
{
// We do not support Bezier curves in polygons, so approximate with a series // We do not support Bezier curves in polygons, so approximate with a series
// of short lines and put those line segments into the !same! PATH. // of short lines and put those line segments into the !same! PATH.
VECTOR2I nextPt;
bool reverse = false;
// Use the end point furthest away from prevPt as we assume the other
// end to be ON prevPt or very close to it.
if( closer_to_first( prevPt, graphic->GetStart(), graphic->GetEnd()) )
{ {
VECTOR2I nextPt; nextPt = graphic->GetEnd();
bool reverse = false;
// Use the end point furthest away from prevPt as we assume the other
// end to be ON prevPt or very close to it.
if( closer_to_first( prevPt, graphic->GetStart(), graphic->GetEnd()) )
{
nextPt = graphic->GetEnd();
}
else
{
nextPt = graphic->GetStart();
reverse = true;
}
// Ensure the approximated Bezier shape is built
// a good value is between (Bezier curve width / 2) and (Bezier curve width)
// ( and at least 0.05 mm to avoid very small segments)
int min_segm_length = std::max( pcbIUScale.mmToIU( 0.05 ), graphic->GetWidth() );
graphic->RebuildBezierToSegmentsPointsList( min_segm_length );
if( reverse )
{
for( int jj = graphic->GetBezierPoints().size()-1; jj >= 0; jj-- )
{
const VECTOR2I& pt = graphic->GetBezierPoints()[jj];
if( prevPt == pt )
continue;
currContour.Append( pt );
shapeOwners[ std::make_pair( prevPt, pt ) ] = graphic;
prevPt = pt;
}
}
else
{
for( const VECTOR2I& pt : graphic->GetBezierPoints() )
{
if( prevPt == pt )
continue;
currContour.Append( pt );
shapeOwners[ std::make_pair( prevPt, pt ) ] = graphic;
prevPt = pt;
}
}
prevPt = nextPt;
} }
break; else
{
nextPt = graphic->GetStart();
reverse = true;
}
// Ensure the approximated Bezier shape is built
// a good value is between (Bezier curve width / 2) and (Bezier curve width)
// ( and at least 0.05 mm to avoid very small segments)
int min_segm_length = std::max( pcbIUScale.mmToIU( 0.05 ),
graphic->GetWidth() );
graphic->RebuildBezierToSegmentsPointsList( min_segm_length );
if( reverse )
{
for( int jj = graphic->GetBezierPoints().size()-1; jj >= 0; jj-- )
{
const VECTOR2I& pt = graphic->GetBezierPoints()[jj];
if( prevPt == pt )
continue;
currContour.Append( pt );
shapeOwners[ std::make_pair( prevPt, pt ) ] = graphic;
prevPt = pt;
}
}
else
{
for( const VECTOR2I& pt : graphic->GetBezierPoints() )
{
if( prevPt == pt )
continue;
currContour.Append( pt );
shapeOwners[ std::make_pair( prevPt, pt ) ] = graphic;
prevPt = pt;
}
}
prevPt = nextPt;
}
break;
default: default:
UNIMPLEMENTED_FOR( graphic->SHAPE_T_asString() ); UNIMPLEMENTED_FOR( graphic->SHAPE_T_asString() );
@ -424,7 +410,6 @@ bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aShapeList, SHAPE_POLY_SE
} }
// Get next closest segment. // Get next closest segment.
PCB_SHAPE* nextGraphic = findNext( graphic, prevPt, aShapeList, aChainingEpsilon ); PCB_SHAPE* nextGraphic = findNext( graphic, prevPt, aShapeList, aChainingEpsilon );
if( nextGraphic && !( nextGraphic->GetFlags() & SKIP_STRUCT ) ) if( nextGraphic && !( nextGraphic->GetFlags() & SKIP_STRUCT ) )
@ -437,7 +422,6 @@ bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aShapeList, SHAPE_POLY_SE
} }
// Finished, or ran into trouble... // Finished, or ran into trouble...
if( close_enough( startPt, prevPt, aChainingEpsilon ) ) if( close_enough( startPt, prevPt, aChainingEpsilon ) )
{ {
currContour.SetClosed( true ); currContour.SetClosed( true );
@ -446,7 +430,8 @@ bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aShapeList, SHAPE_POLY_SE
else if( nextGraphic ) // encountered already-used segment, but not at the start else if( nextGraphic ) // encountered already-used segment, but not at the start
{ {
if( aErrorHandler ) if( aErrorHandler )
(*aErrorHandler)( _( "(self-intersecting)" ), graphic, nextGraphic, prevPt ); (*aErrorHandler)( _( "(self-intersecting)" ), graphic, nextGraphic,
prevPt );
break; break;
} }
@ -468,7 +453,6 @@ bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aShapeList, SHAPE_POLY_SE
} }
// First, collect the parents of each contour // First, collect the parents of each contour
//
std::map<int, std::vector<int>> contourToParentIndexesMap; std::map<int, std::vector<int>> contourToParentIndexesMap;
for( size_t ii = 0; ii < contours.size(); ++ii ) for( size_t ii = 0; ii < contours.size(); ++ii )
@ -491,7 +475,6 @@ bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aShapeList, SHAPE_POLY_SE
} }
// Next add those that are top-level outlines to the SHAPE_POLY_SET // Next add those that are top-level outlines to the SHAPE_POLY_SET
//
std::map<int, int> contourToOutlineIdxMap; std::map<int, int> contourToOutlineIdxMap;
for( const auto& [ contourIndex, parentIndexes ] : contourToParentIndexesMap ) for( const auto& [ contourIndex, parentIndexes ] : contourToParentIndexesMap )
@ -522,7 +505,6 @@ bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aShapeList, SHAPE_POLY_SE
} }
// And finally add the holes // And finally add the holes
//
for( const auto& [ contourIndex, parentIndexes ] : contourToParentIndexesMap ) for( const auto& [ contourIndex, parentIndexes ] : contourToParentIndexesMap )
{ {
if( parentIndexes.size() %2 == 1 ) if( parentIndexes.size() %2 == 1 )
@ -546,7 +528,6 @@ bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aShapeList, SHAPE_POLY_SE
// All of the silliness that follows is to work around the segment iterator while checking // All of the silliness that follows is to work around the segment iterator while checking
// for collisions. // for collisions.
// TODO: Implement proper segment and point iterators that follow std // TODO: Implement proper segment and point iterators that follow std
for( auto seg1 = aPolygons.IterateSegmentsWithHoles(); seg1; seg1++ ) for( auto seg1 = aPolygons.IterateSegmentsWithHoles(); seg1; seg1++ )
{ {
auto seg2 = seg1; auto seg2 = seg1;
@ -584,9 +565,6 @@ bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aShapeList, SHAPE_POLY_SE
} }
/* This function is used to test a board outlines graphic items for validity
* i.e. null or very small segments, rects and circles
*/
bool TestBoardOutlinesGraphicItems( BOARD* aBoard, int aMinDist, bool TestBoardOutlinesGraphicItems( BOARD* aBoard, int aMinDist,
OUTLINE_ERROR_HANDLER* aErrorHandler ) OUTLINE_ERROR_HANDLER* aErrorHandler )
{ {
@ -621,7 +599,7 @@ bool TestBoardOutlinesGraphicItems( BOARD* aBoard, int aMinDist,
} }
} }
// Now Test vailidty of collected items // Now Test validity of collected items
for( PCB_SHAPE* graphic : segList ) for( PCB_SHAPE* graphic : segList )
{ {
switch( graphic->GetShape() ) switch( graphic->GetShape() )
@ -637,8 +615,9 @@ bool TestBoardOutlinesGraphicItems( BOARD* aBoard, int aMinDist,
if( aErrorHandler ) if( aErrorHandler )
{ {
(*aErrorHandler)( wxString::Format( _( "(Rectangle has null or very small size: %d nm)" ), (*aErrorHandler)( wxString::Format( _( "(Rectangle has null or very small "
dim ), "size: %d nm)" ),
dim ),
graphic, nullptr, graphic->GetStart() ); graphic, nullptr, graphic->GetStart() );
} }
} }
@ -653,8 +632,9 @@ bool TestBoardOutlinesGraphicItems( BOARD* aBoard, int aMinDist,
if( aErrorHandler ) if( aErrorHandler )
{ {
(*aErrorHandler)( wxString::Format( _( "(Circle has null or very small radius: %d nm)" ), (*aErrorHandler)( wxString::Format( _( "(Circle has null or very small "
(int)graphic->GetRadius() ), "radius: %d nm)" ),
(int)graphic->GetRadius() ),
graphic, nullptr, graphic->GetStart() ); graphic, nullptr, graphic->GetStart() );
} }
} }
@ -672,7 +652,8 @@ bool TestBoardOutlinesGraphicItems( BOARD* aBoard, int aMinDist,
if( aErrorHandler ) if( aErrorHandler )
{ {
(*aErrorHandler)( wxString::Format( _( "(Segment has null or very small lenght: %d nm)" ), dim ), (*aErrorHandler)( wxString::Format( _( "(Segment has null or very small "
"length: %d nm)" ), dim ),
graphic, nullptr, graphic->GetStart() ); graphic, nullptr, graphic->GetStart() );
} }
} }
@ -698,10 +679,6 @@ bool TestBoardOutlinesGraphicItems( BOARD* aBoard, int aMinDist,
} }
/* This function is used to extract a board outlines (3D view, automatic zones build ...)
* Any closed outline inside the main outline is a hole
* All contours should be closed, i.e. valid closed polygon vertices
*/
bool BuildBoardPolygonOutlines( BOARD* aBoard, SHAPE_POLY_SET& aOutlines, int aErrorMax, bool BuildBoardPolygonOutlines( BOARD* aBoard, SHAPE_POLY_SET& aOutlines, int aErrorMax,
int aChainingEpsilon, OUTLINE_ERROR_HANDLER* aErrorHandler, int aChainingEpsilon, OUTLINE_ERROR_HANDLER* aErrorHandler,
bool aAllowUseArcsInPolygons ) bool aAllowUseArcsInPolygons )
@ -741,10 +718,11 @@ bool BuildBoardPolygonOutlines( BOARD* aBoard, SHAPE_POLY_SET& aOutlines, int aE
// gets an opportunity to use these segments // gets an opportunity to use these segments
nullptr, aAllowUseArcsInPolygons ); nullptr, aAllowUseArcsInPolygons );
// Here, we test to see if we should make holes or outlines. Holes are made if the footprint // Test to see if we should make holes or outlines. Holes are made if the footprint
// has copper outside of a single, closed outline. If there are multiple outlines, we assume // has copper outside of a single, closed outline. If there are multiple outlines,
// that the footprint edges represent holes as we do not support multiple boards. Similarly, if // we assume that the footprint edges represent holes as we do not support multiple
// any of the footprint pads are located outside of the edges, then the edges are holes // boards. Similarly, if any of the footprint pads are located outside of the edges,
// then the edges are holes
if( success && ( isCopperOutside( fp, fpOutlines ) || fpOutlines.OutlineCount() > 1 ) ) if( success && ( isCopperOutside( fp, fpOutlines ) || fpOutlines.OutlineCount() > 1 ) )
{ {
fpHoles.Append( fpOutlines ); fpHoles.Append( fpOutlines );
@ -785,7 +763,6 @@ bool BuildBoardPolygonOutlines( BOARD* aBoard, SHAPE_POLY_SET& aOutlines, int aE
// Couldn't create a valid polygon outline. Use the board edge cuts bounding box to // Couldn't create a valid polygon outline. Use the board edge cuts bounding box to
// create a rectangular outline, or, failing that, the bounding box of the items on // create a rectangular outline, or, failing that, the bounding box of the items on
// the board. // the board.
BOX2I bbbox = aBoard->GetBoardEdgesBoundingBox(); BOX2I bbbox = aBoard->GetBoardEdgesBoundingBox();
// If null area, uses the global bounding box. // If null area, uses the global bounding box.
@ -945,17 +922,6 @@ int findEndSegments( SHAPE_LINE_CHAIN& aChain, SEG& aStartSeg, SEG& aEndSeg )
} }
/**
* This function is used to extract a board outline for a footprint view.
*
* Notes:
* * 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.
*/
bool BuildFootprintPolygonOutlines( BOARD* aBoard, SHAPE_POLY_SET& aOutlines, int aErrorMax, bool BuildFootprintPolygonOutlines( BOARD* aBoard, SHAPE_POLY_SET& aOutlines, int aErrorMax,
int aChainingEpsilon, OUTLINE_ERROR_HANDLER* aErrorHandler ) int aChainingEpsilon, OUTLINE_ERROR_HANDLER* aErrorHandler )

View File

@ -33,49 +33,55 @@ const std::function<void( const wxString& msg, BOARD_ITEM* itemA, BOARD_ITEM* it
const VECTOR2I& pt )> OUTLINE_ERROR_HANDLER; const VECTOR2I& pt )> OUTLINE_ERROR_HANDLER;
/** /**
* This function is used to test a board graphic items on Edge cut layer for validity * Test a board graphic items on edge cut layer for validity.
* i.e. null segments, 0 size rects and circles *
* @param aBoard is the board to test * @param aBoard is the board to test.
* @param aMinDist is the min lenght of a segment (or radius, or diagonal size of a rect) * @param aMinDist is the min length of a segment (or radius, or diagonal size of a rect)
* to be valid * to be valid.
* @param aErrorHandler = an optional error handler * @param aErrorHandler is an optional error handler.
*/ */
bool TestBoardOutlinesGraphicItems( BOARD* aBoard, int aMinDist, bool TestBoardOutlinesGraphicItems( BOARD* aBoard, int aMinDist,
OUTLINE_ERROR_HANDLER* aErrorHandler ); OUTLINE_ERROR_HANDLER* aErrorHandler );
/** /**
* Function ConvertOutlineToPolygon * Build a polygon set with holes from a #PCB_SHAPE list.
* build a polygon set (with holes) from a PCB_SHAPE list, which is expected to be one or more *
* top-level closed outlines, with zero or more holes in each. Optionally, it can be limited to * The shape list is expected to be one or more top-level closed outlines with zero or more
* a single top-level closed outline. * holes in each. Optionally, it can be limited to a single top-level closed outline.
*
* @param aShapeList the initial list of drawsegments (only lines, circles and arcs). * @param aShapeList the initial list of drawsegments (only lines, circles and arcs).
* @param aPolygons will contain the complex polygon. * @param aPolygons will contain the complex polygon.
* @param aErrorMax is the max error distance when polygonizing a curve (internal units) * @param aErrorMax is the max error distance when polygonizing a curve (internal units).
* @param aChainingEpsilon is the max distance from one endPt to the next startPt (internal units) * @param aChainingEpsilon is the max distance from one endPt to the next startPt (internal units).
* @param aAllowDisjoint indicates multiple top-level outlines are allowed * @param aAllowDisjoint indicates multiple top-level outlines are allowed.
* @param aErrorHandler = an optional error handler * @param aErrorHandler is an optional error handler.
* @param aAllowUseArcsInPolygons = an optional option to allow adding arcs in * @param aAllowUseArcsInPolygons is an option to allow adding arcs in #SHAPE_LINE_CHAIN
* SHAPE_LINE_CHAIN polylines/polygons when building outlines from aShapeList * polylines/polygons when building outlines from aShapeList
* This is mainly for export to STEP files * This is mainly for export to STEP files.
* @return true if success, false if a contour is not valid (self intersecting) * @return true if success, false if a contour is not valid (self intersecting).
*/ */
bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aShapeList, SHAPE_POLY_SET& aPolygons, bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aShapeList, SHAPE_POLY_SET& aPolygons,
int aErrorMax, int aChainingEpsilon, bool aAllowDisjoint, int aErrorMax, int aChainingEpsilon, bool aAllowDisjoint,
OUTLINE_ERROR_HANDLER* aErrorHandler, bool aAllowUseArcsInPolygons = false ); OUTLINE_ERROR_HANDLER* aErrorHandler,
bool aAllowUseArcsInPolygons = false );
/** /**
* Extracts the board outlines and build a closed polygon from lines, arcs and circle items on * 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 * edge cut layer.
* closed, i.e. are valid vertices for a closed polygon. *
* @param aBoard is the board to build outlines * Any closed outline inside the main outline is a hole. All contours should be closed, i.e. are
* valid vertices for a closed polygon.
*
* @param aBoard is the board to build outlines.
* @param aOutlines will contain the outlines ( complex polygons ). * @param aOutlines will contain the outlines ( complex polygons ).
* @param aErrorMax is the max error distance when polygonizing a curve (internal units) * @param aErrorMax is the max error distance when polygonizing a curve (internal units).
* @param aChainingEpsilon is the max distance from one endPt to the next startPt (internal units) * @param aChainingEpsilon is the max distance from one endPt to the next startPt (internal units),
* @param aErrorHandler = an optional error handler * @param aErrorHandler = an optional error handler.
* @param aAllowUseArcsInPolygons = an optional option to allow adding arcs in * @param aAllowUseArcsInPolygons is an option to allow adding arcs in #SHAPE_LINE_CHAIN
* SHAPE_LINE_CHAIN polylines/polygons when building outlines from aShapeList * polylines/polygons when building outlines from aShapeList
* This is mainly for export to STEP files * This is mainly for export to STEP files.
* @return true if success, false if a contour is not valid * @return true if success, false if a contour is not valid.
*/ */
extern bool BuildBoardPolygonOutlines( BOARD* aBoard, SHAPE_POLY_SET& aOutlines, extern bool BuildBoardPolygonOutlines( BOARD* aBoard, SHAPE_POLY_SET& aOutlines,
int aErrorMax, int aChainingEpsilon, int aErrorMax, int aChainingEpsilon,
@ -84,9 +90,8 @@ extern bool BuildBoardPolygonOutlines( BOARD* aBoard, SHAPE_POLY_SET& aOutlines,
/** /**
* This function is used to extract a board outline for a footprint view. * Extract a board outline for a footprint view.
* *
* Notes:
* * Incomplete outlines will be closed by joining the end of the outline onto the bounding box * * 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. * (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 * * If all copper lies inside a closed outline, than that outline will be treated as an external