Simplify (and fix) plated copper differentiation.

Also a few fixes for 3D rendering textboxes and
tables.
This commit is contained in:
Jeff Young 2025-03-17 20:08:05 +00:00
parent 683444733a
commit 142f8265c5
8 changed files with 108 additions and 145 deletions

View File

@ -146,8 +146,6 @@ BOARD_ADAPTER::BOARD_ADAPTER() :
m_offboardPadsFront = nullptr; m_offboardPadsFront = nullptr;
m_offboardPadsBack = nullptr; m_offboardPadsBack = nullptr;
m_frontPlatedPadAndGraphicPolys = nullptr;
m_backPlatedPadAndGraphicPolys = nullptr;
m_frontPlatedCopperPolys = nullptr; m_frontPlatedCopperPolys = nullptr;
m_backPlatedCopperPolys = nullptr; m_backPlatedCopperPolys = nullptr;

View File

@ -341,14 +341,14 @@ public:
*/ */
const MAP_POLY& GetPolyMap() const noexcept { return m_layers_poly; } const MAP_POLY& GetPolyMap() const noexcept { return m_layers_poly; }
const SHAPE_POLY_SET* GetFrontPlatedPadAndGraphicPolys() const SHAPE_POLY_SET* GetFrontPlatedCopperPolys()
{ {
return m_frontPlatedPadAndGraphicPolys; return m_frontPlatedCopperPolys;
} }
const SHAPE_POLY_SET* GetBackPlatedPadAndGraphicPolys() const SHAPE_POLY_SET* GetBackPlatedCopperPolys()
{ {
return m_backPlatedPadAndGraphicPolys; return m_backPlatedCopperPolys;
} }
const MAP_POLY& GetHoleIdPolysMap() const noexcept { return m_layerHoleIdPolys; } const MAP_POLY& GetHoleIdPolysMap() const noexcept { return m_layerHoleIdPolys; }
@ -375,7 +375,7 @@ private:
int aInflateValue ); int aInflateValue );
void addPads( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aDstContainer, void addPads( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aDstContainer,
PCB_LAYER_ID aLayerId, bool aSkipPlatedPads, bool aSkipNonPlatedPads ); PCB_LAYER_ID aLayerId );
void addFootprintShapes( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aDstContainer, void addFootprintShapes( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aDstContainer,
PCB_LAYER_ID aLayerId, PCB_LAYER_ID aLayerId,
@ -461,8 +461,6 @@ private:
MAP_POLY m_layers_poly; ///< Amalgamated polygon contours for various types MAP_POLY m_layers_poly; ///< Amalgamated polygon contours for various types
///< of items ///< of items
SHAPE_POLY_SET* m_frontPlatedPadAndGraphicPolys;
SHAPE_POLY_SET* m_backPlatedPadAndGraphicPolys;
SHAPE_POLY_SET* m_frontPlatedCopperPolys; SHAPE_POLY_SET* m_frontPlatedCopperPolys;
SHAPE_POLY_SET* m_backPlatedCopperPolys; SHAPE_POLY_SET* m_backPlatedCopperPolys;

View File

@ -503,7 +503,7 @@ void BOARD_ADAPTER::createPadWithHole( const PAD* aPad, CONTAINER_2D_BASE* aDstC
void BOARD_ADAPTER::addPads( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aContainer, void BOARD_ADAPTER::addPads( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aContainer,
PCB_LAYER_ID aLayerId, bool aSkipPlatedPads, bool aSkipNonPlatedPads ) PCB_LAYER_ID aLayerId )
{ {
for( PAD* pad : aFootprint->Pads() ) for( PAD* pad : aFootprint->Pads() )
{ {
@ -527,24 +527,6 @@ void BOARD_ADAPTER::addPads( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aCo
switch( aLayerId ) switch( aLayerId )
{ {
case F_Cu:
if( aSkipPlatedPads && pad->FlashLayer( F_Mask ) )
continue;
if( aSkipNonPlatedPads && !pad->FlashLayer( F_Mask ) )
continue;
break;
case B_Cu:
if( aSkipPlatedPads && pad->FlashLayer( B_Mask ) )
continue;
if( aSkipNonPlatedPads && !pad->FlashLayer( B_Mask ) )
continue;
break;
case F_Mask: case F_Mask:
case B_Mask: case B_Mask:
margin.x += pad->GetSolderMaskExpansion( aLayerId ); margin.x += pad->GetSolderMaskExpansion( aLayerId );

View File

@ -183,8 +183,6 @@ void BOARD_ADAPTER::destroyLayers()
DELETE_AND_FREE_MAP( m_layers_poly ); DELETE_AND_FREE_MAP( m_layers_poly );
DELETE_AND_FREE( m_frontPlatedPadAndGraphicPolys )
DELETE_AND_FREE( m_backPlatedPadAndGraphicPolys )
DELETE_AND_FREE( m_frontPlatedCopperPolys ) DELETE_AND_FREE( m_frontPlatedCopperPolys )
DELETE_AND_FREE( m_backPlatedCopperPolys ) DELETE_AND_FREE( m_backPlatedCopperPolys )
@ -302,8 +300,6 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
if( cfg.DifferentiatePlatedCopper() ) if( cfg.DifferentiatePlatedCopper() )
{ {
m_frontPlatedPadAndGraphicPolys = new SHAPE_POLY_SET;
m_backPlatedPadAndGraphicPolys = new SHAPE_POLY_SET;
m_frontPlatedCopperPolys = new SHAPE_POLY_SET; m_frontPlatedCopperPolys = new SHAPE_POLY_SET;
m_backPlatedCopperPolys = new SHAPE_POLY_SET; m_backPlatedCopperPolys = new SHAPE_POLY_SET;
@ -614,10 +610,19 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
// ADD PADS // ADD PADS
for( FOOTPRINT* footprint : m_board->Footprints() ) for( FOOTPRINT* footprint : m_board->Footprints() )
{ {
addPads( footprint, layerContainer, layer, cfg.DifferentiatePlatedCopper(), false ); addPads( footprint, layerContainer, layer );
// Micro-wave footprints may have items on copper layers
addFootprintShapes( footprint, layerContainer, layer, visibilityFlags ); addFootprintShapes( footprint, layerContainer, layer, visibilityFlags );
if( cfg.DifferentiatePlatedCopper() && layer == F_Cu )
{
footprint->TransformPadsToPolySet( *m_frontPlatedCopperPolys, F_Cu, 0, maxError,
ERROR_INSIDE, true );
}
else if( cfg.DifferentiatePlatedCopper() && layer == B_Cu )
{
footprint->TransformPadsToPolySet( *m_backPlatedCopperPolys, B_Cu, 0, maxError,
ERROR_INSIDE, true );
}
} }
} }
@ -636,24 +641,11 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
// Note: NPTH pads are not drawn on copper layers when the pad has same shape as // Note: NPTH pads are not drawn on copper layers when the pad has same shape as
// its hole // its hole
footprint->TransformPadsToPolySet( *layerPoly, layer, 0, maxError, ERROR_INSIDE, footprint->TransformPadsToPolySet( *layerPoly, layer, 0, maxError, ERROR_INSIDE,
true, cfg.DifferentiatePlatedCopper(), false ); true );
transformFPShapesToPolySet( footprint, layer, *layerPoly, maxError, ERROR_INSIDE ); transformFPShapesToPolySet( footprint, layer, *layerPoly, maxError, ERROR_INSIDE );
} }
} }
if( cfg.DifferentiatePlatedCopper() )
{
// ADD PLATED PADS contours
for( FOOTPRINT* footprint : m_board->Footprints() )
{
footprint->TransformPadsToPolySet( *m_frontPlatedPadAndGraphicPolys, F_Cu, 0,
maxError, ERROR_INSIDE, true, false, true );
footprint->TransformPadsToPolySet( *m_backPlatedPadAndGraphicPolys, B_Cu, 0,
maxError, ERROR_INSIDE, true, false, true );
}
}
} }
// Add graphic item on copper layers to object containers // Add graphic item on copper layers to object containers
@ -702,36 +694,29 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
} }
// add also this shape to the plated copper polygon list if required // add also this shape to the plated copper polygon list if required
if( cfg.DifferentiatePlatedCopper() ) if( cfg.DifferentiatePlatedCopper() && ( layer == F_Cu || layer == B_Cu ) )
{ {
// Note: for TEXT and TEXTBOX, TransformShapeToPolygon returns the bounding SHAPE_POLY_SET* copperPolys = layer == F_Cu ? m_frontPlatedCopperPolys
// box shape, not the exact text shape. So it is not used for these items
if( layer == F_Cu || layer == B_Cu )
{
SHAPE_POLY_SET* platedCopperPolys = layer == F_Cu
? m_frontPlatedCopperPolys
: m_backPlatedCopperPolys; : m_backPlatedCopperPolys;
if( item->Type() == PCB_TEXTBOX_T ) // Note: for TEXT and TEXTBOX, TransformShapeToPolygon returns the bounding
{ // box shape, not the exact text shape. So it is not used for these items
PCB_TEXTBOX* text_box = static_cast<PCB_TEXTBOX*>( item ); if( item->Type() == PCB_TEXTBOX_T )
text_box->TransformTextToPolySet( *platedCopperPolys, {
0, maxError, ERROR_INSIDE ); PCB_TEXTBOX* text_box = static_cast<PCB_TEXTBOX*>( item );
// Add box outlines text_box->TransformTextToPolySet( *copperPolys, 0, maxError, ERROR_INSIDE );
text_box->PCB_SHAPE::TransformShapeToPolygon( *platedCopperPolys, layer, // Add box outlines
0, maxError, ERROR_INSIDE ); text_box->PCB_SHAPE::TransformShapeToPolygon( *copperPolys, layer, 0, maxError,
} ERROR_INSIDE );
else if( item->Type() == PCB_TEXT_T ) }
{ else if( item->Type() == PCB_TEXT_T )
static_cast<PCB_TEXT*>( item )->TransformTextToPolySet( *platedCopperPolys, {
0, maxError, PCB_TEXT* text = static_cast<PCB_TEXT*>( item );
ERROR_INSIDE ); text->TransformTextToPolySet( *copperPolys, 0, maxError, ERROR_INSIDE );
} }
else else
{ {
item->TransformShapeToPolySet( *platedCopperPolys, layer, 0, maxError, item->TransformShapeToPolySet( *copperPolys, layer, 0, maxError, ERROR_INSIDE );
ERROR_INSIDE );
}
} }
} }
} }
@ -770,13 +755,32 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
{ {
PCB_TEXTBOX* textbox = static_cast<PCB_TEXTBOX*>( item ); PCB_TEXTBOX* textbox = static_cast<PCB_TEXTBOX*>( item );
if( textbox->IsBorderEnabled() )
{
textbox->PCB_SHAPE::TransformShapeToPolygon( *layerPoly, layer, 0,
maxError, ERROR_INSIDE );
}
textbox->TransformTextToPolySet( *layerPoly, 0, maxError, ERROR_INSIDE ); textbox->TransformTextToPolySet( *layerPoly, 0, maxError, ERROR_INSIDE );
break; break;
} }
case PCB_TABLE_T: case PCB_TABLE_T:
// JEY TODO: tables {
PCB_TABLE* table = static_cast<PCB_TABLE*>( item );
for( PCB_TABLECELL* cell : table->GetCells() )
cell->TransformTextToPolySet( *layerPoly, 0, maxError, ERROR_INSIDE );
table->DrawBorders(
[&]( const VECTOR2I& ptA, const VECTOR2I& ptB,
const STROKE_PARAMS& stroke )
{
SHAPE_SEGMENT seg( ptA, ptB, stroke.GetWidth() );
seg.TransformToPolygon( *layerPoly, maxError, ERROR_INSIDE );
} );
break; break;
}
default: default:
wxLogTrace( m_logTrace, wxT( "createLayers: item type: %d not implemented" ), wxLogTrace( m_logTrace, wxT( "createLayers: item type: %d not implemented" ),
@ -1042,7 +1046,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
} }
else else
{ {
addPads( footprint, layerContainer, layer, false, false ); addPads( footprint, layerContainer, layer );
} }
addFootprintShapes( footprint, layerContainer, layer, visibilityFlags ); addFootprintShapes( footprint, layerContainer, layer, visibilityFlags );
@ -1088,13 +1092,33 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
{ {
PCB_TEXTBOX* textbox = static_cast<PCB_TEXTBOX*>( item ); PCB_TEXTBOX* textbox = static_cast<PCB_TEXTBOX*>( item );
if( textbox->IsBorderEnabled() )
{
textbox->PCB_SHAPE::TransformShapeToPolygon( *layerPoly, layer, 0,
maxError, ERROR_INSIDE );
}
textbox->TransformTextToPolySet( *layerPoly, 0, maxError, ERROR_INSIDE ); textbox->TransformTextToPolySet( *layerPoly, 0, maxError, ERROR_INSIDE );
break; break;
} }
case PCB_TABLE_T: case PCB_TABLE_T:
// JEY TODO: tables {
PCB_TABLE* table = static_cast<PCB_TABLE*>( item );
for( PCB_TABLECELL* cell : table->GetCells() )
cell->TransformTextToPolySet( *layerPoly, 0, maxError, ERROR_INSIDE );
table->DrawBorders(
[&]( const VECTOR2I& ptA, const VECTOR2I& ptB,
const STROKE_PARAMS& stroke )
{
SHAPE_SEGMENT seg( ptA, ptB, stroke.GetWidth() );
seg.TransformToPolygon( *layerPoly, maxError, ERROR_INSIDE );
} );
break; break;
}
default: default:
break; break;
@ -1172,9 +1196,9 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
if( !footprint->GetBoundingBox().Intersects( boardBBox ) ) if( !footprint->GetBoundingBox().Intersects( boardBBox ) )
{ {
if( footprint->IsFlipped() ) if( footprint->IsFlipped() )
addPads( footprint, m_offboardPadsBack, B_Cu, false, false ); addPads( footprint, m_offboardPadsBack, B_Cu );
else else
addPads( footprint, m_offboardPadsFront, F_Cu, false, false ); addPads( footprint, m_offboardPadsFront, F_Cu );
} }
} }
@ -1200,41 +1224,11 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
m_backPlatedCopperPolys->BooleanIntersection( *m_layers_poly.at( B_Mask ) ); m_backPlatedCopperPolys->BooleanIntersection( *m_layers_poly.at( B_Mask ) );
// Subtract plated copper from unplated copper // Subtract plated copper from unplated copper
bool hasF_Cu = false;
bool hasB_Cu = false;
if( m_layers_poly.find( F_Cu ) != m_layers_poly.end() ) if( m_layers_poly.find( F_Cu ) != m_layers_poly.end() )
{
m_layers_poly[F_Cu]->BooleanSubtract( *m_frontPlatedPadAndGraphicPolys );
m_layers_poly[F_Cu]->BooleanSubtract( *m_frontPlatedCopperPolys ); m_layers_poly[F_Cu]->BooleanSubtract( *m_frontPlatedCopperPolys );
hasF_Cu = true;
}
if( m_layers_poly.find( B_Cu ) != m_layers_poly.end() ) if( m_layers_poly.find( B_Cu ) != m_layers_poly.end() )
{
m_layers_poly[B_Cu]->BooleanSubtract( *m_backPlatedPadAndGraphicPolys );
m_layers_poly[B_Cu]->BooleanSubtract( *m_backPlatedCopperPolys ); m_layers_poly[B_Cu]->BooleanSubtract( *m_backPlatedCopperPolys );
hasB_Cu = true;
}
// Add plated graphic items to build vertical walls
if( hasF_Cu && m_frontPlatedCopperPolys->OutlineCount() )
m_frontPlatedPadAndGraphicPolys->Append( *m_frontPlatedCopperPolys );
if( hasB_Cu && m_backPlatedCopperPolys->OutlineCount() )
m_backPlatedPadAndGraphicPolys->Append( *m_backPlatedCopperPolys );
m_frontPlatedPadAndGraphicPolys->Simplify();
m_backPlatedPadAndGraphicPolys->Simplify();
m_frontPlatedCopperPolys->Simplify();
m_backPlatedCopperPolys->Simplify();
// ADD PLATED PADS
for( FOOTPRINT* footprint : m_board->Footprints() )
{
addPads( footprint, m_platedPadsFront, F_Cu, false, true );
addPads( footprint, m_platedPadsBack, B_Cu, false, true );
}
// ADD PLATED COPPER // ADD PLATED COPPER
ConvertPolygonToTriangles( *m_frontPlatedCopperPolys, *m_platedPadsFront, m_biuTo3Dunits, ConvertPolygonToTriangles( *m_frontPlatedCopperPolys, *m_platedPadsFront, m_biuTo3Dunits,

View File

@ -607,14 +607,12 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
if( m_boardAdapter.m_Cfg->m_Render.DifferentiatePlatedCopper() ) if( m_boardAdapter.m_Cfg->m_Render.DifferentiatePlatedCopper() )
{ {
const SHAPE_POLY_SET* frontPlatedPadAndGraphicPolys = const SHAPE_POLY_SET* frontPlatedCopperPolys = m_boardAdapter.GetFrontPlatedCopperPolys();
m_boardAdapter.GetFrontPlatedPadAndGraphicPolys(); const SHAPE_POLY_SET* backPlatedCopperPolys = m_boardAdapter.GetBackPlatedCopperPolys();
const SHAPE_POLY_SET* backPlatedPadAndGraphicPolys =
m_boardAdapter.GetBackPlatedPadAndGraphicPolys();
if( frontPlatedPadAndGraphicPolys ) if( frontPlatedCopperPolys )
{ {
SHAPE_POLY_SET poly = frontPlatedPadAndGraphicPolys->CloneDropTriangulation(); SHAPE_POLY_SET poly = frontPlatedCopperPolys->CloneDropTriangulation();
poly.BooleanIntersection( m_boardAdapter.GetBoardPoly() ); poly.BooleanIntersection( m_boardAdapter.GetBoardPoly() );
poly.BooleanSubtract( m_boardAdapter.GetTH_ODPolys() ); poly.BooleanSubtract( m_boardAdapter.GetTH_ODPolys() );
poly.BooleanSubtract( m_boardAdapter.GetNPTH_ODPolys() ); poly.BooleanSubtract( m_boardAdapter.GetNPTH_ODPolys() );
@ -627,9 +625,9 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
m_layers[F_Cu] = generateEmptyLayerList( F_Cu ); m_layers[F_Cu] = generateEmptyLayerList( F_Cu );
} }
if( backPlatedPadAndGraphicPolys ) if( backPlatedCopperPolys )
{ {
SHAPE_POLY_SET poly = backPlatedPadAndGraphicPolys->CloneDropTriangulation(); SHAPE_POLY_SET poly = backPlatedCopperPolys->CloneDropTriangulation();
poly.BooleanIntersection( m_boardAdapter.GetBoardPoly() ); poly.BooleanIntersection( m_boardAdapter.GetBoardPoly() );
poly.BooleanSubtract( m_boardAdapter.GetTH_ODPolys() ); poly.BooleanSubtract( m_boardAdapter.GetTH_ODPolys() );
poly.BooleanSubtract( m_boardAdapter.GetNPTH_ODPolys() ); poly.BooleanSubtract( m_boardAdapter.GetNPTH_ODPolys() );

View File

@ -29,6 +29,8 @@
#include <board_design_settings.h> #include <board_design_settings.h>
#include <footprint.h> #include <footprint.h>
#include <pcb_textbox.h> #include <pcb_textbox.h>
#include <pcb_table.h>
#include <pcb_tablecell.h>
#include <pcb_track.h> #include <pcb_track.h>
#include <pcb_shape.h> #include <pcb_shape.h>
#include <pad.h> #include <pad.h>
@ -545,8 +547,22 @@ bool EXPORTER_STEP::buildGraphic3DShape( BOARD_ITEM* aItem, VECTOR2D aOrigin )
} }
case PCB_TABLE_T: case PCB_TABLE_T:
// JEY TODO: tables {
PCB_TABLE* table = static_cast<PCB_TABLE*>( aItem );
for( PCB_TABLECELL* cell : table->GetCells() )
cell->TransformTextToPolySet( m_poly_shapes[pcblayer], 0, maxError, ERROR_INSIDE );
table->DrawBorders(
[&]( const VECTOR2I& ptA, const VECTOR2I& ptB,
const STROKE_PARAMS& stroke )
{
SHAPE_SEGMENT seg( ptA, ptB, stroke.GetWidth() );
seg.TransformToPolygon( m_poly_shapes[pcblayer], maxError, ERROR_INSIDE );
} );
break; break;
}
default: wxFAIL_MSG( "buildGraphic3DShape: unhandled item type" ); default: wxFAIL_MSG( "buildGraphic3DShape: unhandled item type" );
} }

View File

@ -3852,8 +3852,7 @@ bool FOOTPRINT::cmp_zones::operator()( const ZONE* aFirst, const ZONE* aSecond )
void FOOTPRINT::TransformPadsToPolySet( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer, void FOOTPRINT::TransformPadsToPolySet( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer,
int aClearance, int aMaxError, ERROR_LOC aErrorLoc, int aClearance, int aMaxError, ERROR_LOC aErrorLoc,
bool aSkipNPTHPadsWihNoCopper, bool aSkipPlatedPads, bool aSkipNPTHPadsWihNoCopper ) const
bool aSkipNonPlatedPads ) const
{ {
auto processPad = auto processPad =
[&]( const PAD* pad, PCB_LAYER_ID padLayer ) [&]( const PAD* pad, PCB_LAYER_ID padLayer )
@ -3862,24 +3861,6 @@ void FOOTPRINT::TransformPadsToPolySet( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aL
switch( aLayer ) switch( aLayer )
{ {
case F_Cu:
if( aSkipPlatedPads && pad->FlashLayer( F_Mask ) )
return;
if( aSkipNonPlatedPads && !pad->FlashLayer( F_Mask ) )
return;
break;
case B_Cu:
if( aSkipPlatedPads && pad->FlashLayer( B_Mask ) )
return;
if( aSkipNonPlatedPads && !pad->FlashLayer( B_Mask ) )
return;
break;
case F_Mask: case F_Mask:
case B_Mask: case B_Mask:
clearance.x += pad->GetSolderMaskExpansion( padLayer ); clearance.x += pad->GetSolderMaskExpansion( padLayer );

View File

@ -539,14 +539,10 @@ public:
* Due to diff between layers and holes, these pads must be skipped to be sure * Due to diff between layers and holes, these pads must be skipped to be sure
* there is no copper left on the board (for instance when creating Gerber Files or * there is no copper left on the board (for instance when creating Gerber Files or
* 3D shapes). Defaults to false. * 3D shapes). Defaults to false.
* @param aSkipPlatedPads is used on 3D-Viewer to extract plated and non-plated pads.
* @param aSkipNonPlatedPads is used on 3D-Viewer to extract plated and plated pads.
*/ */
void TransformPadsToPolySet( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer, int aClearance, void TransformPadsToPolySet( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer, int aClearance,
int aMaxError, ERROR_LOC aErrorLoc, int aMaxError, ERROR_LOC aErrorLoc,
bool aSkipNPTHPadsWihNoCopper = false, bool aSkipNPTHPadsWihNoCopper = false ) const;
bool aSkipPlatedPads = false,
bool aSkipNonPlatedPads = false ) const;
/** /**
* Generate shapes of graphic items (outlines) on layer \a aLayer as polygons and adds these * Generate shapes of graphic items (outlines) on layer \a aLayer as polygons and adds these