From 20b7d49c816e423fb26aafaba467698a06b52ca4 Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Sun, 10 Aug 2025 20:19:32 -0700 Subject: [PATCH] ADDED: Action to embed all 3d models referenced Moves through the footprints and replaces external references with internal embedded files Fixes https://gitlab.com/kicad/code/kicad/-/issues/20847 --- pcbnew/tools/pcb_actions.cpp | 6 ++++ pcbnew/tools/pcb_actions.h | 1 + pcbnew/tools/pcb_control.cpp | 66 +++++++++++++++++++++++++++++++++++- pcbnew/tools/pcb_control.h | 1 + 4 files changed, 73 insertions(+), 1 deletion(-) diff --git a/pcbnew/tools/pcb_actions.cpp b/pcbnew/tools/pcb_actions.cpp index e8372cb88a..b8722c19d4 100644 --- a/pcbnew/tools/pcb_actions.cpp +++ b/pcbnew/tools/pcb_actions.cpp @@ -1073,6 +1073,12 @@ TOOL_ACTION PCB_ACTIONS::generateBOM( TOOL_ACTION_ARGS() .Tooltip( _( "Create bill of materials from board" ) ) .Icon( BITMAPS::post_bom ) ); +TOOL_ACTION PCB_ACTIONS::collect3DModels( TOOL_ACTION_ARGS() + .Name( "pcbnew.EditorControl.collect3DModels" ) + .Scope( AS_GLOBAL ) + .FriendlyName( _( "Collect And Embed 3D Models" ) ) + .Tooltip( _( "Collect footprint 3D models and embed them into the board" ) ) ); + // Track & via size control TOOL_ACTION PCB_ACTIONS::trackWidthInc( TOOL_ACTION_ARGS() .Name( "pcbnew.EditorControl.trackWidthInc" ) diff --git a/pcbnew/tools/pcb_actions.h b/pcbnew/tools/pcb_actions.h index 16d39c29c9..df026581d0 100644 --- a/pcbnew/tools/pcb_actions.h +++ b/pcbnew/tools/pcb_actions.h @@ -552,6 +552,7 @@ public: static TOOL_ACTION inspectConstraints; static TOOL_ACTION diffFootprint; static TOOL_ACTION showFootprintAssociations; + static TOOL_ACTION collect3DModels; // Appearance controls static TOOL_ACTION clearHighlight; // Turns off highlight and resets previous highlight diff --git a/pcbnew/tools/pcb_control.cpp b/pcbnew/tools/pcb_control.cpp index eb82ad1506..7315b9d106 100644 --- a/pcbnew/tools/pcb_control.cpp +++ b/pcbnew/tools/pcb_control.cpp @@ -51,7 +51,12 @@ #include #include #include +#include #include +#include +#include <3d_cache/3d_cache.h> +#include +#include #include #include #include @@ -1999,6 +2004,64 @@ int PCB_CONTROL::FlipPcbView( const TOOL_EVENT& aEvent ) return 0; } + +int PCB_CONTROL::CollectAndEmbed3DModels( const TOOL_EVENT& aEvent ) +{ + BOARD* brd = board(); + + if( !brd ) + return 0; + + PROJECT& prj = m_frame->Prj(); + S3D_CACHE* cache = PROJECT_PCB::Get3DCacheManager( &prj ); + FILENAME_RESOLVER* resolver = cache ? cache->GetResolver() : nullptr; + + wxString workingPath = prj.GetProjectPath(); + std::vector stack; + stack.push_back( brd->GetEmbeddedFiles() ); + + BOARD_COMMIT commit( m_frame ); + int embeddedCount = 0; + + for( FOOTPRINT* fp : brd->Footprints() ) + { + bool fpModified = false; + + for( FP_3DMODEL& model : fp->Models() ) + { + if( model.m_Filename.StartsWith( FILEEXT::KiCadUriPrefix ) ) + continue; + + wxString fullPath = + resolver ? resolver->ResolvePath( model.m_Filename, workingPath, stack ) : model.m_Filename; + wxFileName fname( fullPath ); + + if( fname.Exists() ) + { + if( EMBEDDED_FILES::EMBEDDED_FILE* file = brd->GetEmbeddedFiles()->AddFile( fname, false ) ) + { + model.m_Filename = file->GetLink(); + fpModified = true; + embeddedCount++; + } + } + } + + if( fpModified ) + commit.Modify( fp ); + } + + if( embeddedCount > 0 ) + { + commit.Push( _( "Embed 3D Models" ) ); + wxString msg = wxString::Format( _( "%d 3D model(s) successfully embedded." ), embeddedCount ); + m_frame->GetInfoBar()->ShowMessageFor( msg, 5000 ); + } + + return 0; +} + + // clang-format off void PCB_CONTROL::setTransitions() { @@ -2080,7 +2143,8 @@ void PCB_CONTROL::setTransitions() Go( &PCB_CONTROL::SnapModeFeedback, PCB_EVENTS::SnappingModeChangedByKeyEvent() ); // Miscellaneous - Go( &PCB_CONTROL::InteractiveDelete, ACTIONS::deleteTool.MakeEvent() ); + Go( &PCB_CONTROL::InteractiveDelete, ACTIONS::deleteTool.MakeEvent() ); + Go( &PCB_CONTROL::CollectAndEmbed3DModels, PCB_ACTIONS::collect3DModels.MakeEvent() ); // Append control Go( &PCB_CONTROL::AppendBoardFromFile, PCB_ACTIONS::appendBoard.MakeEvent() ); diff --git a/pcbnew/tools/pcb_control.h b/pcbnew/tools/pcb_control.h index bc4163a63d..abdc84c5bf 100644 --- a/pcbnew/tools/pcb_control.h +++ b/pcbnew/tools/pcb_control.h @@ -103,6 +103,7 @@ public: int AppendBoardFromFile( const TOOL_EVENT& aEvent ); int AppendBoard( PCB_IO& pi, wxString& fileName ); int UpdateMessagePanel( const TOOL_EVENT& aEvent ); + int CollectAndEmbed3DModels( const TOOL_EVENT& aEvent ); int FlipPcbView( const TOOL_EVENT& aEvent );