diff --git a/pcbnew/drc/drc_test_provider_solder_mask.cpp b/pcbnew/drc/drc_test_provider_solder_mask.cpp index 8b17511cbd..7bdc3269fc 100644 --- a/pcbnew/drc/drc_test_provider_solder_mask.cpp +++ b/pcbnew/drc/drc_test_provider_solder_mask.cpp @@ -153,8 +153,6 @@ void DRC_TEST_PROVIDER_SOLDER_MASK::addItemToRTrees( BOARD_ITEM* item ) } else { - // JEY TODO: plotter doesn't currently expand graphics by web thickness... - for( PCB_LAYER_ID layer : { F_Mask, B_Mask } ) { if( item->IsOnLayer( layer ) ) diff --git a/pcbnew/pcbplot.h b/pcbnew/pcbplot.h index 52420c3573..20cad0301a 100644 --- a/pcbnew/pcbplot.h +++ b/pcbnew/pcbplot.h @@ -28,6 +28,7 @@ #include #include #include +#include class PLOTTER; class PCB_TEXT; @@ -105,6 +106,7 @@ public: * Plot items like text and graphics but not tracks and footprints. */ void PlotBoardGraphicItems(); + void PlotPcbGraphicItem( const BOARD_ITEM* item ); /** * Draw a drill mark for pads and vias. diff --git a/pcbnew/plot_board_layers.cpp b/pcbnew/plot_board_layers.cpp index 1c83be5c07..6ad7849e62 100644 --- a/pcbnew/plot_board_layers.cpp +++ b/pcbnew/plot_board_layers.cpp @@ -821,31 +821,16 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter, LSET aLayerMask, if( aBoard->GetBoardPolygonOutlines( buffer ) ) boardOutline = &buffer; - // We remove 1nm as we expand both sides of the shapes, so allowing for - // a strictly greater than or equal comparison in the shape separation (boolean add) - // means that we will end up with separate shapes that then are shrunk + // We remove 1nm as we expand both sides of the shapes, so allowing for a strictly greater + // than or equal comparison in the shape separation (boolean add) int inflate = aMinThickness/2 - 1; BRDITEMS_PLOTTER itemplotter( aPlotter, aBoard, aPlotOpt ); itemplotter.SetLayerSet( aLayerMask ); - // Plot edge layer and graphic items. - // They do not have a solder Mask margin, because they are graphic items - // on this layer (like logos), not actually areas around pads. - - itemplotter.PlotBoardGraphicItems(); - for( FOOTPRINT* footprint : aBoard->Footprints() ) - { itemplotter.PlotFootprintTextItems( footprint ); - for( BOARD_ITEM* item : footprint->GraphicalItems() ) - { - if( item->Type() == PCB_FP_SHAPE_T && item->GetLayer() == layer ) - itemplotter.PlotFootprintGraphicItem( (FP_SHAPE*) item ); - } - } - // Build polygons for each pad shape. The size of the shape on solder mask should be size // of pad + clearance around the pad, where clearance = solder mask clearance + extra margin. // Extra margin is half the min width for solder mask, which is used to merge too-close shapes @@ -860,13 +845,13 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter, LSET aLayerMask, SHAPE_POLY_SET initialPolys; #if NEW_ALGO - // Generate polygons with arcs inside the shape or exact shape - // to minimize shape changes created by arc to segment size correction. + // Generate polygons with arcs inside the shape or exact shape to minimize shape changes + // created by arc to segment size correction. DISABLE_ARC_RADIUS_CORRECTION disabler; #endif { - // Plot pads - for( FOOTPRINT* footprint : aBoard->Footprints() ) + // Plot footprint pads and graphics + for( const FOOTPRINT* footprint : aBoard->Footprints() ) { // add shapes with their exact mask layer size in initialPolys footprint->TransformPadsWithClearanceToPolygon( initialPolys, layer, 0, maxError, @@ -874,40 +859,41 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter, LSET aLayerMask, // add shapes inflated by aMinThickness/2 in areas footprint->TransformPadsWithClearanceToPolygon( areas, layer, inflate, maxError, ERROR_OUTSIDE ); + + for( const BOARD_ITEM* item : footprint->GraphicalItems() ) + { + if( item->Type() == PCB_FP_SHAPE_T && item->IsOnLayer( layer ) ) + { + // add shapes with their exact mask layer size in initialPolys + item->TransformShapeWithClearanceToPolygon( initialPolys, layer, 0, maxError, + ERROR_OUTSIDE ); + // add shapes inflated by aMinThickness/2 in areas + item->TransformShapeWithClearanceToPolygon( areas, layer, inflate, maxError, + ERROR_OUTSIDE ); + } + else if( item->Type() == PCB_FP_SHAPE_T && item->IsOnLayer( Edge_Cuts ) ) + { + itemplotter.PlotFootprintGraphicItem( static_cast( item ) ); + } + } } - // Plot vias on solder masks, if aPlotOpt.GetPlotViaOnMaskLayer() is true, - if( aPlotOpt.GetPlotViaOnMaskLayer() ) + // Plot (untented) vias + for( const PCB_TRACK* track : aBoard->Tracks() ) { - for( PCB_TRACK* track : aBoard->Tracks() ) - { - const PCB_VIA* via = dyn_cast( track ); - int via_clearance = via->GetSolderMaskExpansion(); - int via_margin = via_clearance + inflate; + const PCB_VIA* via = dyn_cast( track ); + int clearance = via->GetSolderMaskExpansion(); + // Note: IsOnLayer() checks relevant mask layers of untented vias + if( !via || !via->IsOnLayer( layer ) ) + continue; - if( !via ) - continue; - - // vias are plotted only if they are on the corresponding external copper layer - LSET via_set = via->GetLayerSet(); - - if( via_set[B_Cu] ) - via_set.set( B_Mask ); - - if( via_set[F_Cu] ) - via_set.set( F_Mask ); - - if( !( via_set & aLayerMask ).any() ) - continue; - - // add shapes with their exact mask layer size in initialPolys - via->TransformShapeWithClearanceToPolygon( initialPolys, layer, via_clearance, - maxError, ERROR_OUTSIDE ); - // add shapes inflated by aMinThickness/2 in areas - via->TransformShapeWithClearanceToPolygon( areas, layer, via_margin, maxError, - ERROR_OUTSIDE ); - } + // add shapes with their exact mask layer size in initialPolys + via->TransformShapeWithClearanceToPolygon( initialPolys, layer, clearance, maxError, + ERROR_OUTSIDE ); + // add shapes inflated by aMinThickness/2 in areas + via->TransformShapeWithClearanceToPolygon( areas, layer, clearance + inflate, maxError, + ERROR_OUTSIDE ); } // Add filled zone areas. @@ -917,6 +903,23 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter, LSET aLayerMask, int zone_margin = 0; #endif + for( const BOARD_ITEM* item : aBoard->Drawings() ) + { + if( item->IsOnLayer( layer ) ) + { + // add shapes with their exact mask layer size in initialPolys + item->TransformShapeWithClearanceToPolygon( initialPolys, layer, 0, maxError, + ERROR_OUTSIDE ); + // add shapes inflated by aMinThickness/2 in areas + item->TransformShapeWithClearanceToPolygon( areas, layer, inflate, maxError, + ERROR_OUTSIDE ); + } + else if( item->IsOnLayer( Edge_Cuts ) ) + { + itemplotter.PlotPcbGraphicItem( item ); + } + } + for( ZONE* zone : aBoard->Zones() ) { if( !zone->IsOnLayer( layer ) ) diff --git a/pcbnew/plot_brditems_plotter.cpp b/pcbnew/plot_brditems_plotter.cpp index ef9769f9e8..d6824e1ae8 100644 --- a/pcbnew/plot_brditems_plotter.cpp +++ b/pcbnew/plot_brditems_plotter.cpp @@ -340,36 +340,40 @@ void BRDITEMS_PLOTTER::PlotFootprintTextItems( const FOOTPRINT* aFootprint ) } +void BRDITEMS_PLOTTER::PlotPcbGraphicItem( const BOARD_ITEM* item ) +{ + switch( item->Type() ) + { + case PCB_SHAPE_T: + PlotPcbShape( static_cast( item ) ); + break; + + case PCB_TEXT_T: + PlotPcbText( static_cast( item ) ); + break; + + case PCB_DIM_ALIGNED_T: + case PCB_DIM_CENTER_T: + case PCB_DIM_RADIAL_T: + case PCB_DIM_ORTHOGONAL_T: + case PCB_DIM_LEADER_T: + PlotDimension( static_cast( item ) ); + break; + + case PCB_TARGET_T: + PlotPcbTarget( static_cast( item ) ); + break; + + default: + break; + } +} + + void BRDITEMS_PLOTTER::PlotBoardGraphicItems() { - for( BOARD_ITEM* item : m_board->Drawings() ) - { - switch( item->Type() ) - { - case PCB_SHAPE_T: - PlotPcbShape( (PCB_SHAPE*) item ); - break; - - case PCB_TEXT_T: - PlotPcbText( (PCB_TEXT*) item ); - break; - - case PCB_DIM_ALIGNED_T: - case PCB_DIM_CENTER_T: - case PCB_DIM_RADIAL_T: - case PCB_DIM_ORTHOGONAL_T: - case PCB_DIM_LEADER_T: - PlotDimension( (PCB_DIMENSION_BASE*) item ); - break; - - case PCB_TARGET_T: - PlotPcbTarget( (PCB_TARGET*) item ); - break; - - default: - break; - } - } + for( const BOARD_ITEM* item : m_board->Drawings() ) + PlotPcbGraphicItem( item ); }