pcbnew: Allow closed polygons as board edges

Like circles, polygons are self-closed elements that define an outline.
This allows them to be used as such for board outlines and cutouts.

Fixes: lp:1795563
* https://bugs.launchpad.net/kicad/+bug/1795563
This commit is contained in:
Seth Hillbrand 2018-12-01 21:41:17 -07:00
parent 58036382c1
commit 1858b7dca7
4 changed files with 69 additions and 9 deletions

View File

@ -578,6 +578,21 @@ void DRAWSEGMENT::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerB
poly[ii] += offset;
}
// On the edge cuts layer, a polygon should be treated as a closed set of lines
if( m_Layer == Edge_Cuts )
{
auto start = poly[0];
for( size_t ii = 1; ii < poly.size(); ii++ )
{
TransformOvalClearanceToPolygon( aCornerBuffer, poly[ii - 1], poly[ii],
linewidth, aCircleToSegmentsCount, aCorrectionFactor );
}
TransformOvalClearanceToPolygon( aCornerBuffer, poly[poly.size() - 1], start,
linewidth, aCircleToSegmentsCount, aCorrectionFactor );
break;
}
// Generate polygons for the outline + clearance
// This code is compatible with a polygon with holes linked to external outline
// by overlapping segments.

View File

@ -282,6 +282,21 @@ bool ConvertOutlineToPolygon( std::vector<DRAWSEGMENT*>& aSegList, SHAPE_POLY_SE
}
break;
case S_POLYGON:
{
const auto poly = graphic->GetPolyShape();
for( auto iter = poly.CIterate(); iter; iter++ )
{
if( iter->x < xmin.x )
{
xmin.x = iter->x;
xmin.y = iter->y;
xmini = i;
}
}
}
break;
default:
break;
}
@ -302,6 +317,10 @@ bool ConvertOutlineToPolygon( std::vector<DRAWSEGMENT*>& aSegList, SHAPE_POLY_SE
int steps = GetArcToSegmentCount( graphic->GetRadius(), ARC_LOW_DEF, 360.0 );
TransformCircleToPolygon( aPolygons, graphic->GetCenter(), graphic->GetRadius(), steps );
}
else if( graphic->GetShape() == S_POLYGON )
{
aPolygons = graphic->GetPolyShape();
}
else
{
// Polygon start point. Arbitrarily chosen end of the
@ -465,7 +484,16 @@ bool ConvertOutlineToPolygon( std::vector<DRAWSEGMENT*>& aSegList, SHAPE_POLY_SE
graphic = (DRAWSEGMENT*) segList[0];
segList.erase( segList.begin() );
if( graphic->GetShape() == S_CIRCLE )
// Both circles and polygons on the edge cuts layer are closed items that
// do not connect to other elements, so we process them independently
if( graphic->GetShape() == S_POLYGON )
{
for( auto it = graphic->GetPolyShape().CIterate(); it; it++ )
{
aPolygons.Append( *it, -1, hole );
}
}
else if( graphic->GetShape() == S_CIRCLE )
{
// make a circle by segments;
wxPoint center = graphic->GetCenter();

View File

@ -995,7 +995,12 @@ void PCB_PAINTER::draw( const DRAWSEGMENT* aSegment, int aLayer )
}
m_gal->SetLineWidth( thickness );
m_gal->SetIsFill( true );
if( aLayer != Edge_Cuts )
m_gal->SetIsFill( true );
else
m_gal->SetIsFill( false );
m_gal->SetIsStroke( true );
m_gal->DrawPolygon( shape );

View File

@ -762,14 +762,26 @@ void BRDITEMS_PLOTTER::PlotDrawSegment( DRAWSEGMENT* aSeg )
case S_POLYGON:
{
m_plotter->SetCurrentLineWidth( thickness, &gbr_metadata );
// Draw the polygon: only one polygon is expected
// However we provide a multi polygon shape drawing
// ( for the future or to show a non expected shape )
for( int jj = 0; jj < aSeg->GetPolyShape().OutlineCount(); ++jj )
if( m_layerMask[ Edge_Cuts ] )
{
SHAPE_LINE_CHAIN& poly = aSeg->GetPolyShape().Outline( jj );
m_plotter->PlotPoly( poly, FILLED_SHAPE, thickness, &gbr_metadata );
for( auto it = aSeg->GetPolyShape().IterateSegments( 0 ); it; it++ )
{
auto seg = it.Get();
m_plotter->ThickSegment( wxPoint( seg.A ), wxPoint( seg.B ),
thickness, GetPlotMode(), &gbr_metadata );
}
}
else
{
m_plotter->SetCurrentLineWidth( thickness, &gbr_metadata );
// Draw the polygon: only one polygon is expected
// However we provide a multi polygon shape drawing
// ( for the future or to show a non expected shape )
for( int jj = 0; jj < aSeg->GetPolyShape().OutlineCount(); ++jj )
{
SHAPE_LINE_CHAIN& poly = aSeg->GetPolyShape().Outline( jj );
m_plotter->PlotPoly( poly, FILLED_SHAPE, thickness, &gbr_metadata );
}
}
}
break;