diff --git a/3d-viewer/3d_cache/dialogs/panel_preview_3d_model.cpp b/3d-viewer/3d_cache/dialogs/panel_preview_3d_model.cpp index cd55a23213..ca0c04f565 100644 --- a/3d-viewer/3d_cache/dialogs/panel_preview_3d_model.cpp +++ b/3d-viewer/3d_cache/dialogs/panel_preview_3d_model.cpp @@ -93,9 +93,10 @@ PANEL_PREVIEW_3D_MODEL::PANEL_PREVIEW_3D_MODEL( wxWindow* aParent, PCB_BASE_FRAM // Create the 3D canvas m_previewPane = new EDA_3D_CANVAS( this, OGL_ATT_LIST::GetAttributesList( ANTIALIASING_MODE::AA_8X ), - m_dummyBoard, m_boardAdapter, m_currentCamera, + m_boardAdapter, m_currentCamera, aFrame->Prj().Get3DCacheManager() ); + m_boardAdapter.SetBoard( m_dummyBoard ); loadSettings(); m_boardAdapter.SetFlag( FL_USE_SELECTION, false ); diff --git a/3d-viewer/3d_canvas/board_adapter.cpp b/3d-viewer/3d_canvas/board_adapter.cpp index 0193e4d432..668aafe34c 100644 --- a/3d-viewer/3d_canvas/board_adapter.cpp +++ b/3d-viewer/3d_canvas/board_adapter.cpp @@ -155,7 +155,7 @@ bool BOARD_ADAPTER::Is3dLayerEnabled( PCB_LAYER_ID aLayer ) const { wxASSERT( aLayer < PCB_LAYER_ID_COUNT ); - if( !m_board->IsLayerEnabled( aLayer ) ) + if( m_board && !m_board->IsLayerEnabled( aLayer ) ) return false; // see if layer needs to be shown @@ -210,7 +210,7 @@ bool BOARD_ADAPTER::Is3dLayerEnabled( PCB_LAYER_ID aLayer ) const default: // the layer is an internal copper layer, used the visibility - return m_board->IsLayerVisible( aLayer ); + return m_board && m_board->IsLayerVisible( aLayer ); } } @@ -252,7 +252,8 @@ bool BOARD_ADAPTER::IsFootprintShown( FOOTPRINT_ATTR_T aFPAttributes ) const int BOARD_ADAPTER::GetHolePlatingThickness() const noexcept { - return m_board->GetDesignSettings().GetHolePlatingThickness(); + return m_board ? m_board->GetDesignSettings().GetHolePlatingThickness() + : 0.035 * PCB_IU_PER_MM; } @@ -295,11 +296,13 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR // to ensure any item, even outside the board outlines can be seen bool boardEdgesOnly = true; - if( m_board->IsFootprintHolder() || !GetFlag( FL_USE_REALISTIC_MODE ) + if( ( m_board && m_board->IsFootprintHolder() ) || !GetFlag( FL_USE_REALISTIC_MODE ) || !succeedToGetBoardPolygon ) boardEdgesOnly = false; - EDA_RECT bbbox = m_board->ComputeBoundingBox( boardEdgesOnly ); + EDA_RECT bbbox; + if( m_board ) + bbbox = m_board->ComputeBoundingBox( boardEdgesOnly ); // Gives a non null size to avoid issues in zoom / scale calculations if( ( bbbox.GetWidth() == 0 ) && ( bbbox.GetHeight() == 0 ) ) @@ -312,7 +315,7 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR m_boardPos.y = -m_boardPos.y; // The y coord is inverted in 3D viewer - m_copperLayersCount = m_board->GetCopperLayerCount(); + m_copperLayersCount = m_board ? m_board->GetCopperLayerCount() : 2; // Ensure the board has 2 sides for 3D views, because it is hard to find // a *really* single side board in the true life... @@ -322,7 +325,9 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR // Calculate the conversion to apply to all positions. m_biuTo3Dunits = RANGE_SCALE_3D / std::max( m_boardSize.x, m_boardSize.y ); - m_epoxyThickness3DU = m_board->GetDesignSettings().GetBoardThickness() * m_biuTo3Dunits; + m_epoxyThickness3DU = m_board + ? m_board->GetDesignSettings().GetBoardThickness() * m_biuTo3Dunits + : 1.6 * PCB_IU_PER_MM * m_biuTo3Dunits; // !TODO: use value defined by user (currently use default values by ctor m_copperThickness3DU = COPPER_THICKNESS * m_biuTo3Dunits; @@ -463,6 +468,9 @@ bool BOARD_ADAPTER::createBoardPolygon( wxString* aErrorMsg ) { m_board_poly.RemoveAllContours(); + if( !m_board ) + return false; + bool success; if( m_board->IsFootprintHolder() ) diff --git a/3d-viewer/3d_canvas/create_layer_items.cpp b/3d-viewer/3d_canvas/create_layer_items.cpp index 6c64a7748b..1014da0911 100644 --- a/3d-viewer/3d_canvas/create_layer_items.cpp +++ b/3d-viewer/3d_canvas/create_layer_items.cpp @@ -148,6 +148,9 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter ) m_holeCount = 0; m_averageHoleDiameter = 0; + if( !m_board ) + return; + // Prepare track list, convert in a vector. Calc statistic for the holes std::vector trackList; trackList.clear(); diff --git a/3d-viewer/3d_canvas/eda_3d_canvas.cpp b/3d-viewer/3d_canvas/eda_3d_canvas.cpp index 85c8ba14c9..0cb8676c0e 100644 --- a/3d-viewer/3d_canvas/eda_3d_canvas.cpp +++ b/3d-viewer/3d_canvas/eda_3d_canvas.cpp @@ -87,7 +87,7 @@ BEGIN_EVENT_TABLE( EDA_3D_CANVAS, wxGLCanvas ) END_EVENT_TABLE() -EDA_3D_CANVAS::EDA_3D_CANVAS( wxWindow* aParent, const int* aAttribList, BOARD* aBoard, +EDA_3D_CANVAS::EDA_3D_CANVAS( wxWindow* aParent, const int* aAttribList, BOARD_ADAPTER& aBoardAdapter, CAMERA& aCamera, S3D_CACHE* a3DCachePointer ) : HIDPI_GL_CANVAS( aParent, wxID_ANY, aAttribList, wxDefaultPosition, wxDefaultSize, @@ -139,9 +139,6 @@ EDA_3D_CANVAS::EDA_3D_CANVAS( wxWindow* aParent, const int* aAttribList, BOARD* RenderEngineChanged(); - wxASSERT( aBoard != nullptr ); - m_boardAdapter.SetBoard( aBoard ); - m_boardAdapter.SetColorSettings( Pgm().GetSettingsManager().GetColorSettings() ); wxASSERT( a3DCachePointer != nullptr ); diff --git a/3d-viewer/3d_canvas/eda_3d_canvas.h b/3d-viewer/3d_canvas/eda_3d_canvas.h index 52e8d98433..de691acb5e 100644 --- a/3d-viewer/3d_canvas/eda_3d_canvas.h +++ b/3d-viewer/3d_canvas/eda_3d_canvas.h @@ -56,7 +56,7 @@ public: * @param aBoard The board. * @param aSettings the settings options to be used by this canvas. */ - EDA_3D_CANVAS( wxWindow* aParent, const int* aAttribList, BOARD* aBoard, + EDA_3D_CANVAS( wxWindow* aParent, const int* aAttribList, BOARD_ADAPTER& aSettings, CAMERA& aCamera, S3D_CACHE* a3DCachePointer ); ~EDA_3D_CANVAS(); 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 779312eaf6..9fa0565309 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/create_scene.cpp +++ b/3d-viewer/3d_rendering/3d_render_raytracing/create_scene.cpp @@ -1251,6 +1251,9 @@ void RENDER_3D_RAYTRACE::insertHole( const PAD* aPad ) void RENDER_3D_RAYTRACE::addPadsAndVias() { + if( !m_boardAdapter.GetBoard() ) + return; + // Insert plated vertical holes inside the board // Insert vias holes (vertical cylinders) @@ -1279,6 +1282,9 @@ void RENDER_3D_RAYTRACE::addPadsAndVias() void RENDER_3D_RAYTRACE::loadModels( CONTAINER_3D& aDstContainer, bool aSkipMaterialInformation ) { + if( !m_boardAdapter.GetBoard() ) + return; + // Go for all footprints for( FOOTPRINT* fp : m_boardAdapter.GetBoard()->Footprints() ) { diff --git a/3d-viewer/3d_rendering/legacy/create_scene.cpp b/3d-viewer/3d_rendering/legacy/create_scene.cpp index 275236e3a3..82a9d38744 100644 --- a/3d-viewer/3d_rendering/legacy/create_scene.cpp +++ b/3d-viewer/3d_rendering/legacy/create_scene.cpp @@ -721,6 +721,9 @@ void RENDER_3D_LEGACY::generateCylinder( const SFVEC2F& aCenter, float aInnerRad void RENDER_3D_LEGACY::generateViasAndPads() { + if( !m_boardAdapter.GetBoard() ) + return; + const int platingThickness = m_boardAdapter.GetHolePlatingThickness(); const float platingThickness3d = platingThickness * m_boardAdapter.BiuTo3dUnits(); @@ -862,6 +865,9 @@ void RENDER_3D_LEGACY::generateViasAndPads() void RENDER_3D_LEGACY::load3dModels( REPORTER* aStatusReporter ) { + 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 ) ) diff --git a/3d-viewer/3d_rendering/legacy/render_3d_legacy.cpp b/3d-viewer/3d_rendering/legacy/render_3d_legacy.cpp index af6f1709c1..0468d9e880 100644 --- a/3d-viewer/3d_rendering/legacy/render_3d_legacy.cpp +++ b/3d-viewer/3d_rendering/legacy/render_3d_legacy.cpp @@ -1174,6 +1174,8 @@ void RENDER_3D_LEGACY::renderSolderMaskLayer( PCB_LAYER_ID aLayerID, float aZPos void RENDER_3D_LEGACY::render3dModelsSelected( bool aRenderTopOrBot, bool aRenderTransparentOnly, bool aRenderSelectedOnly ) { + if( !m_boardAdapter.GetBoard() ) + return; MODEL_3D::BeginDrawMulti( !aRenderSelectedOnly ); diff --git a/3d-viewer/3d_viewer/eda_3d_viewer.cpp b/3d-viewer/3d_viewer/eda_3d_viewer.cpp index 2d18096040..10ae80b782 100644 --- a/3d-viewer/3d_viewer/eda_3d_viewer.cpp +++ b/3d-viewer/3d_viewer/eda_3d_viewer.cpp @@ -112,7 +112,7 @@ EDA_3D_VIEWER_FRAME::EDA_3D_VIEWER_FRAME( KIWAY *aKiway, PCB_BASE_FRAME *aParent m_canvas = new EDA_3D_CANVAS( this, OGL_ATT_LIST::GetAttributesList( m_boardAdapter.GetAntiAliasingMode() ), - aParent->GetBoard(), m_boardAdapter, m_currentCamera, + m_boardAdapter, m_currentCamera, Prj().Get3DCacheManager() ); auto config = Pgm().GetSettingsManager().GetAppSettings(); diff --git a/pcbnew/pcb_base_frame.cpp b/pcbnew/pcb_base_frame.cpp index d5991371c5..54ce8001ba 100644 --- a/pcbnew/pcb_base_frame.cpp +++ b/pcbnew/pcb_base_frame.cpp @@ -452,6 +452,11 @@ EDA_3D_VIEWER_FRAME* PCB_BASE_FRAME::CreateAndShow3D_Frame() if( wxWindow::FindFocus() != draw3DFrame ) draw3DFrame->SetFocus(); + // Allocate a slice of time to display the 3D frame + wxSafeYield(); + // And show the current board + Update3DView( true, true ); + return draw3DFrame; }