From c1a988e3ffa937b23fdc26178e633710e82ac04f Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Fri, 22 Sep 2023 18:31:04 +0100 Subject: [PATCH] Handle plated vs non-plated copper for copper other than pads. Fixes https://gitlab.com/kicad/code/kicad/-/issues/5569 --- 3d-viewer/3d_canvas/board_adapter.cpp | 2 + 3d-viewer/3d_canvas/board_adapter.h | 2 + 3d-viewer/3d_canvas/create_layer_items.cpp | 662 ++++++++++-------- .../3d_rendering/opengl/create_scene.cpp | 79 +-- .../3d_rendering/opengl/render_3d_opengl.cpp | 2 +- .../3d_rendering/raytracing/create_scene.cpp | 4 +- .../3d_viewer/eda_3d_viewer_settings.cpp | 2 +- 3d-viewer/3d_viewer/eda_3d_viewer_settings.h | 3 +- .../dialogs/panel_3D_display_options.cpp | 4 +- 9 files changed, 406 insertions(+), 354 deletions(-) diff --git a/3d-viewer/3d_canvas/board_adapter.cpp b/3d-viewer/3d_canvas/board_adapter.cpp index 24c122ca89..8a64216cde 100644 --- a/3d-viewer/3d_canvas/board_adapter.cpp +++ b/3d-viewer/3d_canvas/board_adapter.cpp @@ -143,6 +143,8 @@ BOARD_ADAPTER::BOARD_ADAPTER() : m_frontPlatedPadPolys = nullptr; m_backPlatedPadPolys = nullptr; + m_frontPlatedCopperPolys = nullptr; + m_backPlatedCopperPolys = nullptr; if( !g_ColorsLoaded ) { diff --git a/3d-viewer/3d_canvas/board_adapter.h b/3d-viewer/3d_canvas/board_adapter.h index 8289514fcb..fdb8cd684c 100644 --- a/3d-viewer/3d_canvas/board_adapter.h +++ b/3d-viewer/3d_canvas/board_adapter.h @@ -434,6 +434,8 @@ private: SHAPE_POLY_SET* m_frontPlatedPadPolys; SHAPE_POLY_SET* m_backPlatedPadPolys; + SHAPE_POLY_SET* m_frontPlatedCopperPolys; + SHAPE_POLY_SET* m_backPlatedCopperPolys; MAP_POLY m_layerHoleOdPolys; ///< Hole outer diameters (per layer) MAP_POLY m_layerHoleIdPolys; ///< Hole inner diameters (per layer) diff --git a/3d-viewer/3d_canvas/create_layer_items.cpp b/3d-viewer/3d_canvas/create_layer_items.cpp index 3c0a1e9bb3..c51dd272fe 100644 --- a/3d-viewer/3d_canvas/create_layer_items.cpp +++ b/3d-viewer/3d_canvas/create_layer_items.cpp @@ -34,6 +34,7 @@ #include "board_adapter.h" #include "../3d_rendering/raytracing/shapes2D/filled_circle_2d.h" +#include "raytracing/shapes2D/triangle_2d.h" #include #include #include @@ -118,6 +119,8 @@ void BOARD_ADAPTER::destroyLayers() DELETE_AND_FREE( m_frontPlatedPadPolys ) DELETE_AND_FREE( m_backPlatedPadPolys ) + DELETE_AND_FREE( m_frontPlatedCopperPolys ) + DELETE_AND_FREE( m_backPlatedCopperPolys ) DELETE_AND_FREE_MAP( m_layerHoleOdPolys ) DELETE_AND_FREE_MAP( m_layerHoleIdPolys ) @@ -234,10 +237,12 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) } } - if( cfg.renderPlatedPadsAsPlated ) + if( cfg.differentiate_plated_copper ) { m_frontPlatedPadPolys = new SHAPE_POLY_SET; m_backPlatedPadPolys = new SHAPE_POLY_SET; + m_frontPlatedCopperPolys = new SHAPE_POLY_SET; + m_backPlatedCopperPolys = new SHAPE_POLY_SET; m_platedPadsFront = new BVH_CONTAINER_2D; m_platedPadsBack = new BVH_CONTAINER_2D; @@ -339,6 +344,17 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) m_TH_IDs.Add( new FILLED_CIRCLE_2D( via_center, hole_inner_radius, *track ) ); } } + + if( cfg.differentiate_plated_copper && layer == F_Cu ) + { + track->TransformShapeToPolygon( *m_frontPlatedCopperPolys, F_Cu, 0, maxError, + ERROR_INSIDE ); + } + else if( cfg.differentiate_plated_copper && layer == B_Cu ) + { + track->TransformShapeToPolygon( *m_backPlatedCopperPolys, B_Cu, 0, maxError, + ERROR_INSIDE ); + } } } @@ -529,26 +545,13 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) // ADD PADS for( FOOTPRINT* footprint : m_board->Footprints() ) { - addPads( footprint, layerContainer, layer, cfg.renderPlatedPadsAsPlated, false ); + addPads( footprint, layerContainer, layer, cfg.differentiate_plated_copper, false ); // Micro-wave footprints may have items on copper layers addFootprintShapes( footprint, layerContainer, layer, visibilityFlags ); } } - if( cfg.renderPlatedPadsAsPlated ) - { - // 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 ); - } - - m_platedPadsFront->BuildBVH(); - m_platedPadsBack->BuildBVH(); - } - // Add footprints PADs poly contours (vertical outlines) if( cfg.opengl_copper_thickness && cfg.engine == RENDER_ENGINE::OPENGL ) { @@ -564,13 +567,13 @@ 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.renderPlatedPadsAsPlated, false ); + true, cfg.differentiate_plated_copper, false ); transformFPShapesToPolySet( footprint, layer, *layerPoly, maxError, ERROR_INSIDE ); } } - if( cfg.renderPlatedPadsAsPlated ) + if( cfg.differentiate_plated_copper ) { // ADD PLATED PADS contours for( FOOTPRINT* footprint : m_board->Footprints() ) @@ -688,6 +691,17 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) { zones.emplace_back( std::make_pair( zone, layer ) ); layer_lock.emplace( layer, std::make_unique() ); + + if( cfg.differentiate_plated_copper && layer == F_Cu ) + { + zone->TransformShapeToPolygon( *m_frontPlatedCopperPolys, F_Cu, 0, maxError, + ERROR_INSIDE ); + } + else if( cfg.differentiate_plated_copper && layer == B_Cu ) + { + zone->TransformShapeToPolygon( *m_backPlatedCopperPolys, B_Cu, 0, maxError, + ERROR_INSIDE ); + } } } @@ -737,45 +751,339 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) while( threadsFinished < parallelThreadCount ) std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) ); - } + // End Build Copper layers + + // This will make a union of all added contours + m_TH_ODPolys.Simplify( SHAPE_POLY_SET::PM_FAST ); + m_NPTH_ODPolys.Simplify( SHAPE_POLY_SET::PM_FAST ); + m_viaTH_ODPolys.Simplify( SHAPE_POLY_SET::PM_FAST ); + m_viaAnnuliPolys.Simplify( SHAPE_POLY_SET::PM_FAST ); + + // Build Tech layers + // Based on: + // https://github.com/KiCad/kicad-source-mirror/blob/master/3d-viewer/3d_draw.cpp#L1059 + if( aStatusReporter ) + aStatusReporter->Report( _( "Build Tech layers" ) ); + + // draw graphic items, on technical layers + + static const PCB_LAYER_ID techLayerList[] = { + B_Adhes, + F_Adhes, + B_Paste, + F_Paste, + B_SilkS, + F_SilkS, + B_Mask, + F_Mask, + + // Aux Layers + Dwgs_User, + Cmts_User, + Eco1_User, + Eco2_User + }; + + std::bitset enabledFlags = visibilityFlags; + + if( cfg.subtract_mask_from_silk || cfg.differentiate_plated_copper ) + { + enabledFlags.set( LAYER_3D_SOLDERMASK_TOP ); + enabledFlags.set( LAYER_3D_SOLDERMASK_BOTTOM ); + } + + for( PCB_LAYER_ID layer : LSET::AllNonCuMask().Seq( techLayerList, arrayDim( techLayerList ) ) ) + { + if( aStatusReporter ) + aStatusReporter->Report( wxString::Format( _( "Build Tech layer %d" ), (int) layer ) ); + + if( !Is3dLayerEnabled( layer, enabledFlags ) ) + continue; + + BVH_CONTAINER_2D *layerContainer = new BVH_CONTAINER_2D; + m_layerMap[layer] = layerContainer; + + SHAPE_POLY_SET *layerPoly = new SHAPE_POLY_SET; + m_layers_poly[layer] = layerPoly; + + if( Is3dLayerEnabled( layer, visibilityFlags ) ) + { + // Add drawing objects + for( BOARD_ITEM* item : m_board->Drawings() ) + { + if( !item->IsOnLayer( layer ) ) + continue; + + switch( item->Type() ) + { + case PCB_SHAPE_T: + addShape( static_cast( item ), layerContainer, item ); + break; + + case PCB_TEXT_T: + addText( static_cast( item ), layerContainer, item ); + break; + + case PCB_TEXTBOX_T: + addText( static_cast( item ), layerContainer, item ); + + if( static_cast( item )->IsBorderEnabled() ) + addShape( static_cast( item ), layerContainer, 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: + addShape( static_cast( item ), layerContainer, item ); + break; + + default: + break; + } + } + + // Add via tech layers + if( ( layer == F_Mask || layer == B_Mask ) && !m_board->GetTentVias() ) + { + int maskExpansion = GetBoard()->GetDesignSettings().m_SolderMaskExpansion; + + for( PCB_TRACK* track : m_board->Tracks() ) + { + if( track->Type() == PCB_VIA_T + && static_cast( track )->FlashLayer( layer ) ) + { + createViaWithMargin( track, layerContainer, maskExpansion ); + } + } + } + + // Add footprints tech layers - objects + for( FOOTPRINT* footprint : m_board->Footprints() ) + { + if( layer == F_SilkS || layer == B_SilkS ) + { + int linewidth = m_board->GetDesignSettings().m_LineThickness[ LAYER_CLASS_SILK ]; + + for( PAD* pad : footprint->Pads() ) + { + if( !pad->IsOnLayer( layer ) ) + continue; + + buildPadOutlineAsSegments( pad, layerContainer, linewidth ); + } + } + else + { + addPads( footprint, layerContainer, layer, false, false ); + } + + addFootprintShapes( footprint, layerContainer, layer, visibilityFlags ); + } + + // Draw non copper zones + if( cfg.show_zones ) + { + for( ZONE* zone : m_board->Zones() ) + { + if( zone->IsOnLayer( layer ) ) + addSolidAreasShapes( zone, layerContainer, layer ); + } + } + } + + // Add item contours. We need these if we're building vertical walls or if this is a + // mask layer and we're differentiating copper from plated copper. + if( ( cfg.engine == RENDER_ENGINE::OPENGL && cfg.opengl_copper_thickness ) + || ( cfg.differentiate_plated_copper && ( layer == F_Mask || layer == B_Mask ) ) ) + { + // DRAWINGS + for( BOARD_ITEM* item : m_board->Drawings() ) + { + if( !item->IsOnLayer( layer ) ) + continue; + + switch( item->Type() ) + { + case PCB_SHAPE_T: + item->TransformShapeToPolygon( *layerPoly, layer, 0, maxError, ERROR_INSIDE ); + break; + + case PCB_TEXT_T: + { + PCB_TEXT* text = static_cast( item ); + + text->TransformTextToPolySet( *layerPoly, 0, maxError, ERROR_INSIDE ); + break; + } + + case PCB_TEXTBOX_T: + { + PCB_TEXTBOX* textbox = static_cast( item ); + + textbox->TransformTextToPolySet( *layerPoly, 0, maxError, ERROR_INSIDE ); + break; + } + + default: + break; + } + } + + // NON-TENTED VIAS + if( ( layer == F_Mask || layer == B_Mask ) && !m_board->GetTentVias() ) + { + int maskExpansion = GetBoard()->GetDesignSettings().m_SolderMaskExpansion; + + for( PCB_TRACK* track : m_board->Tracks() ) + { + if( track->Type() == PCB_VIA_T + && static_cast( track )->FlashLayer( layer ) ) + { + track->TransformShapeToPolygon( *layerPoly, layer, maskExpansion, maxError, + ERROR_INSIDE ); + } + } + } + + // FOOTPRINT CHILDREN + for( FOOTPRINT* footprint : m_board->Footprints() ) + { + if( layer == F_SilkS || layer == B_SilkS ) + { + int linewidth = m_board->GetDesignSettings().m_LineThickness[ LAYER_CLASS_SILK ]; + + for( PAD* pad : footprint->Pads() ) + { + if( pad->IsOnLayer( layer ) ) + { + buildPadOutlineAsPolygon( pad, *layerPoly, linewidth, maxError, + ERROR_INSIDE ); + } + } + } + else + { + footprint->TransformPadsToPolySet( *layerPoly, layer, 0, maxError, ERROR_INSIDE ); + } + + // On tech layers, use a poor circle approximation, only for texts (stroke font) + footprint->TransformFPTextToPolySet( *layerPoly, layer, 0, maxError, ERROR_INSIDE ); + + // Add the remaining things with dynamic seg count for circles + transformFPShapesToPolySet( footprint, layer, *layerPoly, maxError, ERROR_INSIDE ); + } + + if( cfg.show_zones || layer == F_Mask || layer == B_Mask ) + { + for( ZONE* zone : m_board->Zones() ) + { + if( zone->IsOnLayer( layer ) ) + zone->TransformSolidAreasShapesToPolygon( layer, *layerPoly ); + } + } + + // This will make a union of all added contours + layerPoly->Simplify( SHAPE_POLY_SET::PM_FAST ); + } + } + // End Build Tech layers + +#if 1 + // A somewhat experimental feature: if we're rendering off-board silk, turn any pads of + // footprints which are entirely outside the board outline into silk. This makes off-board + // footprints more visually recognizable. + if( cfg.show_off_board_silk ) + { + BOX2I boardBBox = m_board_poly.BBox(); + + for( FOOTPRINT* footprint : m_board->Footprints() ) + { + if( !footprint->GetBoundingBox().Intersects( boardBBox ) ) + { + if( footprint->IsFlipped() ) + { + BVH_CONTAINER_2D *layerContainer = m_layerMap[ B_SilkS ]; + addPads( footprint, layerContainer, B_Cu, false, false ); + } + else + { + BVH_CONTAINER_2D *layerContainer = m_layerMap[ F_SilkS ]; + addPads( footprint, layerContainer, F_Cu, false, false ); + } + } + } + } +#endif // Simplify layer polygons if( aStatusReporter ) - aStatusReporter->Report( _( "Simplifying copper layers polygons" ) ); + aStatusReporter->Report( _( "Simplifying copper layer polygons" ) ); + + if( cfg.differentiate_plated_copper ) + { + if( aStatusReporter ) + aStatusReporter->Report( _( "Calculating plated copper" ) ); + + // TRIM PLATED COPPER TO SOLDERMASK + if( m_layers_poly.find( F_Mask ) != m_layers_poly.end() ) + { + m_frontPlatedCopperPolys->BooleanIntersection( *m_layers_poly.at( F_Mask ), + SHAPE_POLY_SET::PM_FAST ); + } + + if( m_layers_poly.find( B_Mask ) != m_layers_poly.end() ) + { + m_backPlatedCopperPolys->BooleanIntersection( *m_layers_poly.at( B_Mask ), + SHAPE_POLY_SET::PM_FAST ); + } + + // SUBTRACT PLATED COPPER FROM (UNPLATED) COPPER + if( m_layers_poly.find( F_Cu ) != m_layers_poly.end() ) + { + m_layers_poly[F_Cu]->BooleanSubtract( *m_frontPlatedPadPolys, SHAPE_POLY_SET::PM_FAST ); + m_layers_poly[F_Cu]->BooleanSubtract( *m_frontPlatedCopperPolys, SHAPE_POLY_SET::PM_FAST ); + } + + if( m_layers_poly.find( B_Cu ) != m_layers_poly.end() ) + { + m_layers_poly[B_Cu]->BooleanSubtract( *m_backPlatedPadPolys, SHAPE_POLY_SET::PM_FAST ); + m_layers_poly[B_Cu]->BooleanSubtract( *m_backPlatedCopperPolys, SHAPE_POLY_SET::PM_FAST ); + } + + m_frontPlatedPadPolys->Simplify( SHAPE_POLY_SET::PM_FAST ); + m_backPlatedPadPolys->Simplify( SHAPE_POLY_SET::PM_FAST ); + m_frontPlatedCopperPolys->Simplify( SHAPE_POLY_SET::PM_FAST ); + m_backPlatedCopperPolys->Simplify( SHAPE_POLY_SET::PM_FAST ); + + // 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, + *m_board->GetItem( niluuid ) ); + + ConvertPolygonToTriangles( *m_backPlatedCopperPolys, *m_platedPadsBack, m_biuTo3Dunits, + *m_board->GetItem( niluuid ) ); + + m_platedPadsFront->BuildBVH(); + m_platedPadsBack->BuildBVH(); + } if( cfg.opengl_copper_thickness && cfg.engine == RENDER_ENGINE::OPENGL ) { - if( cfg.renderPlatedPadsAsPlated ) - { - if( m_frontPlatedPadPolys && ( m_layers_poly.find( F_Cu ) != m_layers_poly.end() ) ) - { - if( aStatusReporter ) - aStatusReporter->Report( _( "Simplifying polygons on F_Cu" ) ); - - SHAPE_POLY_SET *layerPoly_F_Cu = m_layers_poly[F_Cu]; - layerPoly_F_Cu->BooleanSubtract( *m_frontPlatedPadPolys, SHAPE_POLY_SET::PM_FAST ); - - m_frontPlatedPadPolys->Simplify( SHAPE_POLY_SET::PM_FAST ); - } - - if( m_backPlatedPadPolys && ( m_layers_poly.find( B_Cu ) != m_layers_poly.end() ) ) - { - if( aStatusReporter ) - aStatusReporter->Report( _( "Simplifying polygons on B_Cu" ) ); - - SHAPE_POLY_SET *layerPoly_B_Cu = m_layers_poly[B_Cu]; - layerPoly_B_Cu->BooleanSubtract( *m_backPlatedPadPolys, SHAPE_POLY_SET::PM_FAST ); - - m_backPlatedPadPolys->Simplify( SHAPE_POLY_SET::PM_FAST ); - } - } - std::vector &selected_layer_id = layer_ids; std::vector layer_id_without_F_and_B; - if( cfg.renderPlatedPadsAsPlated ) + if( cfg.differentiate_plated_copper ) { layer_id_without_F_and_B.clear(); layer_id_without_F_and_B.reserve( layer_ids.size() ); @@ -816,8 +1124,10 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) auto layerPoly = m_layers_poly.find( selected_layer_id[i] ); if( layerPoly != m_layers_poly.end() ) + { // This will make a union of all added contours layerPoly->second->Simplify( SHAPE_POLY_SET::PM_FAST ); + } } threadsFinished++; @@ -850,268 +1160,6 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) } } - // End Build Copper layers - - // This will make a union of all added contours - m_TH_ODPolys.Simplify( SHAPE_POLY_SET::PM_FAST ); - m_NPTH_ODPolys.Simplify( SHAPE_POLY_SET::PM_FAST ); - m_viaTH_ODPolys.Simplify( SHAPE_POLY_SET::PM_FAST ); - m_viaAnnuliPolys.Simplify( SHAPE_POLY_SET::PM_FAST ); - - // Build Tech layers - // Based on: - // https://github.com/KiCad/kicad-source-mirror/blob/master/3d-viewer/3d_draw.cpp#L1059 - if( aStatusReporter ) - aStatusReporter->Report( _( "Build Tech layers" ) ); - - // draw graphic items, on technical layers - - // Vertical walls (layer thickness) around shapes is really time consumming - // They are built on request - bool buildVerticalWallsForTechLayers = cfg.opengl_copper_thickness - && cfg.engine == RENDER_ENGINE::OPENGL; - - static const PCB_LAYER_ID techLayerList[] = { - B_Adhes, - F_Adhes, - B_Paste, - F_Paste, - B_SilkS, - F_SilkS, - B_Mask, - F_Mask, - - // Aux Layers - Dwgs_User, - Cmts_User, - Eco1_User, - Eco2_User - }; - - for( LSEQ seq = LSET::AllNonCuMask().Seq( techLayerList, arrayDim( techLayerList ) ); - seq; - ++seq ) - { - const PCB_LAYER_ID layer = *seq; - - if( !Is3dLayerEnabled( layer, visibilityFlags ) ) - continue; - - if( aStatusReporter ) - aStatusReporter->Report( wxString::Format( _( "Build Tech layer %d" ), (int) layer ) ); - - BVH_CONTAINER_2D *layerContainer = new BVH_CONTAINER_2D; - m_layerMap[layer] = layerContainer; - - SHAPE_POLY_SET *layerPoly = new SHAPE_POLY_SET; - m_layers_poly[layer] = layerPoly; - - // Add drawing objects - for( BOARD_ITEM* item : m_board->Drawings() ) - { - if( !item->IsOnLayer( layer ) ) - continue; - - switch( item->Type() ) - { - case PCB_SHAPE_T: - addShape( static_cast( item ), layerContainer, item ); - break; - - case PCB_TEXT_T: - addText( static_cast( item ), layerContainer, item ); - break; - - case PCB_TEXTBOX_T: - addText( static_cast( item ), layerContainer, item ); - if( static_cast( item )->IsBorderEnabled() ) - addShape( static_cast( item ), layerContainer, 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: - addShape( static_cast( item ), layerContainer, item ); - break; - - default: - break; - } - } - - // Add drawing contours (vertical walls) - if( buildVerticalWallsForTechLayers ) - { - for( BOARD_ITEM* item : m_board->Drawings() ) - { - if( !item->IsOnLayer( layer ) ) - continue; - - switch( item->Type() ) - { - case PCB_SHAPE_T: - item->TransformShapeToPolygon( *layerPoly, layer, 0, maxError, ERROR_INSIDE ); - break; - - case PCB_TEXT_T: - { - PCB_TEXT* text = static_cast( item ); - - text->TransformTextToPolySet( *layerPoly, 0, maxError, ERROR_INSIDE ); - break; - } - - case PCB_TEXTBOX_T: - { - PCB_TEXTBOX* textbox = static_cast( item ); - - textbox->TransformTextToPolySet( *layerPoly, 0, maxError, ERROR_INSIDE ); - break; - } - - default: - break; - } - } - } - - // Add via tech layers - if( ( layer == F_Mask || layer == B_Mask ) && !m_board->GetTentVias() ) - { - int maskExpansion = GetBoard()->GetDesignSettings().m_SolderMaskExpansion; - - for( PCB_TRACK* track : m_board->Tracks() ) - { - if( track->Type() == PCB_VIA_T - && static_cast( track )->FlashLayer( layer ) ) - { - createViaWithMargin( track, layerContainer, maskExpansion ); - } - } - - // Add via tech layers - contours (vertical walls) - if( buildVerticalWallsForTechLayers ) - { - for( PCB_TRACK* track : m_board->Tracks() ) - { - if( track->Type() == PCB_VIA_T - && static_cast( track )->FlashLayer( layer ) ) - { - track->TransformShapeToPolygon( *layerPoly, layer, maskExpansion, maxError, - ERROR_INSIDE ); - } - } - } - } - - // Add footprints tech layers - objects - for( FOOTPRINT* footprint : m_board->Footprints() ) - { - if( layer == F_SilkS || layer == B_SilkS ) - { - int linewidth = m_board->GetDesignSettings().m_LineThickness[ LAYER_CLASS_SILK ]; - - for( PAD* pad : footprint->Pads() ) - { - if( !pad->IsOnLayer( layer ) ) - continue; - - buildPadOutlineAsSegments( pad, layerContainer, linewidth ); - } - } - else - { - addPads( footprint, layerContainer, layer, false, false ); - } - - addFootprintShapes( footprint, layerContainer, layer, visibilityFlags ); - } - - - // Add footprints tech layers - contours (vertical walls) - if( buildVerticalWallsForTechLayers ) - { - for( FOOTPRINT* footprint : m_board->Footprints() ) - { - if( layer == F_SilkS || layer == B_SilkS ) - { - int linewidth = m_board->GetDesignSettings().m_LineThickness[ LAYER_CLASS_SILK ]; - - for( PAD* pad : footprint->Pads() ) - { - if( pad->IsOnLayer( layer ) ) - { - buildPadOutlineAsPolygon( pad, *layerPoly, linewidth, maxError, - ERROR_INSIDE ); - } - } - } - else - { - footprint->TransformPadsToPolySet( *layerPoly, layer, 0, maxError, ERROR_INSIDE ); - } - - // On tech layers, use a poor circle approximation, only for texts (stroke font) - footprint->TransformFPTextToPolySet( *layerPoly, layer, 0, maxError, ERROR_INSIDE ); - - // Add the remaining things with dynamic seg count for circles - transformFPShapesToPolySet( footprint, layer, *layerPoly, maxError, ERROR_INSIDE ); - } - } - - // Draw non copper zones - if( cfg.show_zones ) - { - for( ZONE* zone : m_board->Zones() ) - { - if( zone->IsOnLayer( layer ) ) - addSolidAreasShapes( zone, layerContainer, layer ); - } - - if( buildVerticalWallsForTechLayers ) - { - for( ZONE* zone : m_board->Zones() ) - { - if( zone->IsOnLayer( layer ) ) - zone->TransformSolidAreasShapesToPolygon( layer, *layerPoly ); - } - } - } - - // This will make a union of all added contours - layerPoly->Simplify( SHAPE_POLY_SET::PM_FAST ); - } - // End Build Tech layers - -#if 1 - // A somewhat experimental feature: if we're rendering off-board silk, turn any pads of - // footprints which are entirely outside the board outline into silk. This makes off-board - // footprints more visually recognizable. - if( cfg.show_off_board_silk ) - { - BOX2I boardBBox = m_board_poly.BBox(); - - for( FOOTPRINT* footprint : m_board->Footprints() ) - { - if( !footprint->GetBoundingBox().Intersects( boardBBox ) ) - { - if( footprint->IsFlipped() ) - { - BVH_CONTAINER_2D *layerContainer = m_layerMap[ B_SilkS ]; - addPads( footprint, layerContainer, B_Cu, false, false ); - } - else - { - BVH_CONTAINER_2D *layerContainer = m_layerMap[ F_SilkS ]; - addPads( footprint, layerContainer, F_Cu, false, false ); - } - } - } - } -#endif - // Build BVH (Bounding volume hierarchy) for holes and vias if( aStatusReporter ) diff --git a/3d-viewer/3d_rendering/opengl/create_scene.cpp b/3d-viewer/3d_rendering/opengl/create_scene.cpp index 0f19e1d4a4..81a9ca4ed7 100644 --- a/3d-viewer/3d_rendering/opengl/create_scene.cpp +++ b/3d-viewer/3d_rendering/opengl/create_scene.cpp @@ -565,39 +565,42 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo // Load the vertical (Z axis) component of shapes - if( map_poly.find( layer ) != map_poly.end() ) + if( m_boardAdapter.m_Cfg->m_Render.opengl_copper_thickness ) { - polyListSubtracted = *map_poly.at( layer ); - - if( LSET::PhysicalLayersMask().test( layer ) ) + if( map_poly.find( layer ) != map_poly.end() ) { - polyListSubtracted.BooleanIntersection( m_boardAdapter.GetBoardPoly(), - SHAPE_POLY_SET::PM_FAST ); - } + polyListSubtracted = *map_poly.at( layer ); - if( layer != B_Mask && layer != F_Mask ) - { - polyListSubtracted.BooleanSubtract( m_boardAdapter.GetTH_ODPolys(), - SHAPE_POLY_SET::PM_FAST ); - polyListSubtracted.BooleanSubtract( m_boardAdapter.GetNPTH_ODPolys(), - SHAPE_POLY_SET::PM_FAST ); - } - - if( m_boardAdapter.m_Cfg->m_Render.subtract_mask_from_silk ) - { - if( layer == B_SilkS && map_poly.find( B_Mask ) != map_poly.end() ) + if( LSET::PhysicalLayersMask().test( layer ) ) { - polyListSubtracted.BooleanSubtract( *map_poly.at( B_Mask ), + polyListSubtracted.BooleanIntersection( m_boardAdapter.GetBoardPoly(), + SHAPE_POLY_SET::PM_FAST ); + } + + if( layer != B_Mask && layer != F_Mask ) + { + polyListSubtracted.BooleanSubtract( m_boardAdapter.GetTH_ODPolys(), + SHAPE_POLY_SET::PM_FAST ); + polyListSubtracted.BooleanSubtract( m_boardAdapter.GetNPTH_ODPolys(), SHAPE_POLY_SET::PM_FAST ); } - else if( layer == F_SilkS && map_poly.find( F_Mask ) != map_poly.end() ) - { - polyListSubtracted.BooleanSubtract( *map_poly.at( F_Mask ), - SHAPE_POLY_SET::PM_FAST ); - } - } - polyList = &polyListSubtracted; + if( m_boardAdapter.m_Cfg->m_Render.subtract_mask_from_silk ) + { + if( layer == B_SilkS && map_poly.find( B_Mask ) != map_poly.end() ) + { + polyListSubtracted.BooleanSubtract( *map_poly.at( B_Mask ), + SHAPE_POLY_SET::PM_FAST ); + } + else if( layer == F_SilkS && map_poly.find( F_Mask ) != map_poly.end() ) + { + polyListSubtracted.BooleanSubtract( *map_poly.at( F_Mask ), + SHAPE_POLY_SET::PM_FAST ); + } + } + + polyList = &polyListSubtracted; + } } OPENGL_RENDER_LIST* oglList = generateLayerList( container2d, polyList, layer, @@ -607,20 +610,19 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo m_layers[layer] = oglList; } - if( m_boardAdapter.m_Cfg->m_Render.renderPlatedPadsAsPlated ) + if( m_boardAdapter.m_Cfg->m_Render.differentiate_plated_copper ) { const SHAPE_POLY_SET* frontPlatedPadPolys = m_boardAdapter.GetFrontPlatedPadPolys(); const SHAPE_POLY_SET* backPlatedPadPolys = m_boardAdapter.GetBackPlatedPadPolys(); if( frontPlatedPadPolys ) { - SHAPE_POLY_SET polySubtracted = frontPlatedPadPolys->CloneDropTriangulation(); - polySubtracted.BooleanIntersection( m_boardAdapter.GetBoardPoly(), SHAPE_POLY_SET::PM_FAST ); - polySubtracted.BooleanSubtract( m_boardAdapter.GetTH_ODPolys(), SHAPE_POLY_SET::PM_FAST ); - polySubtracted.BooleanSubtract( m_boardAdapter.GetNPTH_ODPolys(), SHAPE_POLY_SET::PM_FAST ); + SHAPE_POLY_SET poly = frontPlatedPadPolys->CloneDropTriangulation(); + poly.BooleanIntersection( m_boardAdapter.GetBoardPoly(), SHAPE_POLY_SET::PM_FAST ); + poly.BooleanSubtract( m_boardAdapter.GetTH_ODPolys(), SHAPE_POLY_SET::PM_FAST ); + poly.BooleanSubtract( m_boardAdapter.GetNPTH_ODPolys(), SHAPE_POLY_SET::PM_FAST ); - m_platedPadsFront = generateLayerList( m_boardAdapter.GetPlatedPadsFront(), - &polySubtracted, F_Cu ); + m_platedPadsFront = generateLayerList( m_boardAdapter.GetPlatedPadsFront(), &poly, F_Cu ); // An entry for F_Cu must exist in m_layers or we'll never look at m_platedPadsFront if( m_layers.count( F_Cu ) == 0 ) @@ -629,13 +631,12 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo if( backPlatedPadPolys ) { - SHAPE_POLY_SET polySubtracted = backPlatedPadPolys->CloneDropTriangulation(); - polySubtracted.BooleanIntersection( m_boardAdapter.GetBoardPoly(), SHAPE_POLY_SET::PM_FAST ); - polySubtracted.BooleanSubtract( m_boardAdapter.GetTH_ODPolys(), SHAPE_POLY_SET::PM_FAST ); - polySubtracted.BooleanSubtract( m_boardAdapter.GetNPTH_ODPolys(), SHAPE_POLY_SET::PM_FAST ); + SHAPE_POLY_SET poly = backPlatedPadPolys->CloneDropTriangulation(); + poly.BooleanIntersection( m_boardAdapter.GetBoardPoly(), SHAPE_POLY_SET::PM_FAST ); + poly.BooleanSubtract( m_boardAdapter.GetTH_ODPolys(), SHAPE_POLY_SET::PM_FAST ); + poly.BooleanSubtract( m_boardAdapter.GetNPTH_ODPolys(), SHAPE_POLY_SET::PM_FAST ); - m_platedPadsBack = generateLayerList( m_boardAdapter.GetPlatedPadsBack(), - &polySubtracted, B_Cu ); + m_platedPadsBack = generateLayerList( m_boardAdapter.GetPlatedPadsBack(), &poly, B_Cu ); // An entry for B_Cu must exist in m_layers or we'll never look at m_platedPadsBack if( m_layers.count( B_Cu ) == 0 ) diff --git a/3d-viewer/3d_rendering/opengl/render_3d_opengl.cpp b/3d-viewer/3d_rendering/opengl/render_3d_opengl.cpp index 97dd6601f6..7d583fb0a1 100644 --- a/3d-viewer/3d_rendering/opengl/render_3d_opengl.cpp +++ b/3d-viewer/3d_rendering/opengl/render_3d_opengl.cpp @@ -584,7 +584,7 @@ bool RENDER_3D_OPENGL::Redraw( bool aIsMoving, REPORTER* aStatusReporter, if( isCopperLayer ) { - if( cfg.renderPlatedPadsAsPlated ) + if( cfg.differentiate_plated_copper ) setCopperMaterial(); else setLayerMaterial( layer_id ); diff --git a/3d-viewer/3d_rendering/raytracing/create_scene.cpp b/3d-viewer/3d_rendering/raytracing/create_scene.cpp index 5284593740..cd177dcedd 100644 --- a/3d-viewer/3d_rendering/raytracing/create_scene.cpp +++ b/3d-viewer/3d_rendering/raytracing/create_scene.cpp @@ -625,7 +625,7 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe break; default: - if( m_boardAdapter.m_Cfg->m_Render.renderPlatedPadsAsPlated ) + if( m_boardAdapter.m_Cfg->m_Render.differentiate_plated_copper ) { layerColor = SFVEC3F( 184.0f / 255.0f, 115.0f / 255.0f, 50.0f / 255.0f ); materialLayer = &m_materials.m_NonPlatedCopper; @@ -643,7 +643,7 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe } // for each layer on map // Create plated copper - if( m_boardAdapter.m_Cfg->m_Render.renderPlatedPadsAsPlated ) + if( m_boardAdapter.m_Cfg->m_Render.differentiate_plated_copper ) { createItemsFromContainer( m_boardAdapter.GetPlatedPadsFront(), F_Cu, &m_materials.m_Copper, m_boardAdapter.m_CopperColor, diff --git a/3d-viewer/3d_viewer/eda_3d_viewer_settings.cpp b/3d-viewer/3d_viewer/eda_3d_viewer_settings.cpp index a1f91f9e3d..b1a218d7e8 100644 --- a/3d-viewer/3d_viewer/eda_3d_viewer_settings.cpp +++ b/3d-viewer/3d_viewer/eda_3d_viewer_settings.cpp @@ -367,7 +367,7 @@ EDA_3D_VIEWER_SETTINGS::EDA_3D_VIEWER_SETTINGS() : m_params.emplace_back( new PARAM( "render.clip_silk_on_via_annulus", &m_Render.clip_silk_on_via_annuli, false ) ); m_params.emplace_back( new PARAM( "render.plated_and_bare_copper", - &m_Render.renderPlatedPadsAsPlated, false ) ); + &m_Render.differentiate_plated_copper, false ) ); m_params.emplace_back( new PARAM( "camera.animation_enabled", &m_Camera.animation_enabled, true ) ); m_params.emplace_back( new PARAM( "camera.moving_speed_multiplier", diff --git a/3d-viewer/3d_viewer/eda_3d_viewer_settings.h b/3d-viewer/3d_viewer/eda_3d_viewer_settings.h index f5a83b90fb..12ccca72e7 100644 --- a/3d-viewer/3d_viewer/eda_3d_viewer_settings.h +++ b/3d-viewer/3d_viewer/eda_3d_viewer_settings.h @@ -120,7 +120,6 @@ public: std::vector raytrace_lightElevation; // -90 .. 90 std::vector raytrace_lightAzimuth; // 0 .. 359 - bool realistic; bool show_adhesive; bool show_axis; bool show_board_body; @@ -146,7 +145,7 @@ public: bool show_fp_text; bool subtract_mask_from_silk; bool clip_silk_on_via_annuli; - bool renderPlatedPadsAsPlated; + bool differentiate_plated_copper; }; struct CAMERA_SETTINGS diff --git a/3d-viewer/dialogs/panel_3D_display_options.cpp b/3d-viewer/dialogs/panel_3D_display_options.cpp index 8eda780d3b..b6b14cee8c 100644 --- a/3d-viewer/dialogs/panel_3D_display_options.cpp +++ b/3d-viewer/dialogs/panel_3D_display_options.cpp @@ -49,7 +49,7 @@ void PANEL_3D_DISPLAY_OPTIONS::loadViewSettings( EDA_3D_VIEWER_SETTINGS* aCfg ) m_checkBoxSubtractMaskFromSilk->SetValue( aCfg->m_Render.subtract_mask_from_silk ); m_checkBoxClipSilkOnViaAnnulus->SetValue( aCfg->m_Render.clip_silk_on_via_annuli ); - m_checkBoxRenderPlatedPadsAsPlated->SetValue( aCfg->m_Render.renderPlatedPadsAsPlated ); + m_checkBoxRenderPlatedPadsAsPlated->SetValue( aCfg->m_Render.differentiate_plated_copper ); m_materialProperties->SetSelection( static_cast( aCfg->m_Render.material_mode ) ); @@ -80,7 +80,7 @@ bool PANEL_3D_DISPLAY_OPTIONS::TransferDataFromWindow() cfg->m_Render.show_zones = m_checkBoxAreas->GetValue(); cfg->m_Render.subtract_mask_from_silk = m_checkBoxSubtractMaskFromSilk->GetValue(); cfg->m_Render.clip_silk_on_via_annuli = m_checkBoxClipSilkOnViaAnnulus->GetValue(); - cfg->m_Render.renderPlatedPadsAsPlated = m_checkBoxRenderPlatedPadsAsPlated->GetValue(); + cfg->m_Render.differentiate_plated_copper = m_checkBoxRenderPlatedPadsAsPlated->GetValue(); cfg->m_Render.material_mode = static_cast( m_materialProperties->GetSelection() );