From 142f8265c54f31088967c71e6170bce9810edb06 Mon Sep 17 00:00:00 2001 From: Jeff Young <jeff@rokeby.ie> Date: Mon, 17 Mar 2025 20:08:05 +0000 Subject: [PATCH] Simplify (and fix) plated copper differentiation. Also a few fixes for 3D rendering textboxes and tables. --- 3d-viewer/3d_canvas/board_adapter.cpp | 2 - 3d-viewer/3d_canvas/board_adapter.h | 12 +- .../3d_canvas/create_3Dgraphic_brd_items.cpp | 20 +-- 3d-viewer/3d_canvas/create_layer_items.cpp | 160 +++++++++--------- .../3d_rendering/opengl/create_scene.cpp | 14 +- pcbnew/exporters/step/exporter_step.cpp | 18 +- pcbnew/footprint.cpp | 21 +-- pcbnew/footprint.h | 6 +- 8 files changed, 108 insertions(+), 145 deletions(-) diff --git a/3d-viewer/3d_canvas/board_adapter.cpp b/3d-viewer/3d_canvas/board_adapter.cpp index 62fc5b320d..87911cfebb 100644 --- a/3d-viewer/3d_canvas/board_adapter.cpp +++ b/3d-viewer/3d_canvas/board_adapter.cpp @@ -146,8 +146,6 @@ BOARD_ADAPTER::BOARD_ADAPTER() : m_offboardPadsFront = nullptr; m_offboardPadsBack = nullptr; - m_frontPlatedPadAndGraphicPolys = nullptr; - m_backPlatedPadAndGraphicPolys = nullptr; m_frontPlatedCopperPolys = nullptr; m_backPlatedCopperPolys = nullptr; diff --git a/3d-viewer/3d_canvas/board_adapter.h b/3d-viewer/3d_canvas/board_adapter.h index 1b71c0f9c5..ae0e6056e7 100644 --- a/3d-viewer/3d_canvas/board_adapter.h +++ b/3d-viewer/3d_canvas/board_adapter.h @@ -341,14 +341,14 @@ public: */ 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; } @@ -375,7 +375,7 @@ private: int aInflateValue ); 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, PCB_LAYER_ID aLayerId, @@ -461,8 +461,6 @@ private: MAP_POLY m_layers_poly; ///< Amalgamated polygon contours for various types ///< of items - SHAPE_POLY_SET* m_frontPlatedPadAndGraphicPolys; - SHAPE_POLY_SET* m_backPlatedPadAndGraphicPolys; SHAPE_POLY_SET* m_frontPlatedCopperPolys; SHAPE_POLY_SET* m_backPlatedCopperPolys; diff --git a/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp b/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp index 5f8748b034..4acff477d3 100644 --- a/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp +++ b/3d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp @@ -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, - PCB_LAYER_ID aLayerId, bool aSkipPlatedPads, bool aSkipNonPlatedPads ) + PCB_LAYER_ID aLayerId ) { for( PAD* pad : aFootprint->Pads() ) { @@ -527,24 +527,6 @@ void BOARD_ADAPTER::addPads( const FOOTPRINT* aFootprint, CONTAINER_2D_BASE* aCo 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 B_Mask: margin.x += pad->GetSolderMaskExpansion( aLayerId ); diff --git a/3d-viewer/3d_canvas/create_layer_items.cpp b/3d-viewer/3d_canvas/create_layer_items.cpp index 6ec6365a19..088b6bca2e 100644 --- a/3d-viewer/3d_canvas/create_layer_items.cpp +++ b/3d-viewer/3d_canvas/create_layer_items.cpp @@ -183,8 +183,6 @@ void BOARD_ADAPTER::destroyLayers() 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_backPlatedCopperPolys ) @@ -302,8 +300,6 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) if( cfg.DifferentiatePlatedCopper() ) { - m_frontPlatedPadAndGraphicPolys = new SHAPE_POLY_SET; - m_backPlatedPadAndGraphicPolys = new SHAPE_POLY_SET; m_frontPlatedCopperPolys = new SHAPE_POLY_SET; m_backPlatedCopperPolys = new SHAPE_POLY_SET; @@ -614,10 +610,19 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) // ADD PADS for( FOOTPRINT* footprint : m_board->Footprints() ) { - addPads( footprint, layerContainer, layer, cfg.DifferentiatePlatedCopper(), false ); - - // Micro-wave footprints may have items on copper layers + addPads( footprint, layerContainer, layer ); 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 // its hole footprint->TransformPadsToPolySet( *layerPoly, layer, 0, maxError, ERROR_INSIDE, - true, cfg.DifferentiatePlatedCopper(), false ); + true ); 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 @@ -702,36 +694,29 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) } // 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 - // 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 + SHAPE_POLY_SET* copperPolys = layer == F_Cu ? m_frontPlatedCopperPolys : m_backPlatedCopperPolys; - if( item->Type() == PCB_TEXTBOX_T ) - { - PCB_TEXTBOX* text_box = static_cast<PCB_TEXTBOX*>( item ); - text_box->TransformTextToPolySet( *platedCopperPolys, - 0, maxError, ERROR_INSIDE ); - // Add box outlines - text_box->PCB_SHAPE::TransformShapeToPolygon( *platedCopperPolys, layer, - 0, maxError, ERROR_INSIDE ); - } - else if( item->Type() == PCB_TEXT_T ) - { - static_cast<PCB_TEXT*>( item )->TransformTextToPolySet( *platedCopperPolys, - 0, maxError, - ERROR_INSIDE ); - } - else - { - item->TransformShapeToPolySet( *platedCopperPolys, layer, 0, maxError, - ERROR_INSIDE ); - } + // Note: for TEXT and TEXTBOX, TransformShapeToPolygon returns the bounding + // box shape, not the exact text shape. So it is not used for these items + if( item->Type() == PCB_TEXTBOX_T ) + { + PCB_TEXTBOX* text_box = static_cast<PCB_TEXTBOX*>( item ); + text_box->TransformTextToPolySet( *copperPolys, 0, maxError, ERROR_INSIDE ); + // Add box outlines + text_box->PCB_SHAPE::TransformShapeToPolygon( *copperPolys, layer, 0, maxError, + ERROR_INSIDE ); + } + else if( item->Type() == PCB_TEXT_T ) + { + PCB_TEXT* text = static_cast<PCB_TEXT*>( item ); + text->TransformTextToPolySet( *copperPolys, 0, maxError, ERROR_INSIDE ); + } + else + { + item->TransformShapeToPolySet( *copperPolys, layer, 0, maxError, ERROR_INSIDE ); } } } @@ -770,13 +755,32 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) { 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 ); break; } 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; + } default: wxLogTrace( m_logTrace, wxT( "createLayers: item type: %d not implemented" ), @@ -1042,7 +1046,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) } else { - addPads( footprint, layerContainer, layer, false, false ); + addPads( footprint, layerContainer, layer ); } addFootprintShapes( footprint, layerContainer, layer, visibilityFlags ); @@ -1088,13 +1092,33 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) { 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 ); break; } 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; + } default: break; @@ -1172,9 +1196,9 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) if( !footprint->GetBoundingBox().Intersects( boardBBox ) ) { if( footprint->IsFlipped() ) - addPads( footprint, m_offboardPadsBack, B_Cu, false, false ); + addPads( footprint, m_offboardPadsBack, B_Cu ); 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 ) ); // 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() ) - { - m_layers_poly[F_Cu]->BooleanSubtract( *m_frontPlatedPadAndGraphicPolys ); m_layers_poly[F_Cu]->BooleanSubtract( *m_frontPlatedCopperPolys ); - hasF_Cu = true; - } 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 ); - 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 ConvertPolygonToTriangles( *m_frontPlatedCopperPolys, *m_platedPadsFront, m_biuTo3Dunits, diff --git a/3d-viewer/3d_rendering/opengl/create_scene.cpp b/3d-viewer/3d_rendering/opengl/create_scene.cpp index c9dd977017..31a1ac759a 100644 --- a/3d-viewer/3d_rendering/opengl/create_scene.cpp +++ b/3d-viewer/3d_rendering/opengl/create_scene.cpp @@ -607,14 +607,12 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo if( m_boardAdapter.m_Cfg->m_Render.DifferentiatePlatedCopper() ) { - const SHAPE_POLY_SET* frontPlatedPadAndGraphicPolys = - m_boardAdapter.GetFrontPlatedPadAndGraphicPolys(); - const SHAPE_POLY_SET* backPlatedPadAndGraphicPolys = - m_boardAdapter.GetBackPlatedPadAndGraphicPolys(); + const SHAPE_POLY_SET* frontPlatedCopperPolys = m_boardAdapter.GetFrontPlatedCopperPolys(); + const SHAPE_POLY_SET* backPlatedCopperPolys = m_boardAdapter.GetBackPlatedCopperPolys(); - if( frontPlatedPadAndGraphicPolys ) + if( frontPlatedCopperPolys ) { - SHAPE_POLY_SET poly = frontPlatedPadAndGraphicPolys->CloneDropTriangulation(); + SHAPE_POLY_SET poly = frontPlatedCopperPolys->CloneDropTriangulation(); poly.BooleanIntersection( m_boardAdapter.GetBoardPoly() ); poly.BooleanSubtract( m_boardAdapter.GetTH_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 ); } - if( backPlatedPadAndGraphicPolys ) + if( backPlatedCopperPolys ) { - SHAPE_POLY_SET poly = backPlatedPadAndGraphicPolys->CloneDropTriangulation(); + SHAPE_POLY_SET poly = backPlatedCopperPolys->CloneDropTriangulation(); poly.BooleanIntersection( m_boardAdapter.GetBoardPoly() ); poly.BooleanSubtract( m_boardAdapter.GetTH_ODPolys() ); poly.BooleanSubtract( m_boardAdapter.GetNPTH_ODPolys() ); diff --git a/pcbnew/exporters/step/exporter_step.cpp b/pcbnew/exporters/step/exporter_step.cpp index 0934de7a41..2a4c6d13b1 100644 --- a/pcbnew/exporters/step/exporter_step.cpp +++ b/pcbnew/exporters/step/exporter_step.cpp @@ -29,6 +29,8 @@ #include <board_design_settings.h> #include <footprint.h> #include <pcb_textbox.h> +#include <pcb_table.h> +#include <pcb_tablecell.h> #include <pcb_track.h> #include <pcb_shape.h> #include <pad.h> @@ -545,8 +547,22 @@ bool EXPORTER_STEP::buildGraphic3DShape( BOARD_ITEM* aItem, VECTOR2D aOrigin ) } 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; + } default: wxFAIL_MSG( "buildGraphic3DShape: unhandled item type" ); } diff --git a/pcbnew/footprint.cpp b/pcbnew/footprint.cpp index c9d4c90e25..578e7ae0ef 100644 --- a/pcbnew/footprint.cpp +++ b/pcbnew/footprint.cpp @@ -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, int aClearance, int aMaxError, ERROR_LOC aErrorLoc, - bool aSkipNPTHPadsWihNoCopper, bool aSkipPlatedPads, - bool aSkipNonPlatedPads ) const + bool aSkipNPTHPadsWihNoCopper ) const { auto processPad = [&]( const PAD* pad, PCB_LAYER_ID padLayer ) @@ -3862,24 +3861,6 @@ void FOOTPRINT::TransformPadsToPolySet( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aL 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 B_Mask: clearance.x += pad->GetSolderMaskExpansion( padLayer ); diff --git a/pcbnew/footprint.h b/pcbnew/footprint.h index 26bdea21d9..5a3161e15c 100644 --- a/pcbnew/footprint.h +++ b/pcbnew/footprint.h @@ -539,14 +539,10 @@ public: * 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 * 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, int aMaxError, ERROR_LOC aErrorLoc, - bool aSkipNPTHPadsWihNoCopper = false, - bool aSkipPlatedPads = false, - bool aSkipNonPlatedPads = false ) const; + bool aSkipNPTHPadsWihNoCopper = false ) const; /** * Generate shapes of graphic items (outlines) on layer \a aLayer as polygons and adds these