ADDED: Soldermask layer option for graphic shapes

Allows adding a soldermask opening for shapes on a copper layer.
Soldermask expansion can also be specified.

Fixes: https://gitlab.com/kicad/code/kicad/-/issues/2125
This commit is contained in:
Andrzej.W
2024-10-10 12:46:06 +00:00
committed by Wayne Stambaugh
parent a34c6ecd03
commit b49ebaeb16
17 changed files with 914 additions and 223 deletions
+53 -17
View File
@@ -621,7 +621,7 @@ void BRDITEMS_PLOTTER::PlotFootprintGraphicItems( const FOOTPRINT* aFootprint )
if( aFootprint->IsDNP() && hideDNPItems( itemLayer ) )
continue;
if( !m_layerMask[ itemLayer ] )
if( !( m_layerMask & item->GetLayerSet() ).any() )
continue;
switch( item->Type() )
@@ -831,12 +831,23 @@ void BRDITEMS_PLOTTER::PlotZone( const ZONE* aZone, PCB_LAYER_ID aLayer,
void BRDITEMS_PLOTTER::PlotShape( const PCB_SHAPE* aShape )
{
if( !m_layerMask[aShape->GetLayer()] )
if( !( m_layerMask & aShape->GetLayerSet() ).any() )
return;
OUTLINE_MODE plotMode = GetPlotMode();
OUTLINE_MODE plotMode = GetPlotMode();
int thickness = aShape->GetWidth();
int margin = thickness; // unclamped thickness (can be negative)
LINE_STYLE lineStyle = aShape->GetStroke().GetLineStyle();
bool onCopperLayer = ( LSET::AllCuMask() & m_layerMask ).any();
bool onSolderMaskLayer = ( LSET( { F_Mask, B_Mask } ) & m_layerMask ).any();
if( onSolderMaskLayer
&& aShape->HasSolderMask()
&& IsExternalCopperLayer( aShape->GetLayer() ) )
{
margin += 2 * aShape->GetSolderMaskExpansion();
thickness = std::max( margin, 0 );
}
m_plotter->SetColor( getColor( aShape->GetLayer() ) );
@@ -859,7 +870,7 @@ void BRDITEMS_PLOTTER::PlotShape( const PCB_SHAPE* aShape )
{
gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_EDGECUT );
}
else if( IsCopperLayer( aShape->GetLayer() ) )
else if( onCopperLayer )
{
if( parentFP )
{
@@ -894,8 +905,15 @@ void BRDITEMS_PLOTTER::PlotShape( const PCB_SHAPE* aShape )
case SHAPE_T::CIRCLE:
if( aShape->IsFilled() )
{
m_plotter->FilledCircle( aShape->GetStart(), aShape->GetRadius() * 2 + thickness,
plotMode, &gbr_metadata );
int diameter = aShape->GetRadius() * 2 + thickness;
if( margin < 0 )
{
diameter += margin;
diameter = std::max( diameter, 0 );
}
m_plotter->FilledCircle( aShape->GetStart(), diameter, plotMode, &gbr_metadata );
}
else
{
@@ -916,7 +934,7 @@ void BRDITEMS_PLOTTER::PlotShape( const PCB_SHAPE* aShape )
}
else
{
m_plotter->ThickArc( *aShape, plotMode, &gbr_metadata );
m_plotter->ThickArc( *aShape, plotMode, &gbr_metadata, thickness );
}
break;
@@ -949,6 +967,13 @@ void BRDITEMS_PLOTTER::PlotShape( const PCB_SHAPE* aShape )
// from generating invalid Gerber files
SHAPE_POLY_SET tmpPoly = aShape->GetPolyShape().CloneDropTriangulation();
tmpPoly.Fracture( SHAPE_POLY_SET::PM_FAST );
if( margin < 0 )
{
tmpPoly.Inflate( margin / 2, CORNER_STRATEGY::ROUND_ALL_CORNERS,
m_board->GetDesignSettings().m_MaxError );
}
FILL_T fill = aShape->IsFilled() ? FILL_T::FILLED_SHAPE : FILL_T::NO_FILL;
for( int jj = 0; jj < tmpPoly.OutlineCount(); ++jj )
@@ -988,23 +1013,33 @@ void BRDITEMS_PLOTTER::PlotShape( const PCB_SHAPE* aShape )
}
else
{
SHAPE_LINE_CHAIN poly;
SHAPE_POLY_SET poly;
poly.NewOutline();
for( const VECTOR2I& pt : pts )
poly.Append( pt );
poly.Append( pts[0] ); // Close polygon.
if( margin < 0 )
{
poly.Inflate( margin / 2, CORNER_STRATEGY::ROUND_ALL_CORNERS,
m_board->GetDesignSettings().m_MaxError );
}
FILL_T fill_mode = aShape->IsFilled() ? FILL_T::FILLED_SHAPE : FILL_T::NO_FILL;
if( m_plotter->GetPlotterType() == PLOT_FORMAT::GERBER )
if( poly.OutlineCount() > 0 )
{
GERBER_PLOTTER* gbr_plotter = static_cast<GERBER_PLOTTER*>( m_plotter );
gbr_plotter->PlotPolyAsRegion( poly, fill_mode, thickness, &gbr_metadata );
}
else
{
m_plotter->PlotPoly( poly, fill_mode, thickness, &gbr_metadata );
if( m_plotter->GetPlotterType() == PLOT_FORMAT::GERBER )
{
GERBER_PLOTTER* gbr_plotter = static_cast<GERBER_PLOTTER*>( m_plotter );
gbr_plotter->PlotPolyAsRegion( poly.COutline( 0 ), fill_mode, thickness,
&gbr_metadata );
}
else
{
m_plotter->PlotPoly( poly.COutline( 0 ), fill_mode, thickness,
&gbr_metadata );
}
}
}
@@ -1021,7 +1056,8 @@ void BRDITEMS_PLOTTER::PlotShape( const PCB_SHAPE* aShape )
for( SHAPE* shape : shapes )
{
STROKE_PARAMS::Stroke( shape, lineStyle, thickness, m_plotter->RenderSettings(),
STROKE_PARAMS::Stroke( shape, lineStyle, aShape->GetWidth(),
m_plotter->RenderSettings(),
[&]( const VECTOR2I& a, const VECTOR2I& b )
{
m_plotter->ThickSegment( a, b, thickness, plotMode,