3D viewer: fix some graphic issues:

Avoid issue when a copper layers thickness is 0 (min value is now 1 micrometer)
Fix incorrect rendering of plated graphic items and vias (vertical walls not drawn)
From master branch
This commit is contained in:
jean-pierre charras 2024-03-28 14:52:31 +01:00
parent 92ffd898f5
commit 663e857df6
4 changed files with 48 additions and 31 deletions

View File

@ -3,7 +3,7 @@
*
* Copyright (C) 2015-2023 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2023 CERN
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -142,8 +142,8 @@ BOARD_ADAPTER::BOARD_ADAPTER() :
m_offboardPadsFront = nullptr;
m_offboardPadsBack = nullptr;
m_frontPlatedPadPolys = nullptr;
m_backPlatedPadPolys = nullptr;
m_frontPlatedPadAndGraphicPolys = nullptr;
m_backPlatedPadAndGraphicPolys = nullptr;
m_frontPlatedCopperPolys = nullptr;
m_backPlatedCopperPolys = nullptr;
@ -397,13 +397,18 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR
break;
case BS_ITEM_TYPE_COPPER:
if( item->GetBrdLayerId() == F_Cu )
m_frontCopperThickness3DU = item->GetThickness() * m_biuTo3Dunits;
else if( item->GetBrdLayerId() == B_Cu )
m_backCopperThickness3DU = item->GetThickness() * m_biuTo3Dunits;
else if( item->IsEnabled() )
thickness += item->GetThickness();
{
// The copper thickness must be > 0 to avoid draw issues (divide by 0 for instance)
// We use a minimal arbitrary value = 1 micrometer here:
int copper_thickness = std::max( item->GetThickness(), pcbIUScale.mmToIU( 0.001 ) );
if( item->GetBrdLayerId() == F_Cu )
m_frontCopperThickness3DU = copper_thickness * m_biuTo3Dunits;
else if( item->GetBrdLayerId() == B_Cu )
m_backCopperThickness3DU = copper_thickness * m_biuTo3Dunits;
else if( item->IsEnabled() )
thickness += copper_thickness;
}
break;
default:
@ -449,7 +454,7 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR
for( ; layer < MAX_CU_LAYERS; layer++ )
{
m_layerZcoordBottom[layer] = -( m_boardBodyThickness3DU / 2.0f );
m_layerZcoordTop[layer] = -( m_boardBodyThickness3DU / 2.0f ) - m_backCopperThickness3DU;
m_layerZcoordTop[layer] = m_layerZcoordBottom[layer] - m_backCopperThickness3DU;
}
// This is the top of the copper layer thickness.

View File

@ -331,8 +331,8 @@ public:
*/
const MAP_POLY& GetPolyMap() const noexcept { return m_layers_poly; }
const SHAPE_POLY_SET* GetFrontPlatedPadPolys() { return m_frontPlatedPadPolys; }
const SHAPE_POLY_SET* GetBackPlatedPadPolys() { return m_backPlatedPadPolys; }
const SHAPE_POLY_SET* GetFrontPlatedPadAndGraphicPolys() { return m_frontPlatedPadAndGraphicPolys; }
const SHAPE_POLY_SET* GetBackPlatedPadAndGraphicPolys() { return m_backPlatedPadAndGraphicPolys; }
const MAP_POLY& GetHoleIdPolysMap() const noexcept { return m_layerHoleIdPolys; }
const MAP_POLY& GetHoleOdPolysMap() const noexcept { return m_layerHoleOdPolys; }
@ -438,8 +438,8 @@ private:
MAP_POLY m_layers_poly; ///< Amalgamated polygon contours for various types
///< of items
SHAPE_POLY_SET* m_frontPlatedPadPolys;
SHAPE_POLY_SET* m_backPlatedPadPolys;
SHAPE_POLY_SET* m_frontPlatedPadAndGraphicPolys;
SHAPE_POLY_SET* m_backPlatedPadAndGraphicPolys;
SHAPE_POLY_SET* m_frontPlatedCopperPolys;
SHAPE_POLY_SET* m_backPlatedCopperPolys;

View File

@ -117,8 +117,8 @@ void BOARD_ADAPTER::destroyLayers()
DELETE_AND_FREE_MAP( m_layers_poly );
DELETE_AND_FREE( m_frontPlatedPadPolys )
DELETE_AND_FREE( m_backPlatedPadPolys )
DELETE_AND_FREE( m_frontPlatedPadAndGraphicPolys )
DELETE_AND_FREE( m_backPlatedPadAndGraphicPolys )
DELETE_AND_FREE( m_frontPlatedCopperPolys )
DELETE_AND_FREE( m_backPlatedCopperPolys )
@ -241,8 +241,8 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
if( cfg.differentiate_plated_copper )
{
m_frontPlatedPadPolys = new SHAPE_POLY_SET;
m_backPlatedPadPolys = new SHAPE_POLY_SET;
m_frontPlatedPadAndGraphicPolys = new SHAPE_POLY_SET;
m_backPlatedPadAndGraphicPolys = new SHAPE_POLY_SET;
m_frontPlatedCopperPolys = new SHAPE_POLY_SET;
m_backPlatedCopperPolys = new SHAPE_POLY_SET;
@ -586,10 +586,10 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
// ADD PLATED PADS contours
for( FOOTPRINT* footprint : m_board->Footprints() )
{
footprint->TransformPadsToPolySet( *m_frontPlatedPadPolys, F_Cu, 0, maxError,
footprint->TransformPadsToPolySet( *m_frontPlatedPadAndGraphicPolys, F_Cu, 0, maxError,
ERROR_INSIDE, true, false, true );
footprint->TransformPadsToPolySet( *m_backPlatedPadPolys, B_Cu, 0, maxError,
footprint->TransformPadsToPolySet( *m_backPlatedPadAndGraphicPolys, B_Cu, 0, maxError,
ERROR_INSIDE, true, false, true );
}
}
@ -1050,21 +1050,33 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
SHAPE_POLY_SET::PM_FAST );
}
// 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() )
{
m_layers_poly[F_Cu]->BooleanSubtract( *m_frontPlatedPadPolys, SHAPE_POLY_SET::PM_FAST );
m_layers_poly[F_Cu]->BooleanSubtract( *m_frontPlatedPadAndGraphicPolys, SHAPE_POLY_SET::PM_FAST );
m_layers_poly[F_Cu]->BooleanSubtract( *m_frontPlatedCopperPolys, SHAPE_POLY_SET::PM_FAST );
hasF_Cu = true;
}
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_backPlatedPadAndGraphicPolys, SHAPE_POLY_SET::PM_FAST );
m_layers_poly[B_Cu]->BooleanSubtract( *m_backPlatedCopperPolys, SHAPE_POLY_SET::PM_FAST );
hasB_Cu = true;
}
m_frontPlatedPadPolys->Simplify( SHAPE_POLY_SET::PM_FAST );
m_backPlatedPadPolys->Simplify( SHAPE_POLY_SET::PM_FAST );
// 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( SHAPE_POLY_SET::PM_FAST );
m_backPlatedPadAndGraphicPolys->Simplify( SHAPE_POLY_SET::PM_FAST );
m_frontPlatedCopperPolys->Simplify( SHAPE_POLY_SET::PM_FAST );
m_backPlatedCopperPolys->Simplify( SHAPE_POLY_SET::PM_FAST );

View File

@ -613,12 +613,12 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
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();
const SHAPE_POLY_SET* frontPlatedPadAndGraphicPolys = m_boardAdapter.GetFrontPlatedPadAndGraphicPolys();
const SHAPE_POLY_SET* backPlatedPadAndGraphicPolys = m_boardAdapter.GetBackPlatedPadAndGraphicPolys();
if( frontPlatedPadPolys )
if( frontPlatedPadAndGraphicPolys )
{
SHAPE_POLY_SET poly = frontPlatedPadPolys->CloneDropTriangulation();
SHAPE_POLY_SET poly = frontPlatedPadAndGraphicPolys->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 );
@ -630,9 +630,9 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
m_layers[F_Cu] = generateEmptyLayerList( F_Cu );
}
if( backPlatedPadPolys )
if( backPlatedPadAndGraphicPolys )
{
SHAPE_POLY_SET poly = backPlatedPadPolys->CloneDropTriangulation();
SHAPE_POLY_SET poly = backPlatedPadAndGraphicPolys->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 );