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; 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 // Generate polygons for the outline + clearance
// This code is compatible with a polygon with holes linked to external outline // This code is compatible with a polygon with holes linked to external outline
// by overlapping segments. // by overlapping segments.

View File

@ -282,6 +282,21 @@ bool ConvertOutlineToPolygon( std::vector<DRAWSEGMENT*>& aSegList, SHAPE_POLY_SE
} }
break; 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: default:
break; break;
} }
@ -302,6 +317,10 @@ bool ConvertOutlineToPolygon( std::vector<DRAWSEGMENT*>& aSegList, SHAPE_POLY_SE
int steps = GetArcToSegmentCount( graphic->GetRadius(), ARC_LOW_DEF, 360.0 ); int steps = GetArcToSegmentCount( graphic->GetRadius(), ARC_LOW_DEF, 360.0 );
TransformCircleToPolygon( aPolygons, graphic->GetCenter(), graphic->GetRadius(), steps ); TransformCircleToPolygon( aPolygons, graphic->GetCenter(), graphic->GetRadius(), steps );
} }
else if( graphic->GetShape() == S_POLYGON )
{
aPolygons = graphic->GetPolyShape();
}
else else
{ {
// Polygon start point. Arbitrarily chosen end of the // 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]; graphic = (DRAWSEGMENT*) segList[0];
segList.erase( segList.begin() ); 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; // make a circle by segments;
wxPoint center = graphic->GetCenter(); 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->SetLineWidth( thickness );
if( aLayer != Edge_Cuts )
m_gal->SetIsFill( true ); m_gal->SetIsFill( true );
else
m_gal->SetIsFill( false );
m_gal->SetIsStroke( true ); m_gal->SetIsStroke( true );
m_gal->DrawPolygon( shape ); m_gal->DrawPolygon( shape );

View File

@ -761,6 +761,17 @@ void BRDITEMS_PLOTTER::PlotDrawSegment( DRAWSEGMENT* aSeg )
break; break;
case S_POLYGON: case S_POLYGON:
{
if( m_layerMask[ Edge_Cuts ] )
{
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 ); m_plotter->SetCurrentLineWidth( thickness, &gbr_metadata );
// Draw the polygon: only one polygon is expected // Draw the polygon: only one polygon is expected
@ -772,6 +783,7 @@ void BRDITEMS_PLOTTER::PlotDrawSegment( DRAWSEGMENT* aSeg )
m_plotter->PlotPoly( poly, FILLED_SHAPE, thickness, &gbr_metadata ); m_plotter->PlotPoly( poly, FILLED_SHAPE, thickness, &gbr_metadata );
} }
} }
}
break; break;
default: default: