Pcbnew: plot solder mask layer with min width value specified: algorithm modified to reduce artifacts.
This commit is contained in:
parent
affbb8a8e0
commit
ac41e7009e
|
@ -449,6 +449,20 @@ void PlotStandardLayer( BOARD *aBoard, PLOTTER* aPlotter,
|
|||
/* Plot a solder mask layer.
|
||||
* Solder mask layers have a minimum thickness value and cannot be drawn like standard layers,
|
||||
* unless the minimum thickness is 0.
|
||||
* Currently the algo is:
|
||||
* 1 - build all pad shapes as polygons with a size inflated by
|
||||
* mask clearance + (min width solder mask /2)
|
||||
* 2 - Merge shapes
|
||||
* 3 - deflate result by (min width solder mask /2)
|
||||
* 4 - oring result by all pad shapes as polygons with a size inflated by
|
||||
* mask clearance only (because deflate sometimes creates shape artifacts)
|
||||
* 5 - draw result as plolygons.
|
||||
*
|
||||
* TODO:
|
||||
* make this calculation only for shapes with clearance near than (min width solder mask)
|
||||
* (using DRC algo)
|
||||
* plot all other shapes by flashing the basing shape
|
||||
* (shapes will be better, and calculations faster)
|
||||
*/
|
||||
void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter,
|
||||
long aLayerMask, const PCB_PLOT_PARAMS& aPlotOpt,
|
||||
|
@ -461,9 +475,6 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter,
|
|||
BRDITEMS_PLOTTER itemplotter( aPlotter, aBoard, aPlotOpt );
|
||||
itemplotter.SetLayerMask( aLayerMask );
|
||||
|
||||
// EDA_DRAW_MODE_T plotMode = aPlotOpt.GetMode();
|
||||
// EDA_COLOR_T color = BLACK;
|
||||
|
||||
// Plot edge layer and graphic items
|
||||
itemplotter.PlotBoardGraphicItems();
|
||||
|
||||
|
@ -495,6 +506,7 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter,
|
|||
// (distance < aMinThickness), and will be removed when creating
|
||||
// the actual shapes
|
||||
std::vector <CPolyPt> bufferPolys; // Contains shapes to plot
|
||||
std::vector <CPolyPt> initialPolys; // Contains exact shapes to plot
|
||||
|
||||
/* calculates the coeff to compensate radius reduction of holes clearance
|
||||
* due to the segment approx ( 1 /cos( PI/circleToSegmentsCount )
|
||||
|
@ -510,16 +522,55 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter,
|
|||
if( (pad->GetLayerMask() & aLayerMask) == 0 )
|
||||
continue;
|
||||
|
||||
int margin = pad->GetSolderMaskMargin() + inflate;
|
||||
pad->TransformShapeWithClearanceToPolygon( bufferPolys, margin,
|
||||
int clearance = pad->GetSolderMaskMargin();
|
||||
int margin = clearance + inflate;
|
||||
|
||||
// For rect and trap. pads, use a polygon with the same shape
|
||||
// (i.e. with no rounded corners)
|
||||
if( (pad->GetShape() == PAD_RECT) || (pad->GetShape() == PAD_TRAPEZOID) )
|
||||
{
|
||||
wxPoint coord[4];
|
||||
CPolyPt corner;
|
||||
pad->BuildPadPolygon( coord, wxSize( margin, margin ),
|
||||
pad->GetOrientation() );
|
||||
for( int ii = 0; ii < 4; ii++ )
|
||||
{
|
||||
coord[ii] += pad->ReturnShapePos();
|
||||
corner.x = coord[ii].x;
|
||||
corner.y = coord[ii].y;
|
||||
corner.end_contour = (ii == 3);
|
||||
bufferPolys.push_back( corner );
|
||||
}
|
||||
pad->BuildPadPolygon( coord, wxSize( clearance, clearance ),
|
||||
pad->GetOrientation() );
|
||||
for( int ii = 0; ii < 4; ii++ )
|
||||
{
|
||||
coord[ii] += pad->ReturnShapePos();
|
||||
corner.x = coord[ii].x;
|
||||
corner.y = coord[ii].y;
|
||||
corner.end_contour = (ii == 3);
|
||||
initialPolys.push_back( corner );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pad->TransformShapeWithClearanceToPolygon( bufferPolys, clearance + inflate,
|
||||
circleToSegmentsCount,
|
||||
correction );
|
||||
pad->TransformShapeWithClearanceToPolygon( initialPolys, clearance,
|
||||
circleToSegmentsCount,
|
||||
correction );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Plot vias on solder masks, if aPlotOpt.GetPlotViaOnMaskLayer() is true,
|
||||
if( aPlotOpt.GetPlotViaOnMaskLayer() )
|
||||
{
|
||||
// The current layer is a solder mask,
|
||||
// use the global mask clearance for vias
|
||||
int via_clearance = aBoard->GetDesignSettings().m_SolderMaskMargin;
|
||||
int via_margin = via_clearance + inflate;
|
||||
for( TRACK* track = aBoard->m_Track; track; track = track->Next() )
|
||||
{
|
||||
if( track->Type() != PCB_VIA_T )
|
||||
|
@ -540,13 +591,12 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter,
|
|||
if( ( via_mask_layer & aLayerMask ) == 0 )
|
||||
continue;
|
||||
|
||||
// The current layer is a solder mask,
|
||||
// use the global mask clearance for vias
|
||||
int via_margin = aBoard->GetDesignSettings().m_SolderMaskMargin + inflate;
|
||||
|
||||
via->TransformShapeWithClearanceToPolygon( bufferPolys, via_margin,
|
||||
circleToSegmentsCount,
|
||||
correction );
|
||||
via->TransformShapeWithClearanceToPolygon( initialPolys, via_clearance,
|
||||
circleToSegmentsCount,
|
||||
correction );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -569,6 +619,8 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter,
|
|||
// 2 - deflate resulting areas by aMinThickness/2
|
||||
KI_POLYGON_SET areasToMerge;
|
||||
AddPolygonCornersToKiPolygonList( bufferPolys, areasToMerge );
|
||||
KI_POLYGON_SET initialAreas;
|
||||
AddPolygonCornersToKiPolygonList( initialPolys, initialAreas );
|
||||
|
||||
// Merge polygons: because each shape was created with an extra margin
|
||||
// = aMinThickness/2, shapes too close ( dist < aMinThickness )
|
||||
|
@ -577,7 +629,13 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter,
|
|||
areas |= areasToMerge;
|
||||
|
||||
// Deflate: remove the extra margin, to create the actual shapes
|
||||
areas -= inflate;
|
||||
// Here I am using ploygon:resize, because this function creates better shapes
|
||||
// than deflate algo.
|
||||
// Use here deflate with arc creation and 16 segments per circle to create arcs
|
||||
areas = resize( areas, -inflate , true, 16 );
|
||||
|
||||
// Resize slighly changes shapes. So *ensure* initial shapes are kept
|
||||
areas |= initialAreas;
|
||||
|
||||
// To avoid a lot of code, use a ZONE_CONTAINER
|
||||
// to plot polygons, because they are exactly like
|
||||
|
|
Loading…
Reference in New Issue