STEP export: Stricter contiguity check
Stricter contiguity check points the user to gaps in the outline. Fixes: lp:1774351 * https://bugs.launchpad.net/kicad/+bug/1774351
This commit is contained in:
parent
1541cbdf04
commit
f0b3cf8077
|
@ -2897,15 +2897,13 @@ BOARD_ITEM* BOARD::Duplicate( const BOARD_ITEM* aItem,
|
|||
* All contours should be closed, i.e. are valid vertices for a closed polygon
|
||||
* return true if success, false if a contour is not valid
|
||||
*/
|
||||
extern bool BuildBoardPolygonOutlines( BOARD* aBoard,
|
||||
SHAPE_POLY_SET& aOutlines,
|
||||
wxString* aErrorText );
|
||||
extern bool BuildBoardPolygonOutlines( BOARD* aBoard, SHAPE_POLY_SET& aOutlines,
|
||||
wxString* aErrorText, unsigned int aTolerance );
|
||||
|
||||
|
||||
bool BOARD::GetBoardPolygonOutlines( SHAPE_POLY_SET& aOutlines,
|
||||
wxString* aErrorText )
|
||||
bool BOARD::GetBoardPolygonOutlines( SHAPE_POLY_SET& aOutlines, wxString* aErrorText )
|
||||
{
|
||||
bool success = BuildBoardPolygonOutlines( this, aOutlines, aErrorText );
|
||||
bool success = BuildBoardPolygonOutlines( this, aOutlines, aErrorText, Millimeter2iu( 0.05 ) );
|
||||
|
||||
// Make polygon strictly simple to avoid issues (especially in 3D viewer)
|
||||
aOutlines.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||
|
|
|
@ -1436,8 +1436,8 @@ double MODULE::CoverageRatio( const GENERAL_COLLECTOR& aCollector ) const
|
|||
|
||||
|
||||
// see convert_drawsegment_list_to_polygon.cpp:
|
||||
extern bool ConvertOutlineToPolygon( std::vector< DRAWSEGMENT* >& aSegList,
|
||||
SHAPE_POLY_SET& aPolygons, wxString* aErrorText);
|
||||
extern bool ConvertOutlineToPolygon( std::vector<DRAWSEGMENT*>& aSegList, SHAPE_POLY_SET& aPolygons,
|
||||
wxString* aErrorText, unsigned int aTolerance );
|
||||
|
||||
bool MODULE::BuildPolyCourtyard()
|
||||
{
|
||||
|
@ -1466,10 +1466,14 @@ bool MODULE::BuildPolyCourtyard()
|
|||
|
||||
wxString error_msg;
|
||||
|
||||
bool success = ConvertOutlineToPolygon( list_front, m_poly_courtyard_front, &error_msg );
|
||||
bool success = ConvertOutlineToPolygon( list_front, m_poly_courtyard_front,
|
||||
&error_msg, Millimeter2iu( 0.05 ) );
|
||||
|
||||
if( success )
|
||||
success = ConvertOutlineToPolygon( list_back, m_poly_courtyard_back, &error_msg );
|
||||
{
|
||||
success = ConvertOutlineToPolygon( list_back, m_poly_courtyard_back,
|
||||
&error_msg, Millimeter2iu( 0.05 ) );
|
||||
}
|
||||
|
||||
if( !error_msg.IsEmpty() )
|
||||
{
|
||||
|
|
|
@ -175,12 +175,12 @@ static DRAWSEGMENT* findPoint( const wxPoint& aPoint, std::vector< DRAWSEGMENT*
|
|||
* These closed inner outlines are considered as holes in the main outline
|
||||
* @param aSegList the initial list of drawsegments (only lines, circles and arcs).
|
||||
* @param aPolygons will contain the complex polygon.
|
||||
* @param aTolerance is the max distance between points that is still accepted as connected (internal units)
|
||||
* @param aErrorText is a wxString to return error message.
|
||||
*/
|
||||
bool ConvertOutlineToPolygon( std::vector< DRAWSEGMENT* >& aSegList,
|
||||
SHAPE_POLY_SET& aPolygons, wxString* aErrorText )
|
||||
bool ConvertOutlineToPolygon( std::vector<DRAWSEGMENT*>& aSegList, SHAPE_POLY_SET& aPolygons,
|
||||
wxString* aErrorText, unsigned int aTolerance )
|
||||
{
|
||||
|
||||
if( aSegList.size() == 0 )
|
||||
return true;
|
||||
|
||||
|
@ -189,7 +189,6 @@ bool ConvertOutlineToPolygon( std::vector< DRAWSEGMENT* >& aSegList,
|
|||
// Make a working copy of aSegList, because the list is modified during calculations
|
||||
std::vector< DRAWSEGMENT* > segList = aSegList;
|
||||
|
||||
unsigned prox; // a proximity BIU metric, not an accurate distance
|
||||
DRAWSEGMENT* graphic;
|
||||
wxPoint prevPt;
|
||||
|
||||
|
@ -279,11 +278,6 @@ bool ConvertOutlineToPolygon( std::vector< DRAWSEGMENT* >& aSegList,
|
|||
// The first DRAWSEGMENT is in 'graphic', ok to remove it from 'items'
|
||||
segList.erase( segList.begin() + xmini );
|
||||
|
||||
// Set maximum proximity threshold for point to point nearness metric for
|
||||
// board perimeter only, not interior keepouts yet.
|
||||
prox = Millimeter2iu( 0.01 ); // should be enough to fix rounding issues
|
||||
// is arc start and end point calculations
|
||||
|
||||
// Output the Edge.Cuts perimeter as circle or polygon.
|
||||
if( graphic->GetShape() == S_CIRCLE )
|
||||
{
|
||||
|
@ -337,9 +331,9 @@ bool ConvertOutlineToPolygon( std::vector< DRAWSEGMENT* >& aSegList,
|
|||
double radius = graphic->GetRadius();
|
||||
int steps = GetArcToSegmentCount( radius, ARC_LOW_DEF, angle / 10.0 );
|
||||
|
||||
if( !close_enough( prevPt, pstart, prox ) )
|
||||
if( !close_enough( prevPt, pstart, aTolerance ) )
|
||||
{
|
||||
wxASSERT( close_enough( prevPt, graphic->GetArcEnd(), prox ) );
|
||||
wxASSERT( close_enough( prevPt, graphic->GetArcEnd(), aTolerance ) );
|
||||
|
||||
angle = -angle;
|
||||
std::swap( pstart, pend );
|
||||
|
@ -374,14 +368,14 @@ bool ConvertOutlineToPolygon( std::vector< DRAWSEGMENT* >& aSegList,
|
|||
|
||||
// Get next closest segment.
|
||||
|
||||
graphic = findPoint( prevPt, segList, prox );
|
||||
graphic = findPoint( prevPt, segList, aTolerance );
|
||||
|
||||
// If there are no more close segments, check if the board
|
||||
// outline polygon can be closed.
|
||||
|
||||
if( !graphic )
|
||||
{
|
||||
if( close_enough( startPt, prevPt, prox ) )
|
||||
if( close_enough( startPt, prevPt, aTolerance ) )
|
||||
{
|
||||
// Close the polygon back to start point
|
||||
// aPolygons.Append( startPt ); // not needed
|
||||
|
@ -407,11 +401,6 @@ bool ConvertOutlineToPolygon( std::vector< DRAWSEGMENT* >& aSegList,
|
|||
}
|
||||
}
|
||||
|
||||
// Output the interior Edge.Cuts graphics as keepouts, using same nearness
|
||||
// metric as the board edge as otherwise we have trouble completing complex
|
||||
// polygons.
|
||||
prox = Millimeter2iu( 0.05 );
|
||||
|
||||
while( segList.size() )
|
||||
{
|
||||
// emit a signal layers keepout for every interior polygon left...
|
||||
|
@ -488,9 +477,9 @@ bool ConvertOutlineToPolygon( std::vector< DRAWSEGMENT* >& aSegList,
|
|||
int radius = graphic->GetRadius();
|
||||
int steps = GetArcToSegmentCount( radius, ARC_LOW_DEF, angle / 10.0 );
|
||||
|
||||
if( !close_enough( prevPt, pstart, prox ) )
|
||||
if( !close_enough( prevPt, pstart, aTolerance ) )
|
||||
{
|
||||
wxASSERT( close_enough( prevPt, graphic->GetArcEnd(), prox ) );
|
||||
wxASSERT( close_enough( prevPt, graphic->GetArcEnd(), aTolerance ) );
|
||||
|
||||
angle = -angle;
|
||||
std::swap( pstart, pend );
|
||||
|
@ -526,14 +515,14 @@ bool ConvertOutlineToPolygon( std::vector< DRAWSEGMENT* >& aSegList,
|
|||
|
||||
// Get next closest segment.
|
||||
|
||||
graphic = findPoint( prevPt, segList, prox );
|
||||
graphic = findPoint( prevPt, segList, aTolerance );
|
||||
|
||||
// If there are no more close segments, check if polygon
|
||||
// can be closed.
|
||||
|
||||
if( !graphic )
|
||||
{
|
||||
if( close_enough( startPt, prevPt, prox ) )
|
||||
if( close_enough( startPt, prevPt, aTolerance ) )
|
||||
{
|
||||
// Close the polygon back to start point
|
||||
// aPolygons.Append( startPt, -1, hole ); // not needed
|
||||
|
@ -570,9 +559,8 @@ bool ConvertOutlineToPolygon( std::vector< DRAWSEGMENT* >& aSegList,
|
|||
* 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,
|
||||
wxString* aErrorText )
|
||||
bool BuildBoardPolygonOutlines( BOARD* aBoard, SHAPE_POLY_SET& aOutlines,
|
||||
wxString* aErrorText, unsigned int aTolerance )
|
||||
{
|
||||
PCB_TYPE_COLLECTOR items;
|
||||
|
||||
|
@ -590,7 +578,7 @@ bool BuildBoardPolygonOutlines( BOARD* aBoard,
|
|||
segList.push_back( static_cast< DRAWSEGMENT* >( items[ii] ) );
|
||||
}
|
||||
|
||||
bool success = ConvertOutlineToPolygon( segList, aOutlines, aErrorText );
|
||||
bool success = ConvertOutlineToPolygon( segList, aOutlines, aErrorText, aTolerance );
|
||||
|
||||
if( !success || !aOutlines.OutlineCount() )
|
||||
{
|
||||
|
|
|
@ -219,6 +219,8 @@ void DIALOG_EXPORT_STEP::onUpdateYPos( wxUpdateUIEvent& aEvent )
|
|||
aEvent.Enable( m_rbUserDefinedOrigin->GetValue() );
|
||||
}
|
||||
|
||||
extern bool BuildBoardPolygonOutlines( BOARD* aBoard, SHAPE_POLY_SET& aOutlines,
|
||||
wxString* aErrorText, unsigned int aTolerance );
|
||||
|
||||
void DIALOG_EXPORT_STEP::onExportButton( wxCommandEvent& aEvent )
|
||||
{
|
||||
|
@ -226,8 +228,7 @@ void DIALOG_EXPORT_STEP::onExportButton( wxCommandEvent& aEvent )
|
|||
wxString msg;
|
||||
|
||||
// Check if the board outline is continuous
|
||||
// TODO the check below is more forgiving than kicad2step, needs to be more strict
|
||||
if( !m_parent->GetBoard()->GetBoardPolygonOutlines( outline, &msg ) )
|
||||
if( !BuildBoardPolygonOutlines( m_parent->GetBoard(), outline, &msg, Millimeter2iu( 0.01 ) ) )
|
||||
{
|
||||
DisplayErrorMessage( this, _( "Cannot determine the board outline." ), msg );
|
||||
return;
|
||||
|
|
Loading…
Reference in New Issue