Fix logic errors in handling board body visibility.

Also fixes a bug where models were placed above the silk when the
solder paste layer was shown, but on the solder paste layer when
it wasn't shown.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/15510

Fixes https://gitlab.com/kicad/code/kicad/-/issues/6770
This commit is contained in:
Jeff Young 2023-08-26 17:33:23 +01:00
parent 725840654f
commit 22256c97f3
4 changed files with 22 additions and 41 deletions

View File

@ -767,7 +767,7 @@ std::bitset<LAYER_3D_END> BOARD_ADAPTER::GetVisibleLayers() const
if( !m_board )
return ret;
ret.set( LAYER_3D_BOARD, m_board->IsLayerVisible( Edge_Cuts ) );
ret.set( LAYER_3D_BOARD, true );
ret.set( LAYER_3D_COPPER_TOP, m_board->IsLayerVisible( F_Cu ) );
ret.set( LAYER_3D_COPPER_BOTTOM, m_board->IsLayerVisible( B_Cu ) );
ret.set( LAYER_3D_SILKSCREEN_TOP, m_board->IsLayerVisible( F_SilkS ) );
@ -889,19 +889,9 @@ bool BOARD_ADAPTER::createBoardPolygon( wxString* aErrorMsg )
float BOARD_ADAPTER::GetFootprintZPos( bool aIsFlipped ) const
{
if( aIsFlipped )
{
if( m_Cfg->m_Render.show_solderpaste )
return m_layerZcoordBottom[B_SilkS];
else
return m_layerZcoordBottom[B_Paste];
}
return m_layerZcoordBottom[B_Paste];
else
{
if( m_Cfg->m_Render.show_solderpaste )
return m_layerZcoordTop[F_SilkS];
else
return m_layerZcoordTop[F_Paste];
}
return m_layerZcoordTop[F_Paste];
}

View File

@ -543,6 +543,8 @@ bool RENDER_3D_OPENGL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
bool drawMiddleSegments = !skipThickness;
std::bitset<LAYER_3D_END> layerFlags = m_boardAdapter.GetVisibleLayers();
setLayerMaterial( B_Cu );
if( !( skipRenderVias || skipRenderHoles ) && m_vias )
@ -565,8 +567,7 @@ bool RENDER_3D_OPENGL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
// So avoid creating them is they are not very visible
const double opacity_min = 0.8;
if( m_boardAdapter.m_Cfg->m_Render.show_board_body
&& m_boardAdapter.m_BoardBodyColor.a > opacity_min )
if( layerFlags.test( LAYER_3D_BOARD ) && m_boardAdapter.m_BoardBodyColor.a > opacity_min )
{
if( ( layer_id > F_Cu ) && ( layer_id < B_Cu ) )
continue;
@ -752,12 +753,11 @@ bool RENDER_3D_OPENGL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
renderOpaqueModels( cameraViewMatrix );
// Display board body
if( m_boardAdapter.m_Cfg->m_Render.show_board_body )
if( layerFlags.test( LAYER_3D_BOARD ) )
renderBoardBody( skipRenderHoles );
// Display transparent mask layers
if( m_boardAdapter.m_Cfg->m_Render.show_soldermask_top
|| m_boardAdapter.m_Cfg->m_Render.show_soldermask_bottom )
if( layerFlags.test( LAYER_3D_SOLDERMASK_TOP ) || layerFlags.test( LAYER_3D_SOLDERMASK_BOTTOM ) )
{
// add a depth buffer offset, it will help to hide some artifacts
// on silkscreen where the SolderMask is removed
@ -766,13 +766,13 @@ bool RENDER_3D_OPENGL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
if( m_camera.GetPos().z > 0 )
{
if( m_boardAdapter.m_Cfg->m_Render.show_soldermask_bottom )
if( layerFlags.test( LAYER_3D_SOLDERMASK_BOTTOM ) )
{
renderSolderMaskLayer( B_Mask, m_boardAdapter.GetLayerTopZPos( B_Mask ),
drawMiddleSegments, skipRenderHoles );
}
if( m_boardAdapter.m_Cfg->m_Render.show_soldermask_top )
if( layerFlags.test( LAYER_3D_SOLDERMASK_TOP ) )
{
renderSolderMaskLayer( F_Mask, m_boardAdapter.GetLayerBottomZPos( F_Mask ),
drawMiddleSegments, skipRenderHoles );
@ -780,13 +780,13 @@ bool RENDER_3D_OPENGL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
}
else
{
if( m_boardAdapter.m_Cfg->m_Render.show_soldermask_top )
if( layerFlags.test( LAYER_3D_SOLDERMASK_TOP ) )
{
renderSolderMaskLayer( F_Mask, m_boardAdapter.GetLayerBottomZPos( F_Mask ),
drawMiddleSegments, skipRenderHoles );
}
if( m_boardAdapter.m_Cfg->m_Render.show_soldermask_bottom )
if( layerFlags.test( LAYER_3D_SOLDERMASK_BOTTOM ) )
{
renderSolderMaskLayer( B_Mask, m_boardAdapter.GetLayerTopZPos( B_Mask ),
drawMiddleSegments, skipRenderHoles );

View File

@ -392,6 +392,8 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
m_outlineBoard2dObjects = new CONTAINER_2D;
m_antioutlineBoard2dObjects = new BVH_CONTAINER_2D;
std::bitset<LAYER_3D_END> layerFlags = m_boardAdapter.GetVisibleLayers();
if( !aOnlyLoadCopperAndShapes )
{
const int outlineCount = m_boardAdapter.GetBoardPoly().OutlineCount();
@ -433,7 +435,7 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
*m_boardAdapter.GetBoard(), ii );
}
if( m_boardAdapter.m_Cfg->m_Render.show_board_body )
if( layerFlags.test( LAYER_3D_BOARD ) )
{
const LIST_OBJECT2D& listObjects = m_outlineBoard2dObjects->GetList();
@ -658,8 +660,8 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
// Solder mask layers are "negative" layers so the elements that we have in the container
// should remove the board outline. We will check for all objects in the outline if it
// intersects any object in the layer container and also any hole.
if( ( m_boardAdapter.m_Cfg->m_Render.show_soldermask_top
|| m_boardAdapter.m_Cfg->m_Render.show_soldermask_bottom )
if( ( layerFlags.test( LAYER_3D_SOLDERMASK_TOP )
|| layerFlags.test( LAYER_3D_SOLDERMASK_BOTTOM ) )
&& !m_outlineBoard2dObjects->GetList().empty() )
{
const MATERIAL* materialLayer = &m_materials.m_SolderMask;
@ -674,23 +676,11 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
continue;
// Only get the Solder mask layers (and only if the board has them)
switch( layer_id )
{
case F_Mask:
if( !m_boardAdapter.m_Cfg->m_Render.show_soldermask_top )
continue;
break;
case B_Mask:
if( !m_boardAdapter.m_Cfg->m_Render.show_soldermask_bottom )
continue;
break;
default:
if( layer_id == F_Mask && !layerFlags.test( LAYER_3D_SOLDERMASK_TOP ) )
continue;
if( layer_id == B_Mask && !layerFlags.test( LAYER_3D_SOLDERMASK_BOTTOM ) )
continue;
}
SFVEC3F layerColor;

View File

@ -321,6 +321,7 @@ void APPEARANCE_CONTROLS_3D::OnLayerVisibilityChanged( int aLayer, bool isVisibl
killFollow = true;
break;
case LAYER_3D_BOARD:
case LAYER_3D_COPPER_TOP:
case LAYER_3D_COPPER_BOTTOM:
case LAYER_3D_SILKSCREEN_BOTTOM: