From 5b7c6e100dc74cb3c9c080d6485d74689d5455a1 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Thu, 1 Oct 2020 16:49:36 +0100 Subject: [PATCH] Clip tech layers to board in 3D renderer. Fixes https://gitlab.com/kicad/code/kicad/issues/4873 --- .../c3d_render_createscene_ogl_legacy.cpp | 72 +++++++---- .../c3d_render_ogl_legacy.cpp | 116 ++++++++++-------- .../c3d_render_ogl_legacy.h | 2 + .../3d_render_ogl_legacy/clayer_triangles.cpp | 14 ++- .../3d_render_ogl_legacy/clayer_triangles.h | 7 +- 5 files changed, 126 insertions(+), 85 deletions(-) diff --git a/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_createscene_ogl_legacy.cpp b/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_createscene_ogl_legacy.cpp index 5bb657ba44..7f64897487 100644 --- a/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_createscene_ogl_legacy.cpp +++ b/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_createscene_ogl_legacy.cpp @@ -412,30 +412,11 @@ CLAYERS_OGL_DISP_LISTS* C3D_RENDER_OGL_LEGACY::generateLayerListFromContainer( c } -void C3D_RENDER_OGL_LEGACY::reload( REPORTER* aStatusReporter, REPORTER* aWarningReporter ) +CLAYERS_OGL_DISP_LISTS* C3D_RENDER_OGL_LEGACY::createBoard( SHAPE_POLY_SET aBoardPoly ) { - m_reloadRequested = false; - - ogl_free_all_display_lists(); - - COBJECT2D_STATS::Instance().ResetStats(); - - unsigned stats_startReloadTime = GetRunningMicroSecs(); - - m_boardAdapter.InitSettings( aStatusReporter, aWarningReporter ); - - SFVEC3F camera_pos = m_boardAdapter.GetBoardCenter3DU(); - m_camera.SetBoardLookAtPos( camera_pos ); - - if( aStatusReporter ) - aStatusReporter->Report( _( "Load OpenGL: board" ) ); - - // Create Board - // ///////////////////////////////////////////////////////////////////////// - + CLAYERS_OGL_DISP_LISTS* dispLists = nullptr; CCONTAINER2D boardContainer; - SHAPE_POLY_SET tmpBoard = m_boardAdapter.GetBoardPoly(); - Convert_shape_line_polygon_to_triangles( tmpBoard, + Convert_shape_line_polygon_to_triangles( aBoardPoly, boardContainer, m_boardAdapter.BiuTo3Dunits(), (const BOARD_ITEM &)*m_boardAdapter.GetBoard() ); @@ -487,15 +468,54 @@ void C3D_RENDER_OGL_LEGACY::reload( REPORTER* aStatusReporter, REPORTER* aWarnin m_boardAdapter.BiuTo3Dunits(), false ); - m_ogl_disp_list_board = new CLAYERS_OGL_DISP_LISTS( *layerTriangles, - m_ogl_circle_texture, - layer_z_top, - layer_z_top ); + dispLists = new CLAYERS_OGL_DISP_LISTS( *layerTriangles, + m_ogl_circle_texture, + layer_z_top, + layer_z_top ); } delete layerTriangles; } + return dispLists; +} + + +void C3D_RENDER_OGL_LEGACY::reload( REPORTER* aStatusReporter, REPORTER* aWarningReporter ) +{ + m_reloadRequested = false; + + ogl_free_all_display_lists(); + + COBJECT2D_STATS::Instance().ResetStats(); + + unsigned stats_startReloadTime = GetRunningMicroSecs(); + + m_boardAdapter.InitSettings( aStatusReporter, aWarningReporter ); + + SFVEC3F camera_pos = m_boardAdapter.GetBoardCenter3DU(); + m_camera.SetBoardLookAtPos( camera_pos ); + + if( aStatusReporter ) + aStatusReporter->Report( _( "Load OpenGL: board" ) ); + + // Create Board + // ///////////////////////////////////////////////////////////////////////// + + m_ogl_disp_list_board = createBoard( m_boardAdapter.GetBoardPoly() ); + + SHAPE_POLY_SET anti_board; + anti_board.NewOutline(); + anti_board.Append( VECTOR2I( -INT_MAX/2, -INT_MAX/2 ) ); + anti_board.Append( VECTOR2I( INT_MAX/2, -INT_MAX/2 ) ); + anti_board.Append( VECTOR2I( INT_MAX/2, INT_MAX/2 ) ); + anti_board.Append( VECTOR2I( -INT_MAX/2, INT_MAX/2 ) ); + anti_board.Outline( 0 ).SetClosed( true ); + + anti_board.BooleanSubtract( m_boardAdapter.GetBoardPoly(), SHAPE_POLY_SET::PM_FAST ); + m_ogl_disp_list_anti_board = createBoard( anti_board ); + m_ogl_disp_list_anti_board->SetItIsTransparent( true ); + // Create Through Holes and vias // ///////////////////////////////////////////////////////////////////////// diff --git a/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_ogl_legacy.cpp b/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_ogl_legacy.cpp index 1f3f7ae015..7ea1011d52 100644 --- a/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_ogl_legacy.cpp +++ b/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_ogl_legacy.cpp @@ -59,6 +59,7 @@ C3D_RENDER_OGL_LEGACY::C3D_RENDER_OGL_LEGACY( BOARD_ADAPTER& aAdapter, CCAMERA& m_ogl_disp_lists_layers_holes_inner.clear(); m_triangles.clear(); m_ogl_disp_list_board = NULL; + m_ogl_disp_list_anti_board = NULL; m_ogl_disp_lists_platedPads_F_Cu = nullptr; m_ogl_disp_lists_platedPads_B_Cu = nullptr; @@ -543,12 +544,12 @@ void C3D_RENDER_OGL_LEGACY::render_board_body( bool aSkipRenderHoles ) if( (m_ogl_disp_list_through_holes_outer_with_npth) && (!aSkipRenderHoles) ) { m_ogl_disp_list_through_holes_outer_with_npth->ApplyScalePosition( - -m_boardAdapter.GetEpoxyThickness3DU() / 2.0f, - m_boardAdapter.GetEpoxyThickness3DU() ); + -m_boardAdapter.GetEpoxyThickness3DU() / 2.0f, + m_boardAdapter.GetEpoxyThickness3DU() ); m_ogl_disp_list_board->DrawAllCameraCulledSubtractLayer( - m_ogl_disp_list_through_holes_outer_with_npth, - NULL ); + true, + m_ogl_disp_list_through_holes_outer_with_npth ); } else { @@ -776,9 +777,9 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( if( viasHolesLayer != NULL ) { pLayerDispList->DrawAllCameraCulledSubtractLayer( + drawMiddleSegments, m_ogl_disp_list_through_holes_outer, - viasHolesLayer, - drawMiddleSegments ); + viasHolesLayer ); // Draw copper plated pads @@ -787,16 +788,19 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( setPlatedCopperAndDepthOffset( layer_id ); if( ( layer_id == F_Cu ) && m_ogl_disp_lists_platedPads_F_Cu ) + { m_ogl_disp_lists_platedPads_F_Cu->DrawAllCameraCulledSubtractLayer( + drawMiddleSegments, m_ogl_disp_list_through_holes_outer, - viasHolesLayer, - drawMiddleSegments ); - else - if( ( layer_id == B_Cu ) && m_ogl_disp_lists_platedPads_B_Cu ) - m_ogl_disp_lists_platedPads_B_Cu->DrawAllCameraCulledSubtractLayer( - m_ogl_disp_list_through_holes_outer, - viasHolesLayer, - drawMiddleSegments ); + viasHolesLayer ); + } + else if( ( layer_id == B_Cu ) && m_ogl_disp_lists_platedPads_B_Cu ) + { + m_ogl_disp_lists_platedPads_B_Cu->DrawAllCameraCulledSubtractLayer( + drawMiddleSegments, + m_ogl_disp_list_through_holes_outer, + viasHolesLayer ); + } unsetDepthOffset(); } @@ -804,27 +808,29 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( else { pLayerDispList->DrawAllCameraCulledSubtractLayer( - m_ogl_disp_list_through_holes_outer, - NULL, - drawMiddleSegments ); + drawMiddleSegments, + m_ogl_disp_list_through_holes_outer ); // Draw copper plated pads if( ( ( layer_id == F_Cu ) || ( layer_id == B_Cu ) ) && ( m_ogl_disp_lists_platedPads_F_Cu || m_ogl_disp_lists_platedPads_B_Cu ) ) + { setPlatedCopperAndDepthOffset( layer_id ); + } if( ( layer_id == F_Cu ) && m_ogl_disp_lists_platedPads_F_Cu ) + { m_ogl_disp_lists_platedPads_F_Cu->DrawAllCameraCulledSubtractLayer( - m_ogl_disp_list_through_holes_outer, - NULL, - drawMiddleSegments ); - else - if( ( layer_id == B_Cu ) && m_ogl_disp_lists_platedPads_B_Cu ) - m_ogl_disp_lists_platedPads_B_Cu->DrawAllCameraCulledSubtractLayer( - m_ogl_disp_list_through_holes_outer, - NULL, - drawMiddleSegments ); + drawMiddleSegments, + m_ogl_disp_list_through_holes_outer ); + } + else if( ( layer_id == B_Cu ) && m_ogl_disp_lists_platedPads_B_Cu ) + { + m_ogl_disp_lists_platedPads_B_Cu->DrawAllCameraCulledSubtractLayer( + drawMiddleSegments, + m_ogl_disp_list_through_holes_outer ); + } unsetDepthOffset(); } @@ -841,8 +847,13 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( m_ogl_disp_list_through_holes_outer; if( dispListThroughHolesOuter ) + { dispListThroughHolesOuter->ApplyScalePosition( pLayerDispList->GetZBot(), pLayerDispList->GetZTop() - pLayerDispList->GetZBot() ); + } + + m_ogl_disp_list_anti_board->ApplyScalePosition( pLayerDispList->GetZBot(), + pLayerDispList->GetZTop() - pLayerDispList->GetZBot() ); if( (!skipRenderHoles) && m_boardAdapter.GetFlag( FL_SUBTRACT_MASK_FROM_SILK ) && @@ -851,37 +862,36 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( ( ( layer_id == F_SilkS ) && ( m_ogl_disp_lists_layers.find( F_Mask ) != m_ogl_disp_lists_layers.end() ) ) ) ) { - const PCB_LAYER_ID layerMask_id = (layer_id == B_SilkS)?B_Mask:F_Mask; + const PCB_LAYER_ID layerMask_id = (layer_id == B_SilkS) ? B_Mask : F_Mask; const CLAYERS_OGL_DISP_LISTS *pLayerDispListMask = m_ogl_disp_lists_layers.at( layerMask_id ); pLayerDispList->DrawAllCameraCulledSubtractLayer( + drawMiddleSegments, pLayerDispListMask, dispListThroughHolesOuter, - drawMiddleSegments ); + m_ogl_disp_list_anti_board ); } else { - if((!skipRenderHoles) && - dispListThroughHolesOuter && - ( ( layer_id == B_SilkS ) || ( layer_id == F_SilkS ) - // Remove vias on SolderPaste can be added as an option in future - // ( layer_id == B_Paste ) || ( layer_id == F_Paste ) ) - ) ) + if( !skipRenderHoles && + dispListThroughHolesOuter && ( layer_id == B_SilkS || layer_id == F_SilkS ) ) { pLayerDispList->DrawAllCameraCulledSubtractLayer( - NULL, + drawMiddleSegments, + nullptr, dispListThroughHolesOuter, - drawMiddleSegments ); + m_ogl_disp_list_anti_board ); } else { // Do not render Paste layers when skipRenderHoles is enabled // otherwise it will cause z-fight issues - if( !( skipRenderHoles && - ( ( layer_id == B_Paste ) || ( layer_id == F_Paste ) ) ) ) + if( !( skipRenderHoles && ( layer_id == B_Paste || layer_id == F_Paste ) ) ) { - pLayerDispList->DrawAllCameraCulled( m_camera.GetPos().z, drawMiddleSegments ); + pLayerDispList->DrawAllCameraCulledSubtractLayer( + drawMiddleSegments, + m_ogl_disp_list_anti_board ); } } } @@ -1136,28 +1146,31 @@ void C3D_RENDER_OGL_LEGACY::ogl_free_all_display_lists() delete m_ogl_disp_list_board; - m_ogl_disp_list_board = 0; + m_ogl_disp_list_board = nullptr; + + delete m_ogl_disp_list_anti_board; + m_ogl_disp_list_anti_board = nullptr; delete m_ogl_disp_list_through_holes_outer_with_npth; - m_ogl_disp_list_through_holes_outer_with_npth = 0; + m_ogl_disp_list_through_holes_outer_with_npth = nullptr; delete m_ogl_disp_list_through_holes_outer; - m_ogl_disp_list_through_holes_outer = 0; + m_ogl_disp_list_through_holes_outer = nullptr; delete m_ogl_disp_list_through_holes_vias_outer; - m_ogl_disp_list_through_holes_vias_outer = 0; + m_ogl_disp_list_through_holes_vias_outer = nullptr; delete m_ogl_disp_list_through_holes_outer_ring; - m_ogl_disp_list_through_holes_outer_ring = 0; + m_ogl_disp_list_through_holes_outer_ring = nullptr; delete m_ogl_disp_list_via; - m_ogl_disp_list_via = 0; + m_ogl_disp_list_via = nullptr; delete m_ogl_disp_list_pads_holes; - m_ogl_disp_list_pads_holes = 0; + m_ogl_disp_list_pads_holes = nullptr; delete m_ogl_disp_list_vias_and_pad_holes_outer_contourn_and_caps; - m_ogl_disp_list_vias_and_pad_holes_outer_contourn_and_caps = 0; + m_ogl_disp_list_vias_and_pad_holes_outer_contourn_and_caps = nullptr; } @@ -1196,9 +1209,9 @@ void C3D_RENDER_OGL_LEGACY::render_solder_mask_layer(PCB_LAYER_ID aLayerID, else { m_ogl_disp_list_board->DrawAllCameraCulledSubtractLayer( + aDrawMiddleSegments, pLayerDispListMask, - m_ogl_disp_list_through_holes_vias_outer, - aDrawMiddleSegments ); + m_ogl_disp_list_through_holes_vias_outer ); } } else @@ -1226,9 +1239,8 @@ void C3D_RENDER_OGL_LEGACY::render_solder_mask_layer(PCB_LAYER_ID aLayerID, else { m_ogl_disp_list_board->DrawAllCameraCulledSubtractLayer( - NULL, - m_ogl_disp_list_through_holes_vias_outer, - aDrawMiddleSegments ); + aDrawMiddleSegments, + m_ogl_disp_list_through_holes_vias_outer ); } } } diff --git a/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_ogl_legacy.h b/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_ogl_legacy.h index 05d7b9b5b4..b2f2469ce0 100644 --- a/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_ogl_legacy.h +++ b/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_ogl_legacy.h @@ -73,6 +73,7 @@ public: private: bool initializeOpenGL(); + CLAYERS_OGL_DISP_LISTS* createBoard( SHAPE_POLY_SET aBoardPoly ); void reload( REPORTER* aStatusReporter, REPORTER* aWarningReporter ); void ogl_set_arrow_material(); @@ -84,6 +85,7 @@ private: MAP_OGL_DISP_LISTS m_ogl_disp_lists_layers_holes_outer; MAP_OGL_DISP_LISTS m_ogl_disp_lists_layers_holes_inner; CLAYERS_OGL_DISP_LISTS* m_ogl_disp_list_board; + CLAYERS_OGL_DISP_LISTS* m_ogl_disp_list_anti_board; CLAYERS_OGL_DISP_LISTS* m_ogl_disp_list_through_holes_outer; // User for body render diff --git a/3d-viewer/3d_rendering/3d_render_ogl_legacy/clayer_triangles.cpp b/3d-viewer/3d_rendering/3d_render_ogl_legacy/clayer_triangles.cpp index 9ae5c4d85a..21dd900677 100644 --- a/3d-viewer/3d_rendering/3d_render_ogl_legacy/clayer_triangles.cpp +++ b/3d-viewer/3d_rendering/3d_render_ogl_legacy/clayer_triangles.cpp @@ -521,10 +521,10 @@ void CLAYERS_OGL_DISP_LISTS::DrawAllCameraCulled(float zCameraPos, bool aDrawMid } -void CLAYERS_OGL_DISP_LISTS::DrawAllCameraCulledSubtractLayer( - const CLAYERS_OGL_DISP_LISTS *aLayerToSubtractA, - const CLAYERS_OGL_DISP_LISTS *aLayerToSubtractB, - bool aDrawMiddle ) const +void CLAYERS_OGL_DISP_LISTS::DrawAllCameraCulledSubtractLayer( bool aDrawMiddle, + const CLAYERS_OGL_DISP_LISTS *aLayerToSubtractA, + const CLAYERS_OGL_DISP_LISTS *aLayerToSubtractB, + const CLAYERS_OGL_DISP_LISTS *aLayerToSubtractC ) const { glClearStencil( 0x00 ); glClear( GL_STENCIL_BUFFER_BIT ); @@ -545,6 +545,9 @@ void CLAYERS_OGL_DISP_LISTS::DrawAllCameraCulledSubtractLayer( if( aLayerToSubtractB ) aLayerToSubtractB->DrawBot(); + if( aLayerToSubtractC ) + aLayerToSubtractC->DrawBot(); + //if( !m_draw_it_transparent ) { @@ -570,6 +573,9 @@ void CLAYERS_OGL_DISP_LISTS::DrawAllCameraCulledSubtractLayer( if( aLayerToSubtractB ) aLayerToSubtractB->DrawTop(); + if( aLayerToSubtractC ) + aLayerToSubtractC->DrawTop(); + //if( !m_draw_it_transparent ) { glEnable(GL_DEPTH_TEST); diff --git a/3d-viewer/3d_rendering/3d_render_ogl_legacy/clayer_triangles.h b/3d-viewer/3d_rendering/3d_render_ogl_legacy/clayer_triangles.h index 9deb119782..5da2f084d9 100644 --- a/3d-viewer/3d_rendering/3d_render_ogl_legacy/clayer_triangles.h +++ b/3d-viewer/3d_rendering/3d_render_ogl_legacy/clayer_triangles.h @@ -253,9 +253,10 @@ public: */ void DrawAllCameraCulled( float zCameraPos, bool aDrawMiddle = true ) const; - void DrawAllCameraCulledSubtractLayer( const CLAYERS_OGL_DISP_LISTS *aLayerToSubtractA, - const CLAYERS_OGL_DISP_LISTS *aLayerToSubtractB, - bool aDrawMiddle = true ) const; + void DrawAllCameraCulledSubtractLayer( bool aDrawMiddle, + const CLAYERS_OGL_DISP_LISTS* aLayerToSubtractA = nullptr, + const CLAYERS_OGL_DISP_LISTS* aLayerToSubtractB = nullptr, + const CLAYERS_OGL_DISP_LISTS* aLayerToSubtractC = nullptr ) const; void ApplyScalePosition( float aZposition, float aZscale );