From e1bbb717f60d08af722e5d53308c491e36b0c0bc Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Mon, 16 Aug 2021 16:28:46 +0200 Subject: [PATCH] 3D viewer: ensure 3D shapes are loaded when switching 3D shapes visibility option to ON. Fixes #8959 https://gitlab.com/kicad/code/kicad/issues/8959 --- 3d-viewer/3d_canvas/eda_3d_canvas.cpp | 4 ++-- 3d-viewer/3d_canvas/eda_3d_canvas.h | 6 +++++- .../3d_render_raytracing/create_scene.cpp | 11 ++++++++-- .../render_3d_raytrace.cpp | 4 ++-- .../3d_render_raytracing/render_3d_raytrace.h | 4 ++-- .../3d_rendering/legacy/create_scene.cpp | 20 +++++++++++++++++++ .../3d_rendering/legacy/render_3d_legacy.cpp | 4 ++-- .../3d_rendering/legacy/render_3d_legacy.h | 7 ++++++- 3d-viewer/3d_rendering/render_3d_base.cpp | 3 ++- 3d-viewer/3d_rendering/render_3d_base.h | 5 ++++- .../3d_viewer/tools/eda_3d_controller.cpp | 13 ++++++++++++ 11 files changed, 67 insertions(+), 14 deletions(-) diff --git a/3d-viewer/3d_canvas/eda_3d_canvas.cpp b/3d-viewer/3d_canvas/eda_3d_canvas.cpp index 5b3e258b96..55d5d49615 100644 --- a/3d-viewer/3d_canvas/eda_3d_canvas.cpp +++ b/3d-viewer/3d_canvas/eda_3d_canvas.cpp @@ -126,8 +126,8 @@ EDA_3D_CANVAS::EDA_3D_CANVAS( wxWindow* aParent, const int* aAttribList, m_is_currently_painting.clear(); - m_3d_render_raytracing = new RENDER_3D_RAYTRACE( m_boardAdapter, m_camera ); - m_3d_render_ogl_legacy = new RENDER_3D_LEGACY( m_boardAdapter, m_camera ); + m_3d_render_raytracing = new RENDER_3D_RAYTRACE( this, m_boardAdapter, m_camera ); + m_3d_render_ogl_legacy = new RENDER_3D_LEGACY( this, m_boardAdapter, m_camera ); wxASSERT( m_3d_render_raytracing != nullptr ); wxASSERT( m_3d_render_ogl_legacy != nullptr ); diff --git a/3d-viewer/3d_canvas/eda_3d_canvas.h b/3d-viewer/3d_canvas/eda_3d_canvas.h index de691acb5e..99bf4e7421 100644 --- a/3d-viewer/3d_canvas/eda_3d_canvas.h +++ b/3d-viewer/3d_canvas/eda_3d_canvas.h @@ -96,6 +96,11 @@ public: return false; } + /** + * @return the current render ( a RENDER_3D_RAYTRACE* or a RENDER_3D_LEGACY* render ) + */ + RENDER_3D_BASE* GetCurrentRender() const { return m_3d_render; } + /** * Request to render the current view in Raytracing mode. */ @@ -270,7 +275,6 @@ private: bool m_opengl_supports_raytracing; bool m_render_raytracing_was_requested; - CONTAINER_3D m_3DShapes_container; // Holds 3D shapes from footprints ACCELERATOR_3D* m_accelerator3DShapes; // used for mouse over searching BOARD_ITEM* m_currentRollOverItem; diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/create_scene.cpp b/3d-viewer/3d_rendering/3d_render_raytracing/create_scene.cpp index e291ffc8d6..1f14eba12d 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/create_scene.cpp +++ b/3d-viewer/3d_rendering/3d_render_raytracing/create_scene.cpp @@ -880,7 +880,7 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe if( aStatusReporter ) aStatusReporter->Report( _( "Loading 3D models..." ) ); - loadModels( m_objectContainer, aOnlyLoadCopperAndShapes ); + load3DModels( m_objectContainer, aOnlyLoadCopperAndShapes ); #ifdef PRINT_STATISTICS_3D_VIEWER unsigned stats_endLoad3DmodelsTime = GetRunningMicroSecs(); @@ -1283,11 +1283,18 @@ void RENDER_3D_RAYTRACE::addPadsAndVias() } -void RENDER_3D_RAYTRACE::loadModels( CONTAINER_3D& aDstContainer, bool aSkipMaterialInformation ) +void RENDER_3D_RAYTRACE::load3DModels( CONTAINER_3D& aDstContainer, bool aSkipMaterialInformation ) { if( !m_boardAdapter.GetBoard() ) return; + if( !m_boardAdapter.GetFlag( FL_FP_ATTRIBUTES_NORMAL ) + && !m_boardAdapter.GetFlag( FL_FP_ATTRIBUTES_NORMAL_INSERT ) + && !m_boardAdapter.GetFlag( FL_FP_ATTRIBUTES_VIRTUAL ) ) + { + return; + } + // Go for all footprints for( FOOTPRINT* fp : m_boardAdapter.GetBoard()->Footprints() ) { diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/render_3d_raytrace.cpp b/3d-viewer/3d_rendering/3d_render_raytracing/render_3d_raytrace.cpp index 05e762c122..20e95d6505 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/render_3d_raytrace.cpp +++ b/3d-viewer/3d_rendering/3d_render_raytracing/render_3d_raytrace.cpp @@ -44,8 +44,8 @@ #include -RENDER_3D_RAYTRACE::RENDER_3D_RAYTRACE( BOARD_ADAPTER& aAdapter, CAMERA& aCamera ) : - RENDER_3D_BASE( aAdapter, aCamera ), +RENDER_3D_RAYTRACE::RENDER_3D_RAYTRACE( EDA_3D_CANVAS* aCanvas, BOARD_ADAPTER& aAdapter, CAMERA& aCamera ) : + RENDER_3D_BASE( aCanvas, aAdapter, aCamera ), m_postShaderSsao( aCamera ) { wxLogTrace( m_logTrace, wxT( "RENDER_3D_RAYTRACE::RENDER_3D_RAYTRACE" ) ); diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/render_3d_raytrace.h b/3d-viewer/3d_rendering/3d_render_raytracing/render_3d_raytrace.h index 29ea0015a4..eba7781bc3 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/render_3d_raytrace.h +++ b/3d-viewer/3d_rendering/3d_render_raytracing/render_3d_raytrace.h @@ -59,7 +59,7 @@ typedef enum class RENDER_3D_RAYTRACE : public RENDER_3D_BASE { public: - explicit RENDER_3D_RAYTRACE( BOARD_ADAPTER& aAdapter, CAMERA& aCamera ); + explicit RENDER_3D_RAYTRACE( EDA_3D_CANVAS* aCanvas, BOARD_ADAPTER& aAdapter, CAMERA& aCamera ); ~RENDER_3D_RAYTRACE(); @@ -116,7 +116,7 @@ private: void addPadsAndVias(); void insertHole( const PCB_VIA* aVia ); void insertHole( const PAD* aPad ); - void loadModels( CONTAINER_3D& aDstContainer, bool aSkipMaterialInformation ); + void load3DModels( CONTAINER_3D& aDstContainer, bool aSkipMaterialInformation ); void addModels( CONTAINER_3D& aDstContainer, const S3DMODEL* a3DModel, const glm::mat4& aModelMatrix, float aFPOpacity, bool aSkipMaterialInformation, BOARD_ITEM* aBoardItem ); diff --git a/3d-viewer/3d_rendering/legacy/create_scene.cpp b/3d-viewer/3d_rendering/legacy/create_scene.cpp index 9a265b5e90..db84b09175 100644 --- a/3d-viewer/3d_rendering/legacy/create_scene.cpp +++ b/3d-viewer/3d_rendering/legacy/create_scene.cpp @@ -30,6 +30,8 @@ #include #include #include // To use GetRunningMicroSecs or another profiling utility +#include +#include void RENDER_3D_LEGACY::addObjectTriangles( const FILLED_CIRCLE_2D* aFilledCircle, @@ -867,6 +869,24 @@ void RENDER_3D_LEGACY::generateViasAndPads() } +void RENDER_3D_LEGACY::Load3dModelsIfNeeded() +{ + if( m_3dModelMap.size() > 0 ) + return; + + wxFrame* frame = dynamic_cast( m_canvas->GetParent() ); + + if( frame ) + { + STATUSBAR_REPORTER activityReporter( frame->GetStatusBar(), + (int) EDA_3D_VIEWER_STATUSBAR::ACTIVITY ); + load3dModels( &activityReporter ); + } + else + load3dModels( nullptr ); +} + + void RENDER_3D_LEGACY::load3dModels( REPORTER* aStatusReporter ) { if( !m_boardAdapter.GetBoard() ) diff --git a/3d-viewer/3d_rendering/legacy/render_3d_legacy.cpp b/3d-viewer/3d_rendering/legacy/render_3d_legacy.cpp index 0468d9e880..74a1f9ee21 100644 --- a/3d-viewer/3d_rendering/legacy/render_3d_legacy.cpp +++ b/3d-viewer/3d_rendering/legacy/render_3d_legacy.cpp @@ -39,8 +39,8 @@ */ #define UNITS3D_TO_UNITSPCB (IU_PER_MM) -RENDER_3D_LEGACY::RENDER_3D_LEGACY( BOARD_ADAPTER& aAdapter, CAMERA& aCamera ) : - RENDER_3D_BASE( aAdapter, aCamera ) +RENDER_3D_LEGACY::RENDER_3D_LEGACY( EDA_3D_CANVAS* aCanvas, BOARD_ADAPTER& aAdapter, CAMERA& aCamera ) : + RENDER_3D_BASE( aCanvas, aAdapter, aCamera ) { wxLogTrace( m_logTrace, wxT( "RENDER_3D_LEGACY::RENDER_3D_LEGACY" ) ); diff --git a/3d-viewer/3d_rendering/legacy/render_3d_legacy.h b/3d-viewer/3d_rendering/legacy/render_3d_legacy.h index 339d442dae..53b6fbb935 100644 --- a/3d-viewer/3d_rendering/legacy/render_3d_legacy.h +++ b/3d-viewer/3d_rendering/legacy/render_3d_legacy.h @@ -58,7 +58,7 @@ typedef std::map< wxString, MODEL_3D* > MAP_3DMODEL; class RENDER_3D_LEGACY : public RENDER_3D_BASE { public: - explicit RENDER_3D_LEGACY( BOARD_ADAPTER& aAdapter, CAMERA& aCamera ); + explicit RENDER_3D_LEGACY( EDA_3D_CANVAS* aCanvas, BOARD_ADAPTER& aAdapter, CAMERA& aCamera ); ~RENDER_3D_LEGACY(); @@ -72,6 +72,11 @@ public: m_currentRollOverItem = aRollOverItem; } + /** + * Load footprint models if they are not already loaded, i.e. if m_3dModelMap is empty + */ + void Load3dModelsIfNeeded(); + private: OPENGL_RENDER_LIST* generateHoles( const LIST_OBJECT2D& aListHolesObject2d, const SHAPE_POLY_SET& aPoly, float aZtop, diff --git a/3d-viewer/3d_rendering/render_3d_base.cpp b/3d-viewer/3d_rendering/render_3d_base.cpp index b9361380ab..4215321adc 100644 --- a/3d-viewer/3d_rendering/render_3d_base.cpp +++ b/3d-viewer/3d_rendering/render_3d_base.cpp @@ -44,11 +44,12 @@ const wxChar* RENDER_3D_BASE::m_logTrace = wxT( "KI_TRACE_3D_RENDER" ); -RENDER_3D_BASE::RENDER_3D_BASE( BOARD_ADAPTER& aBoardAdapter, CAMERA& aCamera ) : +RENDER_3D_BASE::RENDER_3D_BASE( EDA_3D_CANVAS* aCanvas, BOARD_ADAPTER& aBoardAdapter, CAMERA& aCamera ) : m_boardAdapter( aBoardAdapter ), m_camera( aCamera ) { wxLogTrace( m_logTrace, wxT( "RENDER_3D_BASE::RENDER_3D_BASE" ) ); + m_canvas = aCanvas; m_is_opengl_initialized = false; m_windowSize = wxSize( -1, -1 ); m_reloadRequested = true; diff --git a/3d-viewer/3d_rendering/render_3d_base.h b/3d-viewer/3d_rendering/render_3d_base.h index 569a71f018..d208b28ef0 100644 --- a/3d-viewer/3d_rendering/render_3d_base.h +++ b/3d-viewer/3d_rendering/render_3d_base.h @@ -42,7 +42,7 @@ class RENDER_3D_BASE { public: - explicit RENDER_3D_BASE( BOARD_ADAPTER& aBoardAdapter, CAMERA& aCamera ); + explicit RENDER_3D_BASE( EDA_3D_CANVAS* aCanvas, BOARD_ADAPTER& aBoardAdapter, CAMERA& aCamera ); virtual ~RENDER_3D_BASE() = 0; @@ -98,6 +98,9 @@ protected: */ std::unique_ptr CreateBusyIndicator() const; + ///< the canvas to disply the scene + EDA_3D_CANVAS* m_canvas; + ///< Settings reference in use for this render. BOARD_ADAPTER& m_boardAdapter; diff --git a/3d-viewer/3d_viewer/tools/eda_3d_controller.cpp b/3d-viewer/3d_viewer/tools/eda_3d_controller.cpp index 258e3aea10..fc3a44805b 100644 --- a/3d-viewer/3d_viewer/tools/eda_3d_controller.cpp +++ b/3d-viewer/3d_viewer/tools/eda_3d_controller.cpp @@ -29,6 +29,7 @@ #include #include #include "eda_3d_actions.h" +#include <3d_rendering/legacy/render_3d_legacy.h> bool EDA_3D_CONTROLLER::Init() @@ -217,11 +218,23 @@ int EDA_3D_CONTROLLER::ToggleVisibility( const TOOL_EVENT& aEvent ) case FL_RENDER_RAYTRACING_REFRACTIONS: case FL_RENDER_RAYTRACING_REFLECTIONS: case FL_RENDER_RAYTRACING_ANTI_ALIASING: + if( m_boardAdapter->GetRenderEngine() == RENDER_ENGINE::OPENGL_LEGACY ) + m_canvas->Request_refresh(); + else + m_canvas->RenderRaytracingRequest(); + + break; + case FL_FP_ATTRIBUTES_NORMAL: case FL_FP_ATTRIBUTES_NORMAL_INSERT: case FL_FP_ATTRIBUTES_VIRTUAL: + // Loading 3D shapes can be needed if not yet loaded if( m_boardAdapter->GetRenderEngine() == RENDER_ENGINE::OPENGL_LEGACY ) + { + RENDER_3D_LEGACY* render = static_cast< RENDER_3D_LEGACY* > ( m_canvas->GetCurrentRender() ); + render->Load3dModelsIfNeeded(); m_canvas->Request_refresh(); + } else m_canvas->RenderRaytracingRequest();