Add relative to footprint 3d model path resolution
Fixes https://gitlab.com/kicad/code/kicad/-/issues/2073
This commit is contained in:
parent
05f01ab6c6
commit
c50b4fb04f
|
@ -212,12 +212,13 @@ S3D_CACHE::~S3D_CACHE()
|
|||
}
|
||||
|
||||
|
||||
SCENEGRAPH* S3D_CACHE::load( const wxString& aModelFile, S3D_CACHE_ENTRY** aCachePtr )
|
||||
SCENEGRAPH* S3D_CACHE::load( const wxString& aModelFile, const wxString& aBasePath,
|
||||
S3D_CACHE_ENTRY** aCachePtr )
|
||||
{
|
||||
if( aCachePtr )
|
||||
*aCachePtr = nullptr;
|
||||
|
||||
wxString full3Dpath = m_FNResolver->ResolvePath( aModelFile );
|
||||
wxString full3Dpath = m_FNResolver->ResolvePath( aModelFile, aBasePath );
|
||||
|
||||
if( full3Dpath.empty() )
|
||||
{
|
||||
|
@ -282,9 +283,9 @@ SCENEGRAPH* S3D_CACHE::load( const wxString& aModelFile, S3D_CACHE_ENTRY** aCach
|
|||
}
|
||||
|
||||
|
||||
SCENEGRAPH* S3D_CACHE::Load( const wxString& aModelFile )
|
||||
SCENEGRAPH* S3D_CACHE::Load( const wxString& aModelFile, const wxString& aBasePath )
|
||||
{
|
||||
return load( aModelFile );
|
||||
return load( aModelFile, aBasePath );
|
||||
}
|
||||
|
||||
|
||||
|
@ -641,10 +642,10 @@ void S3D_CACHE::ClosePlugins()
|
|||
}
|
||||
|
||||
|
||||
S3DMODEL* S3D_CACHE::GetModel( const wxString& aModelFileName )
|
||||
S3DMODEL* S3D_CACHE::GetModel( const wxString& aModelFileName, const wxString& aBasePath )
|
||||
{
|
||||
S3D_CACHE_ENTRY* cp = nullptr;
|
||||
SCENEGRAPH* sp = load( aModelFileName, &cp );
|
||||
SCENEGRAPH* sp = load( aModelFileName, aBasePath,&cp );
|
||||
|
||||
if( !sp )
|
||||
return nullptr;
|
||||
|
|
|
@ -92,9 +92,10 @@ 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
|
||||
* @return true if the model was successfully loaded, otherwise false.
|
||||
*/
|
||||
SCENEGRAPH* Load( const wxString& aModelFile );
|
||||
SCENEGRAPH* Load( const wxString& aModelFile, const wxString& aBasePath );
|
||||
|
||||
FILENAME_RESOLVER* GetResolver() noexcept;
|
||||
|
||||
|
@ -124,7 +125,7 @@ public:
|
|||
* @param aModelFileName is the full path to the model to be loaded.
|
||||
* @return is a pointer to the render data or NULL if not available.
|
||||
*/
|
||||
S3DMODEL* GetModel( const wxString& aModelFileName );
|
||||
S3DMODEL* GetModel( const wxString& aModelFileName, const wxString& aBasePath );
|
||||
|
||||
/**
|
||||
* Delete up old cache files in cache directory.
|
||||
|
@ -164,7 +165,7 @@ private:
|
|||
bool saveCacheData( S3D_CACHE_ENTRY* aCacheItem );
|
||||
|
||||
// the real load function (can supply a cache entry pointer to member functions)
|
||||
SCENEGRAPH* load( const wxString& aModelFile, S3D_CACHE_ENTRY** aCachePtr = nullptr );
|
||||
SCENEGRAPH* load( const wxString& aModelFile, const wxString& aBasePath, S3D_CACHE_ENTRY** aCachePtr = nullptr );
|
||||
|
||||
/// cache entries
|
||||
std::list< S3D_CACHE_ENTRY* > m_CacheList;
|
||||
|
|
|
@ -156,7 +156,7 @@ void EDA_3D_MODEL_VIEWER::Set3DModel( const wxString& aModelPathName)
|
|||
|
||||
if( m_cacheManager )
|
||||
{
|
||||
const S3DMODEL* model = m_cacheManager->GetModel( aModelPathName );
|
||||
const S3DMODEL* model = m_cacheManager->GetModel( aModelPathName, wxEmptyString );
|
||||
|
||||
if( model )
|
||||
Set3DModel( (const S3DMODEL &)*model );
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <trigo.h>
|
||||
#include <project.h>
|
||||
#include <profile.h> // To use GetRunningMicroSecs or another profiling utility
|
||||
#include <fp_lib_table.h>
|
||||
#include <eda_3d_canvas.h>
|
||||
#include <eda_3d_viewer_frame.h>
|
||||
|
||||
|
@ -922,6 +923,19 @@ 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;
|
||||
|
||||
if( m_boardAdapter.GetBoard()->GetProject() )
|
||||
{
|
||||
const FP_LIB_TABLE_ROW* fpRow =
|
||||
m_boardAdapter.GetBoard()->GetProject()->PcbFootprintLibs()->FindRow(
|
||||
libraryName, false );
|
||||
|
||||
if( fpRow )
|
||||
footprintBasePath = fpRow->GetFullURI( true );
|
||||
}
|
||||
|
||||
for( const FP_3DMODEL& fp_model : footprint->Models() )
|
||||
{
|
||||
if( fp_model.m_Show && !fp_model.m_Filename.empty() )
|
||||
|
@ -941,7 +955,7 @@ void RENDER_3D_OPENGL::load3dModels( REPORTER* aStatusReporter )
|
|||
{
|
||||
// It is not present, try get it from cache
|
||||
const S3DMODEL* modelPtr =
|
||||
m_boardAdapter.Get3dCacheManager()->GetModel( fp_model.m_Filename );
|
||||
m_boardAdapter.Get3dCacheManager()->GetModel( fp_model.m_Filename, footprintBasePath );
|
||||
|
||||
// only add it if the return is not NULL
|
||||
if( modelPtr )
|
||||
|
|
|
@ -39,6 +39,8 @@
|
|||
|
||||
#include <board.h>
|
||||
#include <footprint.h>
|
||||
#include <fp_lib_table.h>
|
||||
#include <eda_3d_viewer_frame.h>
|
||||
|
||||
#include <base_units.h>
|
||||
#include <profile.h> // To use GetRunningMicroSecs or another profiling utility
|
||||
|
@ -1251,13 +1253,27 @@ void RENDER_3D_RAYTRACE::load3DModels( CONTAINER_3D& aDstContainer, bool aSkipMa
|
|||
auto sM = fp->Models().begin();
|
||||
auto eM = fp->Models().end();
|
||||
|
||||
wxString libraryName = fp->GetFPID().GetLibNickname();
|
||||
|
||||
wxString footprintBasePath = wxEmptyString;
|
||||
if( m_boardAdapter.GetBoard()->GetProject() )
|
||||
{
|
||||
const FP_LIB_TABLE_ROW* fpRow =
|
||||
m_boardAdapter.GetBoard()->GetProject()->PcbFootprintLibs()->FindRow(
|
||||
libraryName, false );
|
||||
|
||||
if( fpRow )
|
||||
footprintBasePath = fpRow->GetFullURI( true );
|
||||
}
|
||||
|
||||
while( sM != eM )
|
||||
{
|
||||
if( ( static_cast<float>( sM->m_Opacity ) > FLT_EPSILON )
|
||||
&& ( sM->m_Show && !sM->m_Filename.empty() ) )
|
||||
{
|
||||
// get it from cache
|
||||
const S3DMODEL* modelPtr = cacheMgr->GetModel( sM->m_Filename );
|
||||
const S3DMODEL* modelPtr =
|
||||
cacheMgr->GetModel( sM->m_Filename, footprintBasePath );
|
||||
|
||||
// only add it if the return is not NULL.
|
||||
if( modelPtr )
|
||||
|
|
|
@ -54,6 +54,7 @@ PANEL_PREVIEW_3D_MODEL::PANEL_PREVIEW_3D_MODEL( wxWindow* aParent, PCB_BASE_FRAM
|
|||
m_userUnits = aFrame->GetUserUnits();
|
||||
|
||||
m_dummyBoard = new BOARD();
|
||||
m_dummyBoard->SetProject( &aFrame->Prj() );
|
||||
|
||||
// This board will only be used to hold a footprint for viewing
|
||||
m_dummyBoard->SetBoardUse( BOARD_USE::FPHOLDER );
|
||||
|
|
|
@ -240,7 +240,7 @@ bool FILENAME_RESOLVER::UpdatePathList( const std::vector< SEARCH_PATH >& aPathL
|
|||
}
|
||||
|
||||
|
||||
wxString FILENAME_RESOLVER::ResolvePath( const wxString& aFileName )
|
||||
wxString FILENAME_RESOLVER::ResolvePath( const wxString& aFileName, const wxString& aWorkingPath )
|
||||
{
|
||||
std::lock_guard<std::mutex> lock( mutex_resolver );
|
||||
|
||||
|
@ -324,6 +324,21 @@ wxString FILENAME_RESOLVER::ResolvePath( const wxString& aFileName )
|
|||
|
||||
}
|
||||
|
||||
// check path relative to search path
|
||||
if( !aWorkingPath.IsEmpty() && !tname.StartsWith( ":" ) )
|
||||
{
|
||||
wxString tmp = aWorkingPath;
|
||||
tmp.Append( tmpFN.GetPathSeparator() );
|
||||
tmp.Append( tname );
|
||||
tmpFN.Assign( tmp );
|
||||
|
||||
if( tmpFN.MakeAbsolute() && tmpFN.FileExists() )
|
||||
{
|
||||
tname = tmpFN.GetFullPath();
|
||||
return tname;
|
||||
}
|
||||
}
|
||||
|
||||
// check the partial path relative to ${KICAD6_3DMODEL_DIR} (legacy behavior)
|
||||
if( !tname.StartsWith( ":" ) )
|
||||
{
|
||||
|
|
|
@ -101,8 +101,11 @@ public:
|
|||
* In the future remote files may be supported, in which case it is best to require a full
|
||||
* URI in which case ResolvePath should check that the URI conforms to RFC-2396 and related
|
||||
* documents and copies \a aFileName into aResolvedName if the URI is valid.
|
||||
*
|
||||
* @param aFileName The configured file path to resolve
|
||||
* @param aWorkingPath The current working path for relative path resolutions
|
||||
*/
|
||||
wxString ResolvePath( const wxString& aFileName );
|
||||
wxString ResolvePath( const wxString& aFileName, const wxString& aWorkingPath );
|
||||
|
||||
/**
|
||||
* Produce a relative path based on the existing search directories or returns the same path
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <widgets/grid_text_button_helpers.h>
|
||||
#include <widgets/wx_grid.h>
|
||||
#include <footprint.h>
|
||||
#include <fp_lib_table.h>
|
||||
#include <footprint_edit_frame.h>
|
||||
#include <footprint_editor_settings.h>
|
||||
#include <dialog_footprint_properties_fp_editor.h>
|
||||
|
@ -427,7 +428,15 @@ MODEL_VALIDATE_ERRORS PANEL_FP_PROPERTIES_3D_MODEL::validateModelExists( const w
|
|||
if( !resolv->ValidateFileName( aFilename, hasAlias ) )
|
||||
return MODEL_VALIDATE_ERRORS::ILLEGAL_FILENAME;
|
||||
|
||||
wxString fullPath = resolv->ResolvePath( aFilename );
|
||||
wxString libraryName = m_footprint->GetFPID().GetLibNickname();
|
||||
const FP_LIB_TABLE_ROW* fpRow =
|
||||
m_frame->Prj().PcbFootprintLibs()->FindRow( libraryName, false );
|
||||
|
||||
wxString footprintBasePath = wxEmptyString;
|
||||
if( fpRow )
|
||||
footprintBasePath = fpRow->GetFullURI( true );
|
||||
|
||||
wxString fullPath = resolv->ResolvePath( aFilename, footprintBasePath );
|
||||
|
||||
if( fullPath.IsEmpty() )
|
||||
return MODEL_VALIDATE_ERRORS::RESOLVE_FAIL;
|
||||
|
|
|
@ -411,7 +411,7 @@ static void idf_export_footprint( BOARD* aPcb, FOOTPRINT* aFootprint, IDF3_BOARD
|
|||
continue;
|
||||
}
|
||||
|
||||
idfFile.Assign( resolver->ResolvePath( sM->m_Filename ) );
|
||||
idfFile.Assign( resolver->ResolvePath( sM->m_Filename, wxEmptyString ) );
|
||||
idfExt = idfFile.GetExt();
|
||||
|
||||
if( idfExt.Cmp( wxT( "idf" ) ) && idfExt.Cmp( wxT( "IDF" ) ) )
|
||||
|
|
|
@ -1013,7 +1013,7 @@ void EXPORTER_PCB_VRML::ExportVrmlFootprint( FOOTPRINT* aFootprint, std::ostream
|
|||
continue;
|
||||
}
|
||||
|
||||
SGNODE* mod3d = (SGNODE*) m_Cache3Dmodels->Load( sM->m_Filename );
|
||||
SGNODE* mod3d = (SGNODE*) m_Cache3Dmodels->Load( sM->m_Filename, wxEmptyString );
|
||||
|
||||
if( nullptr == mod3d )
|
||||
{
|
||||
|
@ -1078,7 +1078,8 @@ 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 );
|
||||
wxFileName srcFile =
|
||||
m_Cache3Dmodels->GetResolver()->ResolvePath( sM->m_Filename, wxEmptyString );
|
||||
wxFileName dstFile;
|
||||
dstFile.SetPath( m_Subdir3DFpModels );
|
||||
dstFile.SetName( srcFile.GetName() );
|
||||
|
|
Loading…
Reference in New Issue