Support for filled DRAWSEGMENT::S_RECT and S_CIRCLE.

One more step in unifying pad primitives and draw segments.
This commit is contained in:
Jeff Young 2020-06-19 21:46:43 +01:00
parent 986c1a27cd
commit 970921f88b
5 changed files with 91 additions and 50 deletions

View File

@ -777,32 +777,49 @@ void BOARD_ADAPTER::AddShapeWithClearanceToContainer( const DRAWSEGMENT* aDrawSe
if( inner_radius < 0 ) if( inner_radius < 0 )
inner_radius = 0; inner_radius = 0;
aDstContainer->Add( new CRING2D( center3DU, inner_radius, outer_radius, *aDrawSegment ) ); if( aDrawSegment->GetWidth() > 0 )
aDstContainer->Add( new CRING2D( center3DU, inner_radius, outer_radius, *aDrawSegment ) );
else
aDstContainer->Add( new CFILLEDCIRCLE2D( center3DU, outer_radius, *aDrawSegment ) );
} }
break; break;
case S_RECT: case S_RECT:
{ {
std::vector<wxPoint> pts; if( aDrawSegment->GetWidth() > 0 )
aDrawSegment->GetRectCorners( &pts ); {
std::vector<wxPoint> pts;
aDrawSegment->GetRectCorners( &pts );
const SFVEC2F topLeft3DU( pts[0].x * m_biuTo3Dunits, -pts[0].y * m_biuTo3Dunits ); const SFVEC2F topLeft3DU( pts[0].x * m_biuTo3Dunits, -pts[0].y * m_biuTo3Dunits );
const SFVEC2F topRight3DU( pts[1].x * m_biuTo3Dunits, -pts[1].y * m_biuTo3Dunits ); const SFVEC2F topRight3DU( pts[1].x * m_biuTo3Dunits, -pts[1].y * m_biuTo3Dunits );
const SFVEC2F botRight3DU( pts[2].x * m_biuTo3Dunits, -pts[2].y * m_biuTo3Dunits ); const SFVEC2F botRight3DU( pts[2].x * m_biuTo3Dunits, -pts[2].y * m_biuTo3Dunits );
const SFVEC2F botLeft3DU( pts[3].x * m_biuTo3Dunits, -pts[3].y * m_biuTo3Dunits ); const SFVEC2F botLeft3DU( pts[3].x * m_biuTo3Dunits, -pts[3].y * m_biuTo3Dunits );
aDstContainer->Add( new CROUNDSEGMENT2D( topLeft3DU, topRight3DU, aDstContainer->Add( new CROUNDSEGMENT2D( topLeft3DU, topRight3DU,
linewidth * m_biuTo3Dunits, linewidth * m_biuTo3Dunits,
*aDrawSegment ) ); *aDrawSegment ) );
aDstContainer->Add( new CROUNDSEGMENT2D( topRight3DU, botRight3DU, aDstContainer->Add( new CROUNDSEGMENT2D( topRight3DU, botRight3DU,
linewidth * m_biuTo3Dunits, linewidth * m_biuTo3Dunits,
*aDrawSegment ) ); *aDrawSegment ) );
aDstContainer->Add( new CROUNDSEGMENT2D( botRight3DU, botLeft3DU, aDstContainer->Add( new CROUNDSEGMENT2D( botRight3DU, botLeft3DU,
linewidth * m_biuTo3Dunits, linewidth * m_biuTo3Dunits,
*aDrawSegment ) ); *aDrawSegment ) );
aDstContainer->Add( new CROUNDSEGMENT2D( botLeft3DU, topLeft3DU, aDstContainer->Add( new CROUNDSEGMENT2D( botLeft3DU, topLeft3DU,
linewidth * m_biuTo3Dunits, linewidth * m_biuTo3Dunits,
*aDrawSegment ) ); *aDrawSegment ) );
}
else
{
SHAPE_POLY_SET polyList;
aDrawSegment->TransformShapeWithClearanceToPolygon( polyList, aClearanceValue );
polyList.Simplify( SHAPE_POLY_SET::PM_FAST );
Convert_shape_line_polygon_to_triangles( polyList, *aDstContainer, m_biuTo3Dunits,
*aDrawSegment );
}
} }
break; break;

View File

@ -329,6 +329,7 @@ bool DIALOG_GRAPHIC_ITEM_PROPERTIES::Validate()
// Check angle of arc. // Check angle of arc.
if( m_angle.GetValue() == 0 ) if( m_angle.GetValue() == 0 )
error_msgs.Add( _( "The arc angle cannot be zero." ) ); error_msgs.Add( _( "The arc angle cannot be zero." ) );
KI_FALLTHROUGH; KI_FALLTHROUGH;
case S_CIRCLE: case S_CIRCLE:
@ -337,32 +338,23 @@ bool DIALOG_GRAPHIC_ITEM_PROPERTIES::Validate()
error_msgs.Add( _( "The radius must be greater than zero." ) ); error_msgs.Add( _( "The radius must be greater than zero." ) );
break; break;
case S_RECT:
// Check for null rect.
if( m_startX.GetValue() == m_endX.GetValue() && m_startY.GetValue() == m_endY.GetValue() )
error_msgs.Add( _( "The rectangle can not be empty." ) );
break;
case S_POLYGON: case S_POLYGON:
case S_SEGMENT:
case S_CURVE:
break; break;
default: default:
// Check start and end are not the same. wxASSERT_MSG( false, "DIALOG_GRAPHIC_ITEM_PROPERTIES::Validate not implemented for shape"
if( m_startX.GetValue() == m_endX.GetValue() && m_startY.GetValue() == m_endY.GetValue() ) + DRAWSEGMENT::ShowShape( m_item->GetShape() ) );
error_msgs.Add( _( "The start and end points cannot be the same." ) );
break; break;
} }
// Check the item thickness. Note the polygon outline thickness is allowed
// to be set to 0, because if the shape is exactly the polygon, its outline
// thickness must be 0
int thickness = m_thickness.GetValue();
if( m_item->GetShape() == S_POLYGON )
{
if( thickness < 0 )
error_msgs.Add( _( "The polygon outline thickness must be >= 0." ) );
}
else
{
if( thickness <= 0 )
error_msgs.Add( _( "The item thickness must be greater than zero." ) );
}
if( error_msgs.GetCount() ) if( error_msgs.GetCount() )
{ {
HTML_MESSAGE_BOX dlg( this, _( "Error List" ) ); HTML_MESSAGE_BOX dlg( this, _( "Error List" ) );

View File

@ -161,6 +161,7 @@ void D_PAD::AddPrimitivePoly( const SHAPE_POLY_SET& aPoly, int aThickness, bool
AddPrimitivePoly( points, aThickness, aMergePrimitives ); AddPrimitivePoly( points, aThickness, aMergePrimitives );
} }
void D_PAD::AddPrimitivePoly( const std::vector<wxPoint>& aPoly, int aThickness, void D_PAD::AddPrimitivePoly( const std::vector<wxPoint>& aPoly, int aThickness,
bool aMergePrimitives ) bool aMergePrimitives )
{ {
@ -260,6 +261,7 @@ bool D_PAD::SetPrimitives( const std::vector<PAD_CS_PRIMITIVE>& aPrimitivesList
return MergePrimitivesAsPolygon(); return MergePrimitivesAsPolygon();
} }
bool D_PAD::AddPrimitives( const std::vector<PAD_CS_PRIMITIVE>& aPrimitivesList ) bool D_PAD::AddPrimitives( const std::vector<PAD_CS_PRIMITIVE>& aPrimitivesList )
{ {
for( const auto& prim : aPrimitivesList ) for( const auto& prim : aPrimitivesList )

View File

@ -919,10 +919,23 @@ void PCB_PAINTER::draw( const DRAWSEGMENT* aSegment, int aLayer )
std::vector<wxPoint> pts; std::vector<wxPoint> pts;
aSegment->GetRectCorners( &pts ); aSegment->GetRectCorners( &pts );
m_gal->DrawSegment( pts[0], pts[1], thickness ); if( aSegment->GetWidth() > 0 )
m_gal->DrawSegment( pts[1], pts[2], thickness ); {
m_gal->DrawSegment( pts[2], pts[3], thickness ); m_gal->DrawSegment( pts[0], pts[1], thickness );
m_gal->DrawSegment( pts[3], pts[0], thickness ); m_gal->DrawSegment( pts[1], pts[2], thickness );
m_gal->DrawSegment( pts[2], pts[3], thickness );
m_gal->DrawSegment( pts[3], pts[0], thickness );
}
else
{
SHAPE_POLY_SET poly;
poly.NewOutline();
for( const wxPoint& pt : pts )
poly.Append( pt );
m_gal->DrawPolygon( poly );
}
} }
break; break;
@ -942,15 +955,15 @@ void PCB_PAINTER::draw( const DRAWSEGMENT* aSegment, int aLayer )
else else
{ {
m_gal->SetLineWidth( thickness ); m_gal->SetLineWidth( thickness );
m_gal->SetIsFill( false ); m_gal->SetIsFill( aSegment->GetWidth() == 0 );
m_gal->SetIsStroke( true ); m_gal->SetIsStroke( aSegment->GetWidth() > 0 );
m_gal->DrawCircle( start, aSegment->GetRadius() ); m_gal->DrawCircle( start, aSegment->GetRadius() );
} }
break; break;
case S_POLYGON: case S_POLYGON:
{ {
SHAPE_POLY_SET& shape = ((DRAWSEGMENT*)aSegment)->GetPolyShape(); SHAPE_POLY_SET& shape = const_cast<DRAWSEGMENT*>( aSegment )->GetPolyShape();
if( shape.OutlineCount() == 0 ) if( shape.OutlineCount() == 0 )
break; break;

View File

@ -533,16 +533,33 @@ void BRDITEMS_PLOTTER::PlotFootprintGraphicItem( EDGE_MODULE* aEdge )
std::vector<wxPoint> pts; std::vector<wxPoint> pts;
aEdge->GetRectCorners( &pts ); aEdge->GetRectCorners( &pts );
m_plotter->ThickSegment( pts[0], pts[1], thickness, GetPlotMode(), &gbr_metadata ); if( aEdge->GetWidth() > 0 )
m_plotter->ThickSegment( pts[1], pts[2], thickness, GetPlotMode(), &gbr_metadata ); {
m_plotter->ThickSegment( pts[2], pts[3], thickness, GetPlotMode(), &gbr_metadata ); m_plotter->ThickSegment( pts[0], pts[1], thickness, GetPlotMode(), &gbr_metadata );
m_plotter->ThickSegment( pts[3], pts[0], thickness, GetPlotMode(), &gbr_metadata ); m_plotter->ThickSegment( pts[1], pts[2], thickness, GetPlotMode(), &gbr_metadata );
m_plotter->ThickSegment( pts[2], pts[3], thickness, GetPlotMode(), &gbr_metadata );
m_plotter->ThickSegment( pts[3], pts[0], thickness, GetPlotMode(), &gbr_metadata );
}
else
{
SHAPE_LINE_CHAIN poly;
for( const wxPoint& pt : pts )
poly.Append( pt );
m_plotter->PlotPoly( poly, FILLED_SHAPE, -1, &gbr_metadata );
}
} }
break; break;
case S_CIRCLE: case S_CIRCLE:
radius = KiROUND( GetLineLength( end, pos ) ); radius = KiROUND( GetLineLength( end, pos ) );
m_plotter->ThickCircle( pos, radius * 2, thickness, GetPlotMode(), &gbr_metadata );
if( aEdge->GetWidth() > 0 )
m_plotter->ThickCircle( pos, radius * 2, thickness, GetPlotMode(), &gbr_metadata );
else
m_plotter->Circle( pos, radius * 2, FILLED_SHAPE, -1 );
break; break;
case S_ARC: case S_ARC: