Allow embedded files to come from components

as well as parent containers, part II.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/20210
This commit is contained in:
Jeff Young 2025-04-24 11:33:02 +01:00
parent c2be7fa3e6
commit 524575a595
36 changed files with 225 additions and 102 deletions

View File

@ -141,12 +141,13 @@ S3D_CACHE::~S3D_CACHE()
SCENEGRAPH* S3D_CACHE::load( const wxString& aModelFile, const wxString& aBasePath,
S3D_CACHE_ENTRY** aCachePtr, const EMBEDDED_FILES* aEmbeddedFiles )
S3D_CACHE_ENTRY** aCachePtr,
std::vector<const EMBEDDED_FILES*> aEmbeddedFilesStack )
{
if( aCachePtr )
*aCachePtr = nullptr;
wxString full3Dpath = m_FNResolver->ResolvePath( aModelFile, aBasePath, aEmbeddedFiles );
wxString full3Dpath = m_FNResolver->ResolvePath( aModelFile, aBasePath, aEmbeddedFilesStack );
if( full3Dpath.empty() )
{
@ -212,9 +213,9 @@ SCENEGRAPH* S3D_CACHE::load( const wxString& aModelFile, const wxString& aBasePa
SCENEGRAPH* S3D_CACHE::Load( const wxString& aModelFile, const wxString& aBasePath,
const EMBEDDED_FILES* aEmbeddedFiles )
std::vector<const EMBEDDED_FILES*> aEmbeddedFilesStack )
{
return load( aModelFile, aBasePath, nullptr, aEmbeddedFiles );
return load( aModelFile, aBasePath, nullptr, aEmbeddedFilesStack );
}
@ -548,10 +549,10 @@ void S3D_CACHE::ClosePlugins()
S3DMODEL* S3D_CACHE::GetModel( const wxString& aModelFileName, const wxString& aBasePath,
const EMBEDDED_FILES* aEmbeddedFiles )
std::vector<const EMBEDDED_FILES*> aEmbeddedFilesStack )
{
S3D_CACHE_ENTRY* cp = nullptr;
SCENEGRAPH* sp = load( aModelFileName, aBasePath, &cp, aEmbeddedFiles );
SCENEGRAPH* sp = load( aModelFileName, aBasePath, &cp, aEmbeddedFilesStack );
if( !sp )
return nullptr;

View File

@ -95,11 +95,12 @@ public:
*
* @param aModelFile is the partial or full path to the model to be loaded.
* @param aBasePath is the path to search for any relative files
* @param aEmbeddedFiles is a pointer to the embedded files list.
* @param aEmbeddedFilesStack is a list of pointers to the embedded files list. They will
* be searched from the front of the list.
* @return true if the model was successfully loaded, otherwise false.
*/
SCENEGRAPH* Load( const wxString& aModelFile, const wxString& aBasePath,
const EMBEDDED_FILES* aEmbeddedFiles );
std::vector<const EMBEDDED_FILES*> aEmbeddedFilesStack );
FILENAME_RESOLVER* GetResolver() noexcept;
@ -128,11 +129,12 @@ public:
*
* @param aModelFileName is the full path to the model to be loaded.
* @param aBasePath is the path to search for any relative files.
* @param aEmbeddedFiles is a pointer to the embedded files list.
* @param aEmbeddedFilesStack is a stack of pointers to the embedded files lists. They will
* be searched from the bottom of the stack.
* @return is a pointer to the render data or NULL if not available.
*/
S3DMODEL* GetModel( const wxString& aModelFileName, const wxString& aBasePath,
const EMBEDDED_FILES* aEmbeddedFiles );
std::vector<const EMBEDDED_FILES*> aEmbeddedFilesStack );
/**
* Delete up old cache files in cache directory.
@ -174,7 +176,7 @@ private:
// the real load function (can supply a cache entry pointer to member functions)
SCENEGRAPH* load( const wxString& aModelFile, const wxString& aBasePath,
S3D_CACHE_ENTRY** aCachePtr = nullptr,
const EMBEDDED_FILES* aEmbeddedFiles = nullptr );
std::vector<const EMBEDDED_FILES*> aEmbeddedFilesStack = {} );
/// Cache entries.
std::list< S3D_CACHE_ENTRY* > m_CacheList;

View File

@ -451,7 +451,7 @@ void EDA_3D_CANVAS::DoRePaint()
return;
}
// Don't attend to ray trace if OpenGL doesn't support it.
// Don't attempt to ray trace if OpenGL doesn't support it.
if( !m_opengl_supports_raytracing )
{
m_3d_render = m_3d_render_opengl;
@ -459,7 +459,7 @@ void EDA_3D_CANVAS::DoRePaint()
m_boardAdapter.m_Cfg->m_Render.engine = RENDER_ENGINE::OPENGL;
}
// Check if a raytacing was requested and need to switch to raytracing mode
// Check if a raytracing was requested and need to switch to raytracing mode
if( m_boardAdapter.m_Cfg->m_Render.engine == RENDER_ENGINE::OPENGL )
{
const bool was_camera_changed = m_camera.ParametersChanged();

View File

@ -157,7 +157,7 @@ void EDA_3D_MODEL_VIEWER::Set3DModel( const wxString& aModelPathName)
if( m_cacheManager )
{
const S3DMODEL* model = m_cacheManager->GetModel( aModelPathName, wxEmptyString, nullptr );
const S3DMODEL* model = m_cacheManager->GetModel( aModelPathName, wxEmptyString, {} );
if( model )
Set3DModel( (const S3DMODEL &)*model );

View File

@ -926,8 +926,8 @@ void RENDER_3D_OPENGL::load3dModels( REPORTER* aStatusReporter )
// Go for all footprints
for( const FOOTPRINT* footprint : m_boardAdapter.GetBoard()->Footprints() )
{
wxString libraryName = footprint->GetFPID().GetLibNickname();
wxString footprintBasePath = wxEmptyString;
wxString libraryName = footprint->GetFPID().GetLibNickname();
wxString footprintBasePath = wxEmptyString;
if( m_boardAdapter.GetBoard()->GetProject() )
{
@ -965,10 +965,13 @@ void RENDER_3D_OPENGL::load3dModels( REPORTER* aStatusReporter )
if( !m_3dModelMap.contains( fp_model.m_Filename ) )
{
// It is not present, try get it from cache
const S3DMODEL* modelPtr =
m_boardAdapter.Get3dCacheManager()->GetModel( fp_model.m_Filename,
footprintBasePath,
footprint );
std::vector<const EMBEDDED_FILES*> embeddedFilesStack;
embeddedFilesStack.push_back( footprint->GetEmbeddedFiles() );
embeddedFilesStack.push_back( m_boardAdapter.GetBoard()->GetEmbeddedFiles() );
const S3DMODEL* modelPtr = m_boardAdapter.Get3dCacheManager()->GetModel( fp_model.m_Filename,
footprintBasePath,
embeddedFilesStack );
// only add it if the return is not NULL
if( modelPtr )

View File

@ -1291,8 +1291,12 @@ void RENDER_3D_RAYTRACE_BASE::load3DModels( CONTAINER_3D& aDstContainer,
continue;
// get it from cache
const S3DMODEL* modelPtr =
cacheMgr->GetModel( model.m_Filename, footprintBasePath, fp );
std::vector<const EMBEDDED_FILES*> embeddedFilesStack;
embeddedFilesStack.push_back( fp->GetEmbeddedFiles() );
embeddedFilesStack.push_back( m_boardAdapter.GetBoard()->GetEmbeddedFiles() );
const S3DMODEL* modelPtr = cacheMgr->GetModel( model.m_Filename, footprintBasePath,
embeddedFilesStack );
// only add it if the return is not NULL.
if( modelPtr )

View File

@ -27,6 +27,7 @@
#include "panel_preview_3d_model.h"
#include <dialogs/dialog_unit_entry.h>
#include <3d_canvas/eda_3d_canvas.h>
#include <3d_rendering/opengl/render_3d_opengl.h>
#include <tool/tool_manager.h>
#include <tool/tool_dispatcher.h>
#include <tools/eda_3d_actions.h>
@ -64,6 +65,7 @@ PANEL_PREVIEW_3D_MODEL::PANEL_PREVIEW_3D_MODEL( wxWindow* aParent, PCB_BASE_FRAM
m_dummyBoard = new BOARD();
m_dummyBoard->SetProject( &aFrame->Prj(), true );
m_dummyBoard->SetEmbeddedFilesDelegate( aFrame->GetBoard() );
// This board will only be used to hold a footprint for viewing
m_dummyBoard->SetBoardUse( BOARD_USE::FPHOLDER );

View File

@ -477,7 +477,7 @@ bool DIALOG_PAGES_SETTINGS::SavePageSettings()
if( fileName != BASE_SCREEN::m_DrawingSheetFileName )
{
wxString fullFileName = m_filenameResolver->ResolvePath( fileName, m_projectPath,
m_embeddedFiles );
{ m_embeddedFiles } );
BASE_SCREEN::m_DrawingSheetFileName = fileName;

View File

@ -244,7 +244,7 @@ bool FILENAME_RESOLVER::UpdatePathList( const std::vector< SEARCH_PATH >& aPathL
wxString FILENAME_RESOLVER::ResolvePath( const wxString& aFileName, const wxString& aWorkingPath,
const EMBEDDED_FILES* aFiles )
std::vector<const EMBEDDED_FILES*> aEmbeddedFilesStack )
{
std::lock_guard<std::mutex> lock( mutex_resolver );
@ -266,15 +266,20 @@ wxString FILENAME_RESOLVER::ResolvePath( const wxString& aFileName, const wxStri
// Check to see if the file is a URI for an embedded file.
if( tname.StartsWith( FILEEXT::KiCadUriPrefix + "://" ) )
{
if( !aFiles )
if( aEmbeddedFilesStack.empty() )
{
wxLogTrace( wxT( "KICAD_EMBED" ),
wxT( "No EMBEDDED_FILES object provided for kicad_embed URI" ) );
return wxEmptyString;
}
wxString path = tname.Mid( 14 );
wxFileName temp_file = aFiles->GetTemporaryFileName( path );
wxString path = tname.Mid( wxString( FILEEXT::KiCadUriPrefix + "://" ).length() );
wxFileName temp_file = aEmbeddedFilesStack[0]->GetTemporaryFileName( path );
int ii = 1;
while( !temp_file.IsOk() && ii < (int) aEmbeddedFilesStack.size() )
temp_file = aEmbeddedFilesStack[ii++]->GetTemporaryFileName( path );
if( !temp_file.IsOk() )
{

View File

@ -69,8 +69,8 @@ DIALOG_SIM_MODEL<T>::DIALOG_SIM_MODEL( wxWindow* aParent, EDA_BASE_FRAME* aFrame
m_frame( aFrame ),
m_symbol( aSymbol ),
m_fields( aFields ),
m_libraryModelsMgr( &Prj(), nullptr ),
m_builtinModelsMgr( &Prj(), nullptr ),
m_libraryModelsMgr( &Prj() ),
m_builtinModelsMgr( &Prj() ),
m_prevModel( nullptr ),
m_curModelType( SIM_MODEL::TYPE::NONE ),
m_scintillaTricksCode( nullptr ),
@ -83,12 +83,15 @@ DIALOG_SIM_MODEL<T>::DIALOG_SIM_MODEL( wxWindow* aParent, EDA_BASE_FRAME* aFrame
m_infoBar->AddCloseButton();
if constexpr (std::is_same_v<T, SCH_SYMBOL>)
m_files = aSymbol.Schematic();
else
m_files = &aSymbol;
{
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( &aSymbol );
m_filesStack.push_back( symbol->Schematic()->GetEmbeddedFiles() );
}
m_libraryModelsMgr.SetFiles( m_files );
m_builtinModelsMgr.SetFiles( m_files );
m_filesStack.push_back( aSymbol.GetEmbeddedFiles() );
m_libraryModelsMgr.SetFilesStack( m_filesStack );
m_builtinModelsMgr.SetFilesStack( m_filesStack );
for( SCH_PIN* pin : aSymbol.GetPins() )
{
@ -1256,11 +1259,13 @@ void DIALOG_SIM_MODEL<T>::onBrowseButtonClick( wxCommandEvent& aEvent )
if( customize.GetEmbed() )
{
EMBEDDED_FILES::EMBEDDED_FILE* result = m_files->AddFile( fn, false );
EMBEDDED_FILES::EMBEDDED_FILE* result = m_filesStack[0]->AddFile( fn, false );
path = result->GetLink();
}
else if( fn.MakeRelativeTo( Prj().GetProjectPath() ) && !fn.GetFullPath().StartsWith( wxS( ".." ) ) )
{
path = fn.GetFullPath();
}
WX_STRING_REPORTER reporter;

View File

@ -125,17 +125,17 @@ private:
bool isIbisLoaded() { return dynamic_cast<const SIM_LIBRARY_IBIS*>( library() ); }
private:
EDA_BASE_FRAME* m_frame;
T& m_symbol;
std::vector<SCH_FIELD>& m_fields;
EDA_BASE_FRAME* m_frame;
T& m_symbol;
std::vector<SCH_FIELD>& m_fields;
EMBEDDED_FILES* m_files;
SIM_LIB_MGR m_libraryModelsMgr;
SIM_LIB_MGR m_builtinModelsMgr;
wxString m_prevLibrary;
const SIM_MODEL* m_prevModel;
std::vector<EMBEDDED_FILES*> m_filesStack;
SIM_LIB_MGR m_libraryModelsMgr;
SIM_LIB_MGR m_builtinModelsMgr;
wxString m_prevLibrary;
const SIM_MODEL* m_prevModel;
std::map<wxString, int> m_modelListBoxEntryToLibraryIdx;
std::map<wxString, int> m_modelListBoxEntryToLibraryIdx;
std::vector<SCH_PIN*> m_sortedPartPins; ///< Pins of the current part.
std::map<SIM_MODEL::DEVICE_T, SIM_MODEL::TYPE> m_curModelTypeOfDeviceType;

View File

@ -93,7 +93,7 @@ void SCH_EDIT_FRAME::LoadDrawingSheet()
wxString filename = resolver.ResolvePath( settings.m_SchDrawingSheetFileName,
Prj().GetProjectPath(),
Schematic().GetEmbeddedFiles() );
{ Schematic().GetEmbeddedFiles() } );
wxString msg;
if( !DS_DATA_MODEL::GetTheInstance().LoadDrawingSheet( filename, &msg ) )
@ -220,7 +220,7 @@ void SCH_EDIT_FRAME::saveProjectSettings()
wxFileName layoutfn( resolve.ResolvePath( BASE_SCREEN::m_DrawingSheetFileName,
Prj().GetProjectPath(),
Schematic().GetEmbeddedFiles() ) );
{ Schematic().GetEmbeddedFiles() } ) );
bool success = true;

View File

@ -224,7 +224,7 @@ void EESCHEMA_JOBS_HANDLER::InitRenderSettings( SCH_RENDER_SETTINGS* aRenderSett
resolve.SetProgramBase( &Pgm() );
wxString absolutePath = resolve.ResolvePath( path, wxGetCwd(),
aSch->GetEmbeddedFiles() );
{ aSch->GetEmbeddedFiles() } );
if( !DS_DATA_MODEL::GetTheInstance().LoadDrawingSheet( absolutePath, &msg ) )
{

View File

@ -1740,7 +1740,7 @@ int ERC_TESTER::TestSimModelIssues()
{
WX_STRING_REPORTER reporter;
int err_count = 0;
SIM_LIB_MGR libMgr( &m_schematic->Prj(), m_schematic );
SIM_LIB_MGR libMgr( &m_schematic->Prj() );
for( SCH_SHEET_PATH& sheet : m_sheetList )
{

View File

@ -63,8 +63,11 @@ std::string NAME_GENERATOR::Generate( const std::string& aProposedName )
NETLIST_EXPORTER_SPICE::NETLIST_EXPORTER_SPICE( SCHEMATIC* aSchematic ) :
NETLIST_EXPORTER_BASE( aSchematic ),
m_libMgr( &aSchematic->Prj(), aSchematic )
m_libMgr( &aSchematic->Prj() )
{
std::vector<EMBEDDED_FILES*> embeddedFilesStack;
embeddedFilesStack.push_back( aSchematic->GetEmbeddedFiles() );
m_libMgr.SetFilesStack( embeddedFilesStack );
}

View File

@ -1516,7 +1516,7 @@ void SCH_EDIT_FRAME::OnExit( wxCommandEvent& event )
void SCH_EDIT_FRAME::RefreshOperatingPointDisplay()
{
SCHEMATIC_SETTINGS& settings = m_schematic->Settings();
SIM_LIB_MGR simLibMgr( &Prj(), &Schematic() );
SIM_LIB_MGR simLibMgr( &Prj() );
NULL_REPORTER devnull;
// Patch for bug early in V7.99 dev
@ -1608,8 +1608,13 @@ void SCH_EDIT_FRAME::RefreshOperatingPointDisplay()
}
else
{
SIM_MODEL& model = simLibMgr.CreateModel( &GetCurrentSheet(), *symbol,
devnull ).model;
std::vector<EMBEDDED_FILES*> embeddedFilesStack;
embeddedFilesStack.push_back( m_schematic->GetEmbeddedFiles() );
embeddedFilesStack.push_back( symbol->GetEmbeddedFiles() );
simLibMgr.SetFilesStack( embeddedFilesStack );
SIM_MODEL& model = simLibMgr.CreateModel( &GetCurrentSheet(), *symbol, devnull ).model;
SPICE_ITEM spiceItem;
spiceItem.refName = ref;

View File

@ -749,8 +749,15 @@ void SCH_FIELD::OnScintillaCharAdded( SCINTILLA_TRICKS* aScintillaTricks,
{
NULL_REPORTER devnull;
SCH_SHEET_PATH& sheet = schematic->CurrentSheet();
SIM_LIB_MGR mgr( &schematic->Prj(), schematic );
SIM_MODEL& model = mgr.CreateModel( &sheet, *symbol, devnull ).model;
SIM_LIB_MGR mgr( &schematic->Prj() );
std::vector<EMBEDDED_FILES*> embeddedFilesStack;
embeddedFilesStack.push_back( schematic->GetEmbeddedFiles() );
embeddedFilesStack.push_back( symbol->GetEmbeddedFiles() );
mgr.SetFilesStack( embeddedFilesStack );
SIM_MODEL& model = mgr.CreateModel( &sheet, *symbol, devnull ).model;
for( wxString pin : model.GetPinNames() )
{

View File

@ -1311,7 +1311,14 @@ bool SCH_SYMBOL::ResolveTextVar( const SCH_SHEET_PATH* aPath, wxString* token, i
if( range.IsEmpty() )
range = wxS( "~A" );
SIM_LIB_MGR simLibMgr( &schematic->Prj(), schematic );
SIM_LIB_MGR simLibMgr( &schematic->Prj() );
std::vector<EMBEDDED_FILES*> embeddedFilesStack;
embeddedFilesStack.push_back( schematic->GetEmbeddedFiles() );
embeddedFilesStack.push_back( GetLibSymbolRef()->GetEmbeddedFiles() );
simLibMgr.SetFilesStack( embeddedFilesStack );
NULL_REPORTER devnull;
SIM_MODEL& model = simLibMgr.CreateModel( aPath, const_cast<SCH_SYMBOL&>( *this ),
devnull ).model;
@ -2027,6 +2034,12 @@ BITMAPS SCH_SYMBOL::GetMenuImage() const
}
EMBEDDED_FILES* SCH_SYMBOL::GetEmbeddedFiles()
{
return GetLibSymbolRef()->GetEmbeddedFiles();
}
void SCH_SYMBOL::MirrorHorizontally( int aCenter )
{
int dx = m_pos.x;

View File

@ -684,6 +684,12 @@ public:
/// Set the selected unit of this symbol for all sheets.
void SetUnitSelection( int aUnitSelection );
/**
* SCH_SYMBOLs don't currently support embedded files, but their LIB_SYMBOL counterparts
* do.
*/
EMBEDDED_FILES* GetEmbeddedFiles() override;
void Move( const VECTOR2I& aMoveVector ) override
{
if( aMoveVector == VECTOR2I( 0, 0 ) )

View File

@ -41,8 +41,7 @@
using namespace std::placeholders;
SIM_LIB_MGR::SIM_LIB_MGR( const PROJECT* aPrj, EMBEDDED_FILES* aFiles ) :
m_files( aFiles ),
SIM_LIB_MGR::SIM_LIB_MGR( const PROJECT* aPrj ) :
m_project( aPrj ),
m_forceFullParse( false )
{
@ -62,7 +61,12 @@ wxString SIM_LIB_MGR::ResolveLibraryPath( const wxString& aLibraryPath, REPORTER
resolver.SetProject( m_project );
wxString expandedPath = resolver.ResolvePath( aLibraryPath, wxEmptyString, m_files );
std::vector<const EMBEDDED_FILES*> embeddedFilesStack;
for( const EMBEDDED_FILES* embeddedFiles : m_embeddedFilesStack )
embeddedFilesStack.push_back( embeddedFiles );
wxString expandedPath = resolver.ResolvePath( aLibraryPath, wxEmptyString, embeddedFilesStack );
wxFileName fn( expandedPath );

View File

@ -39,14 +39,14 @@ class SCH_SYMBOL;
class SIM_LIB_MGR
{
public:
SIM_LIB_MGR( const PROJECT* aPrj, EMBEDDED_FILES* aFiles );
SIM_LIB_MGR( const PROJECT* aPrj );
virtual ~SIM_LIB_MGR() = default;
void SetForceFullParse() { m_forceFullParse = true; }
void Clear();
void SetFiles( EMBEDDED_FILES* aFiles ) { m_files = aFiles; }
void SetFilesStack( std::vector<EMBEDDED_FILES*> aFilesStack ) { m_embeddedFilesStack = aFilesStack; }
void SetLibrary( const wxString& aLibraryPath, REPORTER& aReporter );
@ -83,7 +83,7 @@ public:
REPORTER& aReporter );
private:
EMBEDDED_FILES* m_files;
std::vector<EMBEDDED_FILES*> m_embeddedFilesStack;
const PROJECT* m_project;
bool m_forceFullParse;
std::map<wxString, std::unique_ptr<SIM_LIBRARY>> m_libraries;

View File

@ -1668,14 +1668,20 @@ void SIM_MODEL::MigrateSimModel( T& aSymbol, const PROJECT* aProject )
if( !lib.IsEmpty() )
{
WX_STRING_REPORTER reporter;
SIM_LIB_MGR libMgr( aProject, nullptr );
std::vector<SCH_FIELD> emptyFields;
WX_STRING_REPORTER reporter;
SIM_LIB_MGR libMgr( aProject );
std::vector<SCH_FIELD> emptyFields;
std::vector<EMBEDDED_FILES*> embeddedFilesStack;
if constexpr (std::is_same_v<T, SCH_SYMBOL>)
libMgr.SetFiles( aSymbol.Schematic() );
else
libMgr.SetFiles( &aSymbol );
{
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( &aSymbol );
embeddedFilesStack.push_back( symbol->Schematic()->GetEmbeddedFiles() );
}
embeddedFilesStack.push_back( aSymbol.GetEmbeddedFiles() );
libMgr.SetFilesStack( embeddedFilesStack );
// Pull out any following parameters from model name
model = model.BeforeFirst( ' ', &modelLineParams );

View File

@ -53,8 +53,7 @@ std::vector<std::string> SPICE_GENERATOR_IBIS::CurrentNames( const SPICE_ITEM& a
std::string SPICE_GENERATOR_IBIS::IbisDevice( const SPICE_ITEM& aItem, SCHEMATIC* aSchematic,
const wxString& aCacheDir,
REPORTER& aReporter ) const
const wxString& aCacheDir, REPORTER& aReporter ) const
{
std::string ibisLibFilename = GetFieldValue( &aItem.fields, SIM_LIBRARY::LIBRARY_FIELD );
std::string ibisCompName = GetFieldValue( &aItem.fields, SIM_LIBRARY::NAME_FIELD );
@ -63,8 +62,13 @@ std::string SPICE_GENERATOR_IBIS::IbisDevice( const SPICE_ITEM& aItem, SCHEMATIC
bool diffMode = GetFieldValue( &aItem.fields, SIM_LIBRARY_IBIS::DIFF_FIELD ) == "1";
WX_STRING_REPORTER reporter;
SIM_LIB_MGR mgr( &aSchematic->Prj(), aSchematic );
wxString path = mgr.ResolveLibraryPath( ibisLibFilename, reporter );
SIM_LIB_MGR mgr( &aSchematic->Prj() );
std::vector<EMBEDDED_FILES*> embeddedFilesStack;
embeddedFilesStack.push_back( aSchematic->GetEmbeddedFiles() );
mgr.SetFilesStack( embeddedFilesStack );
wxString path = mgr.ResolveLibraryPath( ibisLibFilename, reporter );
if( reporter.HasMessage() )
THROW_IO_ERROR( reporter.GetMessages() );

View File

@ -1664,8 +1664,15 @@ void SIMULATOR_FRAME_UI::UpdateTunerValue( const SCH_SHEET_PATH& aSheetPath, con
}
NULL_REPORTER devnull;
SIM_LIB_MGR mgr( &m_schematicFrame->Prj(), &m_schematicFrame->Schematic() );
SIM_MODEL& model = mgr.CreateModel( &aSheetPath, *symbol, devnull ).model;
SIM_LIB_MGR mgr( &m_schematicFrame->Prj() );
std::vector<EMBEDDED_FILES*> embeddedFilesStack;
embeddedFilesStack.push_back( m_schematicFrame->Schematic().GetEmbeddedFiles() );
embeddedFilesStack.push_back( symbol->GetEmbeddedFiles() );
mgr.SetFilesStack( embeddedFilesStack );
SIM_MODEL& model = mgr.CreateModel( &aSheetPath, *symbol, devnull ).model;
const SIM_MODEL::PARAM* tunerParam = model.GetTunerParam();

View File

@ -580,17 +580,22 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item->GetParent() );
WX_STRING_REPORTER reporter;
SIM_LIB_MGR mgr( &m_frame->Prj(), &m_frame->Schematic() );
SIM_LIB_MGR mgr( &m_frame->Prj() );
SIM_MODEL& model = mgr.CreateModel( &sheet, *symbol, reporter ).model;
std::vector<EMBEDDED_FILES*> embeddedFilesStack;
embeddedFilesStack.push_back( m_frame->Schematic().GetEmbeddedFiles() );
embeddedFilesStack.push_back( symbol->GetEmbeddedFiles() );
mgr.SetFilesStack( embeddedFilesStack );
SIM_MODEL& model = mgr.CreateModel( &sheet, *symbol, reporter ).model;
if( reporter.HasMessage() )
THROW_IO_ERROR( reporter.GetMessages() );
SPICE_ITEM spiceItem;
spiceItem.refName = symbol->GetRef( &sheet ).ToStdString();
std::vector<std::string> currentNames =
model.SpiceGenerator().CurrentNames( spiceItem );
std::vector<std::string> currentNames = model.SpiceGenerator().CurrentNames( spiceItem );
if( currentNames.size() == 0 )
{

View File

@ -100,10 +100,11 @@ public:
*
* @param aFileName The configured file path to resolve.
* @param aWorkingPath The current working path for relative path resolutions.
* @param aFiles The embedded files object to use for embedded file resolution.
* @param aEmbeddedFilesStack is a list of pointers to the embedded files list. They will
* be searched from the front of the list.
*/
wxString ResolvePath( const wxString& aFileName, const wxString& aWorkingPath,
const EMBEDDED_FILES* aFiles );
std::vector<const EMBEDDED_FILES*> aEmbeddedFilesStack );
/**
* Produce a relative path based on the existing search directories or returns the same path

View File

@ -74,11 +74,20 @@ VECTOR2I BOARD_ITEM::ZeroOffset( 0, 0 );
BOARD::BOARD() :
BOARD_ITEM_CONTAINER( (BOARD_ITEM*) nullptr, PCB_T ), m_LegacyDesignSettingsLoaded( false ),
m_LegacyCopperEdgeClearanceLoaded( false ), m_LegacyNetclassesLoaded( false ), m_boardUse( BOARD_USE::NORMAL ),
m_timeStamp( 1 ), m_paper( PAGE_INFO::A4 ), m_project( nullptr ), m_userUnits( EDA_UNITS::MM ),
m_designSettings( new BOARD_DESIGN_SETTINGS( nullptr, "board.design_settings" ) ), m_NetInfo( this ),
m_embedFonts( false ), m_componentClassManager( std::make_unique<COMPONENT_CLASS_MANAGER>( this ) ),
BOARD_ITEM_CONTAINER( (BOARD_ITEM*) nullptr, PCB_T ),
m_LegacyDesignSettingsLoaded( false ),
m_LegacyCopperEdgeClearanceLoaded( false ),
m_LegacyNetclassesLoaded( false ),
m_boardUse( BOARD_USE::NORMAL ),
m_timeStamp( 1 ),
m_paper( PAGE_INFO::A4 ),
m_project( nullptr ),
m_userUnits( EDA_UNITS::MM ),
m_designSettings( new BOARD_DESIGN_SETTINGS( nullptr, "board.design_settings" ) ),
m_NetInfo( this ),
m_embedFonts( false ),
m_embeddedFilesDelegate( nullptr ),
m_componentClassManager( std::make_unique<COMPONENT_CLASS_MANAGER>( this ) ),
m_lengthDelayCalc( std::make_unique<LENGTH_DELAY_CALCULATION>( this ) )
{
// A too small value do not allow connecting 2 shapes (i.e. segments) not exactly connected
@ -2573,8 +2582,8 @@ bool BOARD::GetBoardPolygonOutlines( SHAPE_POLY_SET& aOutlines,
EMBEDDED_FILES* BOARD::GetEmbeddedFiles()
{
if( IsFootprintHolder() )
return static_cast<EMBEDDED_FILES*>( GetFirstFootprint() );
if( m_embeddedFilesDelegate )
return static_cast<EMBEDDED_FILES*>( m_embeddedFilesDelegate );
return static_cast<EMBEDDED_FILES*>( this );
}
@ -2582,8 +2591,8 @@ EMBEDDED_FILES* BOARD::GetEmbeddedFiles()
const EMBEDDED_FILES* BOARD::GetEmbeddedFiles() const
{
if( IsFootprintHolder() )
return static_cast<const EMBEDDED_FILES*>( GetFirstFootprint() );
if( m_embeddedFilesDelegate )
return static_cast<const EMBEDDED_FILES*>( m_embeddedFilesDelegate );
return static_cast<const EMBEDDED_FILES*>( this );
}

View File

@ -1275,6 +1275,8 @@ public:
EMBEDDED_FILES* GetEmbeddedFiles() override;
const EMBEDDED_FILES* GetEmbeddedFiles() const;
void SetEmbeddedFilesDelegate( EMBEDDED_FILES* aDelegate ) { m_embeddedFilesDelegate = aDelegate; }
/**
* Get the list of all outline fonts used in the board
*/
@ -1413,8 +1415,11 @@ private:
bool m_embedFonts;
std::unique_ptr<COMPONENT_CLASS_MANAGER> m_componentClassManager;
// Used for dummy boards, such as a footprint holder, where we don't want to make a copy
// of all the parent's embedded data.
EMBEDDED_FILES* m_embeddedFilesDelegate;
std::unique_ptr<COMPONENT_CLASS_MANAGER> m_componentClassManager;
std::unique_ptr<LENGTH_DELAY_CALCULATION> m_lengthDelayCalc;
};

View File

@ -84,7 +84,11 @@ DIALOG_FOOTPRINT_PROPERTIES::DIALOG_FOOTPRINT_PROPERTIES( PCB_EDIT_FRAME* aParen
m_posX.SetCoordType( ORIGIN_TRANSFORMS::ABS_X_COORD );
m_posY.SetCoordType( ORIGIN_TRANSFORMS::ABS_Y_COORD );
m_fields = new PCB_FIELDS_GRID_TABLE( m_frame, this, { m_embeddedFiles->GetLocalFiles() } );
std::vector<EMBEDDED_FILES*> embeddedFilesStack;
embeddedFilesStack.push_back( m_embeddedFiles->GetLocalFiles() );
embeddedFilesStack.push_back( m_frame->GetBoard()->GetEmbeddedFiles() );
m_fields = new PCB_FIELDS_GRID_TABLE( m_frame, this, embeddedFilesStack );
m_delayedErrorMessage = wxEmptyString;
m_delayedFocusGrid = nullptr;

View File

@ -34,9 +34,9 @@
#include <widgets/grid_text_button_helpers.h>
#include <widgets/wx_grid.h>
#include <widgets/std_bitmap_button.h>
#include <board.h>
#include <footprint.h>
#include <fp_lib_table.h>
#include <footprint.h>
#include <footprint_edit_frame.h>
#include <footprint_editor_settings.h>
#include <dialog_footprint_properties_fp_editor.h>
@ -379,8 +379,11 @@ void PANEL_FP_PROPERTIES_3D_MODEL::OnAdd3DModel( wxCommandEvent& )
// if libraryName is not found in table, do nothing
}
std::vector<const EMBEDDED_FILES*> embeddedFilesStack;
embeddedFilesStack.push_back( m_filesPanel->GetLocalFiles() );
embeddedFilesStack.push_back( m_frame->GetBoard()->GetEmbeddedFiles() );
wxString fullPath = res->ResolvePath( model.m_Filename, footprintBasePath, nullptr );
wxString fullPath = res->ResolvePath( model.m_Filename, footprintBasePath, embeddedFilesStack );
wxFileName fname( fullPath );
EMBEDDED_FILES::EMBEDDED_FILE* result = m_filesPanel->AddEmbeddedFile( fname.GetFullPath() ); ;
@ -532,7 +535,11 @@ MODEL_VALIDATE_ERRORS PANEL_FP_PROPERTIES_3D_MODEL::validateModelExists( const w
if( fpRow )
footprintBasePath = fpRow->GetFullURI( true );
wxString fullPath = resolv->ResolvePath( aFilename, footprintBasePath, m_footprint );
std::vector<const EMBEDDED_FILES*> embeddedFilesStack;
embeddedFilesStack.push_back( m_filesPanel->GetLocalFiles() );
embeddedFilesStack.push_back( m_frame->GetBoard()->GetEmbeddedFiles() );
wxString fullPath = resolv->ResolvePath( aFilename, footprintBasePath, embeddedFilesStack );
if( fullPath.IsEmpty() )
return MODEL_VALIDATE_ERRORS::RESOLVE_FAIL;

View File

@ -437,7 +437,11 @@ static void idf_export_footprint( BOARD* aPcb, FOOTPRINT* aFootprint, IDF3_BOARD
continue;
}
idfFile.Assign( resolver->ResolvePath( sM->m_Filename, footprintBasePath, aFootprint ) );
std::vector<const EMBEDDED_FILES*> embeddedFilesStack;
embeddedFilesStack.push_back( aFootprint->GetEmbeddedFiles() );
embeddedFilesStack.push_back( aPcb->GetEmbeddedFiles() );
idfFile.Assign( resolver->ResolvePath( sM->m_Filename, footprintBasePath, embeddedFilesStack ) );
idfExt = idfFile.GetExt();
if( idfExt.Cmp( wxT( "idf" ) ) && idfExt.Cmp( wxT( "IDF" ) ) )

View File

@ -1044,7 +1044,11 @@ void EXPORTER_PCB_VRML::ExportVrmlFootprint( FOOTPRINT* aFootprint, std::ostream
continue;
}
SGNODE* mod3d = (SGNODE*) m_Cache3Dmodels->Load( sM->m_Filename, footprintBasePath, aFootprint );
std::vector<const EMBEDDED_FILES*> embeddedFilesStack;
embeddedFilesStack.push_back( aFootprint->GetEmbeddedFiles() );
embeddedFilesStack.push_back( m_board->GetEmbeddedFiles() );
SGNODE* mod3d = (SGNODE*) m_Cache3Dmodels->Load( sM->m_Filename, footprintBasePath, embeddedFilesStack );
if( nullptr == mod3d )
{
@ -1109,8 +1113,12 @@ void EXPORTER_PCB_VRML::ExportVrmlFootprint( FOOTPRINT* aFootprint, std::ostream
int old_precision = aOutputFile->precision();
aOutputFile->precision( m_precision );
wxFileName srcFile =
m_Cache3Dmodels->GetResolver()->ResolvePath( sM->m_Filename, footprintBasePath, aFootprint );
std::vector<const EMBEDDED_FILES*> embeddedFilesStack;
embeddedFilesStack.push_back( aFootprint->GetEmbeddedFiles() );
embeddedFilesStack.push_back( m_board->GetEmbeddedFiles() );
wxFileName srcFile = m_Cache3Dmodels->GetResolver()->ResolvePath( sM->m_Filename, footprintBasePath,
embeddedFilesStack );
wxFileName dstFile;
dstFile.SetPath( m_Subdir3DFpModels );
dstFile.SetName( srcFile.GetName() );

View File

@ -360,8 +360,11 @@ bool EXPORTER_STEP::buildFootprint3DShapes( FOOTPRINT* aFootprint, VECTOR2D aOri
continue;
std::vector<wxString> searchedPaths;
wxString mname = m_resolver->ResolvePath( fp_model.m_Filename, footprintBasePath, aFootprint );
std::vector<const EMBEDDED_FILES*> embeddedFilesStack;
embeddedFilesStack.push_back( aFootprint->GetEmbeddedFiles() );
embeddedFilesStack.push_back( m_board->GetEmbeddedFiles() );
wxString mname = m_resolver->ResolvePath( fp_model.m_Filename, footprintBasePath, embeddedFilesStack );
if( mname.empty() || !wxFileName::FileExists( mname ) )
{

View File

@ -53,7 +53,7 @@ void PCB_EDIT_FRAME::LoadDrawingSheet()
wxString filename = resolver.ResolvePath( project.m_BoardDrawingSheetFile,
Prj().GetProjectPath(),
GetBoard()->GetEmbeddedFiles() );
{ GetBoard()->GetEmbeddedFiles() } );
wxString msg;

View File

@ -2431,7 +2431,7 @@ void PCBNEW_JOBS_HANDLER::loadOverrideDrawingSheet( BOARD* aBrd, const wxString&
wxString filename = resolver.ResolvePath( BASE_SCREEN::m_DrawingSheetFileName,
aBrd->GetProject()->GetProjectPath(),
aBrd->GetEmbeddedFiles() );
{ aBrd->GetEmbeddedFiles() } );
wxString msg;
if( !DS_DATA_MODEL::GetTheInstance().LoadDrawingSheet( filename, &msg ) )

View File

@ -210,8 +210,8 @@ BOARD* LoadBoard( const wxString& aFileName, PCB_IO_MGR::PCB_FILE_T aFormat, boo
resolver.SetProgramBase( PgmOrNull() );
wxString filename = resolver.ResolvePath( BASE_SCREEN::m_DrawingSheetFileName,
project->GetProjectPath(),
brd->GetEmbeddedFiles() );
project->GetProjectPath(),
{ brd->GetEmbeddedFiles() } );
wxString msg;