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 ) if( !m_board )
return ret; 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_TOP, m_board->IsLayerVisible( F_Cu ) );
ret.set( LAYER_3D_COPPER_BOTTOM, m_board->IsLayerVisible( B_Cu ) ); ret.set( LAYER_3D_COPPER_BOTTOM, m_board->IsLayerVisible( B_Cu ) );
ret.set( LAYER_3D_SILKSCREEN_TOP, m_board->IsLayerVisible( F_SilkS ) ); ret.set( LAYER_3D_SILKSCREEN_TOP, m_board->IsLayerVisible( F_SilkS ) );
@ -889,20 +889,10 @@ bool BOARD_ADAPTER::createBoardPolygon( wxString* aErrorMsg )
float BOARD_ADAPTER::GetFootprintZPos( bool aIsFlipped ) const float BOARD_ADAPTER::GetFootprintZPos( bool aIsFlipped ) const
{ {
if( aIsFlipped ) 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 else
return m_layerZcoordTop[F_Paste]; return m_layerZcoordTop[F_Paste];
} }
}
SFVEC4F BOARD_ADAPTER::GetLayerColor( PCB_LAYER_ID aLayerId ) const SFVEC4F BOARD_ADAPTER::GetLayerColor( PCB_LAYER_ID aLayerId ) const

View File

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

View File

@ -392,6 +392,8 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
m_outlineBoard2dObjects = new CONTAINER_2D; m_outlineBoard2dObjects = new CONTAINER_2D;
m_antioutlineBoard2dObjects = new BVH_CONTAINER_2D; m_antioutlineBoard2dObjects = new BVH_CONTAINER_2D;
std::bitset<LAYER_3D_END> layerFlags = m_boardAdapter.GetVisibleLayers();
if( !aOnlyLoadCopperAndShapes ) if( !aOnlyLoadCopperAndShapes )
{ {
const int outlineCount = m_boardAdapter.GetBoardPoly().OutlineCount(); const int outlineCount = m_boardAdapter.GetBoardPoly().OutlineCount();
@ -433,7 +435,7 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
*m_boardAdapter.GetBoard(), ii ); *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(); 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 // 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 // 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. // intersects any object in the layer container and also any hole.
if( ( m_boardAdapter.m_Cfg->m_Render.show_soldermask_top if( ( layerFlags.test( LAYER_3D_SOLDERMASK_TOP )
|| m_boardAdapter.m_Cfg->m_Render.show_soldermask_bottom ) || layerFlags.test( LAYER_3D_SOLDERMASK_BOTTOM ) )
&& !m_outlineBoard2dObjects->GetList().empty() ) && !m_outlineBoard2dObjects->GetList().empty() )
{ {
const MATERIAL* materialLayer = &m_materials.m_SolderMask; const MATERIAL* materialLayer = &m_materials.m_SolderMask;
@ -674,24 +676,12 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
continue; continue;
// Only get the Solder mask layers (and only if the board has them) // Only get the Solder mask layers (and only if the board has them)
switch( layer_id ) if( layer_id == F_Mask && !layerFlags.test( LAYER_3D_SOLDERMASK_TOP ) )
{
case F_Mask:
if( !m_boardAdapter.m_Cfg->m_Render.show_soldermask_top )
continue; continue;
break; if( layer_id == B_Mask && !layerFlags.test( LAYER_3D_SOLDERMASK_BOTTOM ) )
case B_Mask:
if( !m_boardAdapter.m_Cfg->m_Render.show_soldermask_bottom )
continue; continue;
break;
default:
continue;
}
SFVEC3F layerColor; SFVEC3F layerColor;
if( layer_id == B_Mask ) if( layer_id == B_Mask )

View File

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