More work courtyard overlap detection: better code.
This commit is contained in:
parent
77c1b1b4ea
commit
ecdfa404cb
|
@ -2874,13 +2874,14 @@ BOARD_ITEM* BOARD::Duplicate( const BOARD_ITEM* aItem,
|
||||||
* All contours should be closed, i.e. are valid vertices for a closed polygon
|
* 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
|
* return true if success, false if a contour is not valid
|
||||||
*/
|
*/
|
||||||
#include <specctra.h>
|
extern bool BuildBoardPolygonOutlines( BOARD* aBoard,
|
||||||
|
SHAPE_POLY_SET& aOutlines,
|
||||||
|
SHAPE_POLY_SET& aHoles,
|
||||||
|
wxString* aErrorText );
|
||||||
|
|
||||||
bool BOARD::GetBoardPolygonOutlines( SHAPE_POLY_SET& aOutlines,
|
bool BOARD::GetBoardPolygonOutlines( SHAPE_POLY_SET& aOutlines,
|
||||||
SHAPE_POLY_SET& aHoles,
|
SHAPE_POLY_SET& aHoles,
|
||||||
wxString* aErrorText )
|
wxString* aErrorText )
|
||||||
{
|
{
|
||||||
// the SPECCTRA_DB function to extract board outlines:
|
return BuildBoardPolygonOutlines( this, aOutlines, aHoles, aErrorText );
|
||||||
DSN::SPECCTRA_DB dummy;
|
|
||||||
return dummy.GetBoardPolygonOutlines( this, aOutlines,
|
|
||||||
aHoles, aErrorText );
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
/*
|
/*
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
* Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||||
* Copyright (C) 2015 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
* Copyright (C) 2015 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||||
* Copyright (C) 2015 Wayne Stambaugh <stambaughw@verizon.net>
|
* Copyright (C) 2015 Wayne Stambaugh <stambaughw@verizon.net>
|
||||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -1223,7 +1223,7 @@ double MODULE::PadCoverageRatio() const
|
||||||
|
|
||||||
// see convert_drawsegment_list_to_polygon.cpp:
|
// see convert_drawsegment_list_to_polygon.cpp:
|
||||||
extern bool ConvertOutlineToPolygon( std::vector< DRAWSEGMENT* >& aSegList,
|
extern bool ConvertOutlineToPolygon( std::vector< DRAWSEGMENT* >& aSegList,
|
||||||
SHAPE_POLY_SET& aPolygons);
|
SHAPE_POLY_SET& aPolygons, wxString* aErrorText);
|
||||||
|
|
||||||
bool MODULE::BuildPolyCourtyard()
|
bool MODULE::BuildPolyCourtyard()
|
||||||
{
|
{
|
||||||
|
@ -1250,10 +1250,18 @@ bool MODULE::BuildPolyCourtyard()
|
||||||
if( !list_front.size() && !list_back.size() )
|
if( !list_front.size() && !list_back.size() )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
bool success = ConvertOutlineToPolygon( list_front, m_poly_courtyard_front );
|
wxString error_msg;
|
||||||
|
|
||||||
|
bool success = ConvertOutlineToPolygon( list_front, m_poly_courtyard_front, &error_msg );
|
||||||
|
|
||||||
if( success )
|
if( success )
|
||||||
success = ConvertOutlineToPolygon( list_back, m_poly_courtyard_back );
|
success = ConvertOutlineToPolygon( list_back, m_poly_courtyard_back, &error_msg );
|
||||||
|
|
||||||
|
if( !error_msg.IsEmpty() )
|
||||||
|
{
|
||||||
|
error_msg.Prepend( GetReference() + ": " );
|
||||||
|
wxLogMessage( error_msg );
|
||||||
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
|
@ -175,13 +175,17 @@ static DRAWSEGMENT* findPoint( const wxPoint& aPoint, std::vector< DRAWSEGMENT*
|
||||||
* These closed inner outlines are considered as holes in the main outline
|
* 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 aSegList 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 aErrorText is a wxString to return error message.
|
||||||
*/
|
*/
|
||||||
bool ConvertOutlineToPolygon( std::vector< DRAWSEGMENT* >& aSegList, SHAPE_POLY_SET& aPolygons)
|
bool ConvertOutlineToPolygon( std::vector< DRAWSEGMENT* >& aSegList,
|
||||||
|
SHAPE_POLY_SET& aPolygons, wxString* aErrorText)
|
||||||
{
|
{
|
||||||
|
|
||||||
if( aSegList.size() == 0 )
|
if( aSegList.size() == 0 )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
wxString msg;
|
||||||
|
|
||||||
// Make a working copy of aSegList, because the list is modified during calculations
|
// Make a working copy of aSegList, because the list is modified during calculations
|
||||||
std::vector< DRAWSEGMENT* > segList = aSegList;
|
std::vector< DRAWSEGMENT* > segList = aSegList;
|
||||||
|
|
||||||
|
@ -367,13 +371,15 @@ bool ConvertOutlineToPolygon( std::vector< DRAWSEGMENT* >& aSegList, SHAPE_POLY_
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
if( aErrorText )
|
||||||
{
|
{
|
||||||
wxLogMessage( _( "Unsupported DRAWSEGMENT type %s" ),
|
msg.Printf( _( "Unsupported DRAWSEGMENT type %s" ),
|
||||||
GetChars( BOARD_ITEM::ShowShape( graphic->GetShape() ) ) );
|
GetChars( BOARD_ITEM::ShowShape( graphic->GetShape() ) ) );
|
||||||
|
|
||||||
return false;
|
*aErrorText << msg << "\n";
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get next closest segment.
|
// Get next closest segment.
|
||||||
|
@ -392,12 +398,18 @@ bool ConvertOutlineToPolygon( std::vector< DRAWSEGMENT* >& aSegList, SHAPE_POLY_
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wxLogMessage(
|
if( aErrorText )
|
||||||
|
{
|
||||||
|
msg.Printf(
|
||||||
_( "Unable to find the next boundary segment with an endpoint of (%s mm, %s mm). "
|
_( "Unable to find the next boundary segment with an endpoint of (%s mm, %s mm). "
|
||||||
"graphic outline must form a contiguous, closed polygon." ),
|
"graphic outline must form a contiguous, closed polygon." ),
|
||||||
GetChars( FROM_UTF8( BOARD_ITEM::FormatInternalUnits( prevPt.x ).c_str() ) ),
|
GetChars( FROM_UTF8( BOARD_ITEM::FormatInternalUnits( prevPt.x ).c_str() ) ),
|
||||||
GetChars( FROM_UTF8( BOARD_ITEM::FormatInternalUnits( prevPt.y ).c_str() ) )
|
GetChars( FROM_UTF8( BOARD_ITEM::FormatInternalUnits( prevPt.y ).c_str() ) )
|
||||||
);
|
);
|
||||||
|
|
||||||
|
*aErrorText << msg << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -497,7 +509,7 @@ bool ConvertOutlineToPolygon( std::vector< DRAWSEGMENT* >& aSegList, SHAPE_POLY_
|
||||||
|
|
||||||
wxPoint nextPt;
|
wxPoint nextPt;
|
||||||
|
|
||||||
for( int step = 1; step<=steps; ++step )
|
for( int step = 1; step <= steps; ++step )
|
||||||
{
|
{
|
||||||
double rotation = ( angle * step ) / steps;
|
double rotation = ( angle * step ) / steps;
|
||||||
|
|
||||||
|
@ -512,14 +524,16 @@ bool ConvertOutlineToPolygon( std::vector< DRAWSEGMENT* >& aSegList, SHAPE_POLY_
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
if( aErrorText )
|
||||||
{
|
{
|
||||||
wxLogMessage(
|
msg.Printf(
|
||||||
_( "Unsupported DRAWSEGMENT type %s" ),
|
_( "Unsupported DRAWSEGMENT type %s" ),
|
||||||
GetChars( BOARD_ITEM::ShowShape( graphic->GetShape() ) ) );
|
GetChars( BOARD_ITEM::ShowShape( graphic->GetShape() ) ) );
|
||||||
|
|
||||||
return false;
|
*aErrorText << msg << "\n";
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get next closest segment.
|
// Get next closest segment.
|
||||||
|
@ -538,13 +552,18 @@ bool ConvertOutlineToPolygon( std::vector< DRAWSEGMENT* >& aSegList, SHAPE_POLY_
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wxLogMessage(
|
if( aErrorText )
|
||||||
|
{
|
||||||
|
msg.Printf(
|
||||||
_( "Unable to find the next graphic segment with an endpoint of (%s mm, %s mm).\n"
|
_( "Unable to find the next graphic segment with an endpoint of (%s mm, %s mm).\n"
|
||||||
"Edit graphics, making them contiguous polygons each." ),
|
"Edit graphics, making them contiguous polygons each." ),
|
||||||
GetChars( FROM_UTF8( BOARD_ITEM::FormatInternalUnits( prevPt.x ).c_str() ) ),
|
GetChars( FROM_UTF8( BOARD_ITEM::FormatInternalUnits( prevPt.x ).c_str() ) ),
|
||||||
GetChars( FROM_UTF8( BOARD_ITEM::FormatInternalUnits( prevPt.y ).c_str() ) )
|
GetChars( FROM_UTF8( BOARD_ITEM::FormatInternalUnits( prevPt.y ).c_str() ) )
|
||||||
);
|
);
|
||||||
|
|
||||||
|
*aErrorText << msg << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -555,3 +574,91 @@ bool ConvertOutlineToPolygon( std::vector< DRAWSEGMENT* >& aSegList, SHAPE_POLY_
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <class_board.h>
|
||||||
|
#include <collectors.h>
|
||||||
|
|
||||||
|
/* 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,
|
||||||
|
SHAPE_POLY_SET& aHoles,
|
||||||
|
wxString* aErrorText )
|
||||||
|
{
|
||||||
|
PCB_TYPE_COLLECTOR items;
|
||||||
|
|
||||||
|
// Get all the DRAWSEGMENTS and module graphics into 'items',
|
||||||
|
// then keep only those on layer == Edge_Cuts.
|
||||||
|
static const KICAD_T scan_graphics[] = { PCB_LINE_T, PCB_MODULE_EDGE_T, EOT };
|
||||||
|
items.Collect( aBoard, scan_graphics );
|
||||||
|
|
||||||
|
// Make a working copy of aSegList, because the list is modified during calculations
|
||||||
|
std::vector< DRAWSEGMENT* > segList;
|
||||||
|
|
||||||
|
for( int ii = 0; ii < items.GetCount(); ii++ )
|
||||||
|
{
|
||||||
|
if( items[ii]->GetLayer() == Edge_Cuts )
|
||||||
|
segList.push_back( static_cast< DRAWSEGMENT* >( items[ii] ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool success = ConvertOutlineToPolygon( segList, aOutlines, aErrorText );
|
||||||
|
|
||||||
|
// Now move holes in aHoles
|
||||||
|
// only one main outline is expected
|
||||||
|
if( success && aOutlines.OutlineCount() )
|
||||||
|
{
|
||||||
|
int outlineId = 0;
|
||||||
|
|
||||||
|
int holecount = aOutlines.HoleCount( outlineId );
|
||||||
|
|
||||||
|
if( holecount )
|
||||||
|
{
|
||||||
|
for( int ii = 0; ii < holecount; ++ii )
|
||||||
|
{
|
||||||
|
aHoles.AddOutline( aOutlines.Hole( outlineId, ii ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove holes from aOutlines:
|
||||||
|
SHAPE_POLY_SET::POLYGON& polygon = aOutlines.Polygon( outlineId );
|
||||||
|
polygon.erase( polygon.begin()+1, polygon.end() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Creates a valid polygon outline is not possible.
|
||||||
|
// So uses the board edge cuts bounding box to create a
|
||||||
|
// rectangular outline
|
||||||
|
// (when no edge cuts items, fillBOUNDARY build a contour
|
||||||
|
// from global bounding box
|
||||||
|
|
||||||
|
EDA_RECT bbbox = aBoard->GetBoardEdgesBoundingBox();
|
||||||
|
|
||||||
|
// Ensure non null area. If happen, gives a minimal size.
|
||||||
|
if( ( bbbox.GetWidth() ) == 0 || ( bbbox.GetHeight() == 0 ) )
|
||||||
|
bbbox.Inflate( Millimeter2iu( 1.0 ) );
|
||||||
|
|
||||||
|
aOutlines.RemoveAllContours();
|
||||||
|
aOutlines.NewOutline();
|
||||||
|
|
||||||
|
wxPoint corner;
|
||||||
|
corner.x = bbbox.GetOrigin().x;
|
||||||
|
corner.y = bbbox.GetOrigin().y;
|
||||||
|
aOutlines.Append( corner.x, corner.y );
|
||||||
|
|
||||||
|
corner.x = bbbox.GetOrigin().x;
|
||||||
|
corner.y = bbbox.GetEnd().y;
|
||||||
|
aOutlines.Append( corner.x, corner.y );
|
||||||
|
|
||||||
|
corner.x = bbbox.GetEnd().x;
|
||||||
|
corner.y = bbbox.GetEnd().y;
|
||||||
|
aOutlines.Append( corner.x, corner.y );
|
||||||
|
|
||||||
|
corner.x = bbbox.GetEnd().x;
|
||||||
|
corner.y = bbbox.GetOrigin().y;
|
||||||
|
aOutlines.Append( corner.x, corner.y );
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue