KiCad PCB EDA Suite
S3D_CACHE Class Reference

Cache for storing the 3D shapes. More...

#include <3d_cache.h>

Inheritance diagram for S3D_CACHE:
PROJECT::_ELEM

Public Member Functions

 S3D_CACHE ()
 
virtual ~S3D_CACHE ()
 
KICAD_T Type () noexcept override
 
bool Set3DConfigDir (const wxString &aConfigDir)
 Sets the configuration directory to be used by the model manager for storing 3D model manager configuration data and the model cache. More...
 
bool SetProject (PROJECT *aProject)
 Set the current project's working directory; this affects the model search path. More...
 
void SetProgramBase (PGM_BASE *aBase)
 Set the filename resolver's pointer to the application's PGM_BASE instance. More...
 
SCENEGRAPHLoad (const wxString &aModelFile)
 Attempt to load the scene data for a model. More...
 
FILENAME_RESOLVERGetResolver () noexcept
 
std::list< wxString > const * GetFileFilters () const
 Return the list of file filters retrieved from the plugins. More...
 
void FlushCache (bool closePlugins=true)
 Free all data in the cache and by default closes all plugins. More...
 
void ClosePlugins ()
 Unload plugins to free memory. More...
 
S3DMODELGetModel (const wxString &aModelFileName)
 Attempt to load the scene data for a model and to translate it into an S3D_MODEL structure for display by a renderer. More...
 
void CleanCacheDir (int aNumDaysOld)
 Delete up old cache files in cache directory. More...
 

Private Member Functions

SCENEGRAPHcheckCache (const wxString &aFileName, S3D_CACHE_ENTRY **aCachePtr=nullptr)
 Find or create cache entry for file name. More...
 
bool getSHA1 (const wxString &aFileName, unsigned char *aSHA1Sum)
 Calculate the SHA1 hash of the given file. More...
 
bool loadCacheData (S3D_CACHE_ENTRY *aCacheItem)
 
bool saveCacheData (S3D_CACHE_ENTRY *aCacheItem)
 
SCENEGRAPHload (const wxString &aModelFile, S3D_CACHE_ENTRY **aCachePtr=nullptr)
 

Private Attributes

std::list< S3D_CACHE_ENTRY * > m_CacheList
 cache entries More...
 
std::map< wxString, S3D_CACHE_ENTRY *, rsort_wxStringm_CacheMap
 mapping of file names to cache names and data More...
 
FILENAME_RESOLVERm_FNResolver
 
S3D_PLUGIN_MANAGERm_Plugins
 
PROJECTm_project
 
wxString m_CacheDir
 
wxString m_ConfigDir
 

Detailed Description

Cache for storing the 3D shapes.

This cache is able to be stored as a project element (since it inherits from PROJECT::_ELEM).

Definition at line 52 of file 3d_cache.h.

Constructor & Destructor Documentation

◆ S3D_CACHE()

S3D_CACHE::S3D_CACHE ( )

Definition at line 187 of file 3d_cache.cpp.

188 {
190  m_project = nullptr;
192 }
FILENAME_RESOLVER * m_FNResolver
Definition: 3d_cache.h:175
Provide an extensible class to resolve 3D model paths.
PROJECT * m_project
Definition: 3d_cache.h:179
S3D_PLUGIN_MANAGER * m_Plugins
Definition: 3d_cache.h:177

References m_FNResolver, m_Plugins, and m_project.

◆ ~S3D_CACHE()

S3D_CACHE::~S3D_CACHE ( )
virtual

Definition at line 195 of file 3d_cache.cpp.

196 {
197  COMMON_SETTINGS* commonSettings = Pgm().GetCommonSettings();
198 
199  FlushCache();
200 
201  // We'll delete ".3dc" cache files older than this many days
202  int clearCacheInterval = commonSettings->m_System.clear_3d_cache_interval;
203 
204  // An interval of zero means the user doesn't want to ever clear the cache
205 
206  if( clearCacheInterval > 0 )
207  CleanCacheDir( clearCacheInterval );
208 
209  delete m_FNResolver;
210  delete m_Plugins;
211 }
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:106
FILENAME_RESOLVER * m_FNResolver
Definition: 3d_cache.h:175
void FlushCache(bool closePlugins=true)
Free all data in the cache and by default closes all plugins.
Definition: 3d_cache.cpp:617
void CleanCacheDir(int aNumDaysOld)
Delete up old cache files in cache directory.
Definition: 3d_cache.cpp:669
S3D_PLUGIN_MANAGER * m_Plugins
Definition: 3d_cache.h:177

References CleanCacheDir(), COMMON_SETTINGS::SYSTEM::clear_3d_cache_interval, FlushCache(), m_FNResolver, m_Plugins, COMMON_SETTINGS::m_System, and Pgm().

Member Function Documentation

◆ checkCache()

SCENEGRAPH * S3D_CACHE::checkCache ( const wxString &  aFileName,
S3D_CACHE_ENTRY **  aCachePtr = nullptr 
)
private

Find or create cache entry for file name.

Searches the cache list for the given filename and retrieves the cache data; a cache entry is created if one does not already exist.

Parameters
aFileNameis the file name (full or partial path).
aCachePtris an optional return address for cache entry pointer.
Returns
SCENEGRAPH object associated with file name or NULL on error.

Definition at line 290 of file 3d_cache.cpp.

291 {
292  if( aCachePtr )
293  *aCachePtr = nullptr;
294 
295  unsigned char sha1sum[20];
297  m_CacheList.push_back( ep );
298  wxFileName fname( aFileName );
299  ep->modTime = fname.GetModificationTime();
300 
301  if( !getSHA1( aFileName, sha1sum ) || m_CacheDir.empty() )
302  {
303  // just in case we can't get a hash digest (for example, on access issues)
304  // or we do not have a configured cache file directory, we create an
305  // entry to prevent further attempts at loading the file
306 
307  if( m_CacheMap.insert( std::pair< wxString, S3D_CACHE_ENTRY* >
308  ( aFileName, ep ) ).second == false )
309  {
310  wxLogTrace( MASK_3D_CACHE, "%s:%s:%d\n * [BUG] duplicate entry in map file; key = '%s'",
311  __FILE__, __FUNCTION__, __LINE__, aFileName );
312 
313  m_CacheList.pop_back();
314  delete ep;
315  }
316  else
317  {
318  if( aCachePtr )
319  *aCachePtr = ep;
320  }
321 
322  return nullptr;
323  }
324 
325  if( m_CacheMap.insert( std::pair< wxString, S3D_CACHE_ENTRY* >
326  ( aFileName, ep ) ).second == false )
327  {
328  wxLogTrace( MASK_3D_CACHE, "%s:%s:%d\n * [BUG] duplicate entry in map file; key = '%s'",
329  __FILE__, __FUNCTION__, __LINE__, aFileName );
330 
331  m_CacheList.pop_back();
332  delete ep;
333  return nullptr;
334  }
335 
336  if( aCachePtr )
337  *aCachePtr = ep;
338 
339  ep->SetSHA1( sha1sum );
340 
341  wxString bname = ep->GetCacheBaseName();
342  wxString cachename = m_CacheDir + bname + wxT( ".3dc" );
343 
344  if( !ADVANCED_CFG::GetCfg().m_Skip3DModelFileCache && wxFileName::FileExists( cachename )
345  && loadCacheData( ep ) )
346  return ep->sceneData;
347 
348  ep->sceneData = m_Plugins->Load3DModel( aFileName, ep->pluginInfo );
349 
350  if( !ADVANCED_CFG::GetCfg().m_Skip3DModelFileCache && nullptr != ep->sceneData )
351  saveCacheData( ep );
352 
353  return ep->sceneData;
354 }
std::string pluginInfo
Definition: 3d_cache.cpp:134
#define MASK_3D_CACHE
Definition: 3d_cache.cpp:60
std::map< wxString, S3D_CACHE_ENTRY *, rsort_wxString > m_CacheMap
mapping of file names to cache names and data
Definition: 3d_cache.h:173
bool loadCacheData(S3D_CACHE_ENTRY *aCacheItem)
Definition: 3d_cache.cpp:413
SCENEGRAPH * Load3DModel(const wxString &aFileName, std::string &aPluginInfo)
const wxString GetCacheBaseName()
Definition: 3d_cache.cpp:178
bool saveCacheData(S3D_CACHE_ENTRY *aCacheItem)
Definition: 3d_cache.cpp:454
wxDateTime modTime
Definition: 3d_cache.cpp:132
wxString m_CacheDir
Definition: 3d_cache.h:180
void SetSHA1(const unsigned char *aSHA1Sum)
Definition: 3d_cache.cpp:164
bool getSHA1(const wxString &aFileName, unsigned char *aSHA1Sum)
Calculate the SHA1 hash of the given file.
Definition: 3d_cache.cpp:357
SCENEGRAPH * sceneData
Definition: 3d_cache.cpp:135
std::list< S3D_CACHE_ENTRY * > m_CacheList
cache entries
Definition: 3d_cache.h:170
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
Definition: 3d_cache.cpp:123
S3D_PLUGIN_MANAGER * m_Plugins
Definition: 3d_cache.h:177

References S3D_CACHE_ENTRY::GetCacheBaseName(), ADVANCED_CFG::GetCfg(), getSHA1(), S3D_PLUGIN_MANAGER::Load3DModel(), loadCacheData(), m_CacheDir, m_CacheList, m_CacheMap, m_Plugins, MASK_3D_CACHE, S3D_CACHE_ENTRY::modTime, S3D_CACHE_ENTRY::pluginInfo, saveCacheData(), S3D_CACHE_ENTRY::sceneData, and S3D_CACHE_ENTRY::SetSHA1().

Referenced by load().

◆ CleanCacheDir()

void S3D_CACHE::CleanCacheDir ( int  aNumDaysOld)

Delete up old cache files in cache directory.

Deletes ".3dc" files in the cache directory that are older than aNumDaysOld.

Parameters
aNumDaysOldis age threshold to delete ".3dc" cache files.

Definition at line 669 of file 3d_cache.cpp.

670 {
671  wxDir dir;
672  wxString fileSpec = wxT( "*.3dc" );
673  wxArrayString fileList; // Holds list of ".3dc" files found in cache directory
674  size_t numFilesFound = 0;
675 
676  wxFileName thisFile;
677  wxDateTime lastAccess, thresholdDate;
678  wxDateSpan durationInDays;
679 
680  // Calc the threshold date above which we delete cache files
681  durationInDays.SetDays( aNumDaysOld );
682  thresholdDate = wxDateTime::Now() - durationInDays;
683 
684  // If the cache directory can be found and opened, then we'll try and clean it up
685  if( dir.Open( m_CacheDir ) )
686  {
687  thisFile.SetPath( m_CacheDir ); // Set the base path to the cache folder
688 
689  // Get a list of all the ".3dc" files in the cache directory
690  numFilesFound = dir.GetAllFiles( m_CacheDir, &fileList, fileSpec );
691 
692  for( unsigned int i = 0; i < numFilesFound; i++ )
693  {
694  // Completes path to specific file so we can get its "last access" date
695  thisFile.SetFullName( fileList[i] );
696 
697  // Only get "last access" time to compare against. Don't need the other 2 timestamps.
698  if( thisFile.GetTimes( &lastAccess, nullptr, nullptr ) )
699  {
700  if( lastAccess.IsEarlierThan( thresholdDate ) )
701  {
702  // This file is older than the threshold so delete it
703  wxRemoveFile( thisFile.GetFullPath() );
704  }
705  }
706  }
707  }
708 }
wxString m_CacheDir
Definition: 3d_cache.h:180

References m_CacheDir.

Referenced by ~S3D_CACHE().

◆ ClosePlugins()

void S3D_CACHE::ClosePlugins ( )

Unload plugins to free memory.

Definition at line 636 of file 3d_cache.cpp.

637 {
638  if( m_Plugins )
640 }
void ClosePlugins(void)
Iterate through all discovered plugins and closes them to reclaim memory.
S3D_PLUGIN_MANAGER * m_Plugins
Definition: 3d_cache.h:177

References S3D_PLUGIN_MANAGER::ClosePlugins(), and m_Plugins.

Referenced by FlushCache().

◆ FlushCache()

void S3D_CACHE::FlushCache ( bool  closePlugins = true)

Free all data in the cache and by default closes all plugins.

Definition at line 617 of file 3d_cache.cpp.

618 {
619  std::list< S3D_CACHE_ENTRY* >::iterator sCL = m_CacheList.begin();
620  std::list< S3D_CACHE_ENTRY* >::iterator eCL = m_CacheList.end();
621 
622  while( sCL != eCL )
623  {
624  delete *sCL;
625  ++sCL;
626  }
627 
628  m_CacheList.clear();
629  m_CacheMap.clear();
630 
631  if( closePlugins )
632  ClosePlugins();
633 }
std::map< wxString, S3D_CACHE_ENTRY *, rsort_wxString > m_CacheMap
mapping of file names to cache names and data
Definition: 3d_cache.h:173
void ClosePlugins()
Unload plugins to free memory.
Definition: 3d_cache.cpp:636
std::list< S3D_CACHE_ENTRY * > m_CacheList
cache entries
Definition: 3d_cache.h:170

References ClosePlugins(), m_CacheList, and m_CacheMap.

Referenced by ~S3D_CACHE().

◆ GetFileFilters()

std::list< wxString > const * S3D_CACHE::GetFileFilters ( ) const

Return the list of file filters retrieved from the plugins.

This will contain at least the default "All Files (*.*)|*.*"

Returns
a pointer to the filter list.

Definition at line 611 of file 3d_cache.cpp.

612 {
613  return m_Plugins->GetFileFilters();
614 }
std::list< wxString > const * GetFileFilters(void) const noexcept
Return the list of file filters; this will contain at least the default "All Files (*....
S3D_PLUGIN_MANAGER * m_Plugins
Definition: 3d_cache.h:177

References S3D_PLUGIN_MANAGER::GetFileFilters(), and m_Plugins.

Referenced by DIALOG_SELECT_3DMODEL::DIALOG_SELECT_3DMODEL().

◆ GetModel()

S3DMODEL * S3D_CACHE::GetModel ( const wxString &  aModelFileName)

Attempt to load the scene data for a model and to translate it into an S3D_MODEL structure for display by a renderer.

Parameters
aModelFileNameis the full path to the model to be loaded.
Returns
is a pointer to the render data or NULL if not available.

Definition at line 643 of file 3d_cache.cpp.

644 {
645  S3D_CACHE_ENTRY* cp = nullptr;
646  SCENEGRAPH* sp = load( aModelFileName, &cp );
647 
648  if( !sp )
649  return nullptr;
650 
651  if( !cp )
652  {
653  wxLogTrace( MASK_3D_CACHE,
654  "%s:%s:%d\n * [BUG] model loaded with no associated S3D_CACHE_ENTRY",
655  __FILE__, __FUNCTION__, __LINE__ );
656 
657  return nullptr;
658  }
659 
660  if( cp->renderData )
661  return cp->renderData;
662 
663  S3DMODEL* mp = S3D::GetModel( sp );
664  cp->renderData = mp;
665 
666  return mp;
667 }
#define MASK_3D_CACHE
Definition: 3d_cache.cpp:60
S3DMODEL * renderData
Definition: 3d_cache.cpp:136
Define the basic data set required to represent a 3D model.
Definition: scenegraph.h:44
Store the a model based on meshes and materials.
Definition: c3dmodel.h:90
Definition: 3d_cache.cpp:123
SGLIB_API S3DMODEL * GetModel(SCENEGRAPH *aNode)
Function GetModel creates an S3DMODEL representation of aNode (raw data, no transforms)
Definition: ifsg_api.cpp:336
SCENEGRAPH * load(const wxString &aModelFile, S3D_CACHE_ENTRY **aCachePtr=nullptr)
Definition: 3d_cache.cpp:214

References S3D::GetModel(), load(), MASK_3D_CACHE, and S3D_CACHE_ENTRY::renderData.

Referenced by RENDER_3D_RAYTRACE::load3DModels(), RENDER_3D_LEGACY::load3dModels(), and EDA_3D_MODEL_VIEWER::Set3DModel().

◆ GetResolver()

FILENAME_RESOLVER * S3D_CACHE::GetResolver ( )
noexcept

Definition at line 605 of file 3d_cache.cpp.

606 {
607  return m_FNResolver;
608 }
FILENAME_RESOLVER * m_FNResolver
Definition: 3d_cache.h:175

References m_FNResolver.

Referenced by EXPORTER_PCB_VRML::ExportVrmlFootprint().

◆ getSHA1()

bool S3D_CACHE::getSHA1 ( const wxString &  aFileName,
unsigned char *  aSHA1Sum 
)
private

Calculate the SHA1 hash of the given file.

Parameters
aFileNamefile name (full path).
aSHA1Suma 20 byte character array to hold the SHA1 hash.
Returns
true on success, otherwise false.

Definition at line 357 of file 3d_cache.cpp.

358 {
359  if( aFileName.empty() )
360  {
361  wxLogTrace( MASK_3D_CACHE, "%s:%s:%d\n * [BUG] empty filename",
362  __FILE__, __FUNCTION__, __LINE__ );
363 
364  return false;
365  }
366 
367  if( nullptr == aSHA1Sum )
368  {
369  wxLogTrace( MASK_3D_CACHE, "%s\n * [BUG] NULL pointer passed for aMD5Sum",
370  __FILE__, __FUNCTION__, __LINE__ );
371 
372  return false;
373  }
374 
375 #ifdef _WIN32
376  FILE* fp = _wfopen( aFileName.wc_str(), L"rb" );
377 #else
378  FILE* fp = fopen( aFileName.ToUTF8(), "rb" );
379 #endif
380 
381  if( nullptr == fp )
382  return false;
383 
384  boost::uuids::detail::sha1 dblock;
385  unsigned char block[4096];
386  size_t bsize = 0;
387 
388  while( ( bsize = fread( &block, 1, 4096, fp ) ) > 0 )
389  dblock.process_bytes( block, bsize );
390 
391  fclose( fp );
392  unsigned int digest[5];
393  dblock.get_digest( digest );
394 
395  // ensure MSB order
396  for( int i = 0; i < 5; ++i )
397  {
398  int idx = i << 2;
399  unsigned int tmp = digest[i];
400  aSHA1Sum[idx+3] = tmp & 0xff;
401  tmp >>= 8;
402  aSHA1Sum[idx+2] = tmp & 0xff;
403  tmp >>= 8;
404  aSHA1Sum[idx+1] = tmp & 0xff;
405  tmp >>= 8;
406  aSHA1Sum[idx] = tmp & 0xff;
407  }
408 
409  return true;
410 }
#define MASK_3D_CACHE
Definition: 3d_cache.cpp:60

References MASK_3D_CACHE.

Referenced by checkCache(), and load().

◆ Load()

SCENEGRAPH * S3D_CACHE::Load ( const wxString &  aModelFile)

Attempt to load the scene data for a model.

It will consult the internal cache list and load from cache if possible before invoking the load() function of the available plugins. The model may fail to load if, for example, the plugin does not support rendering of the 3D model.

Parameters
aModelFileis the partial or full path to the model to be loaded.
Returns
true if the model was successfully loaded, otherwise false.

Definition at line 284 of file 3d_cache.cpp.

285 {
286  return load( aModelFile );
287 }
SCENEGRAPH * load(const wxString &aModelFile, S3D_CACHE_ENTRY **aCachePtr=nullptr)
Definition: 3d_cache.cpp:214

References load().

Referenced by EXPORTER_PCB_VRML::ExportVrmlFootprint().

◆ load()

SCENEGRAPH * S3D_CACHE::load ( const wxString &  aModelFile,
S3D_CACHE_ENTRY **  aCachePtr = nullptr 
)
private

Definition at line 214 of file 3d_cache.cpp.

215 {
216  if( aCachePtr )
217  *aCachePtr = nullptr;
218 
219  wxString full3Dpath = m_FNResolver->ResolvePath( aModelFile );
220 
221  if( full3Dpath.empty() )
222  {
223  // the model cannot be found; we cannot proceed
224  wxLogTrace( MASK_3D_CACHE, "%s:%s:%d\n * [3D model] could not find model '%s'\n",
225  __FILE__, __FUNCTION__, __LINE__, aModelFile );
226  return nullptr;
227  }
228 
229  // check cache if file is already loaded
230  std::lock_guard<std::mutex> lock( mutex3D_cache );
231 
232  std::map< wxString, S3D_CACHE_ENTRY*, rsort_wxString >::iterator mi;
233  mi = m_CacheMap.find( full3Dpath );
234 
235  if( mi != m_CacheMap.end() )
236  {
237  wxFileName fname( full3Dpath );
238 
239  if( fname.FileExists() ) // Only check if file exists. If not, it will
240  { // use the same model in cache.
242  wxDateTime fmdate = fname.GetModificationTime();
243 
244  if( fmdate != mi->second->modTime )
245  {
246  unsigned char hashSum[20];
247  getSHA1( full3Dpath, hashSum );
248  mi->second->modTime = fmdate;
249 
250  if( !isSHA1Same( hashSum, mi->second->sha1sum ) )
251  {
252  mi->second->SetSHA1( hashSum );
253  reload = true;
254  }
255  }
256 
257  if( reload )
258  {
259  if( nullptr != mi->second->sceneData )
260  {
261  S3D::DestroyNode( mi->second->sceneData );
262  mi->second->sceneData = nullptr;
263  }
264 
265  if( nullptr != mi->second->renderData )
266  S3D::Destroy3DModel( &mi->second->renderData );
267 
268  mi->second->sceneData = m_Plugins->Load3DModel( full3Dpath,
269  mi->second->pluginInfo );
270  }
271  }
272 
273  if( nullptr != aCachePtr )
274  *aCachePtr = mi->second;
275 
276  return mi->second->sceneData;
277  }
278 
279  // a cache item does not exist; search the Filename->Cachename map
280  return checkCache( full3Dpath, aCachePtr );
281 }
#define MASK_3D_CACHE
Definition: 3d_cache.cpp:60
static std::mutex mutex3D_cache
Definition: 3d_cache.cpp:62
SGLIB_API void Destroy3DModel(S3DMODEL **aModel)
Function Destroy3DModel frees memory used by an S3DMODEL structure and sets the pointer to the struct...
Definition: ifsg_api.cpp:401
std::map< wxString, S3D_CACHE_ENTRY *, rsort_wxString > m_CacheMap
mapping of file names to cache names and data
Definition: 3d_cache.h:173
SCENEGRAPH * checkCache(const wxString &aFileName, S3D_CACHE_ENTRY **aCachePtr=nullptr)
Find or create cache entry for file name.
Definition: 3d_cache.cpp:290
SCENEGRAPH * Load3DModel(const wxString &aFileName, std::string &aPluginInfo)
FILENAME_RESOLVER * m_FNResolver
Definition: 3d_cache.h:175
SGLIB_API void DestroyNode(SGNODE *aNode) noexcept
Function DestroyNode deletes the given SG* class node.
Definition: ifsg_api.cpp:148
bool getSHA1(const wxString &aFileName, unsigned char *aSHA1Sum)
Calculate the SHA1 hash of the given file.
Definition: 3d_cache.cpp:357
bool m_Skip3DModelMemoryCache
Skip reading/writing 3d model memory caches This ensures 3d models are always reloaded from disk even...
SCENEGRAPH * sceneData
Definition: 3d_cache.cpp:135
wxString ResolvePath(const wxString &aFileName)
Determines the full path of the given file name.
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
S3D_PLUGIN_MANAGER * m_Plugins
Definition: 3d_cache.h:177
static bool isSHA1Same(const unsigned char *shaA, const unsigned char *shaB) noexcept
Definition: 3d_cache.cpp:66

References checkCache(), S3D::Destroy3DModel(), S3D::DestroyNode(), ADVANCED_CFG::GetCfg(), getSHA1(), isSHA1Same(), S3D_PLUGIN_MANAGER::Load3DModel(), m_CacheMap, m_FNResolver, m_Plugins, ADVANCED_CFG::m_Skip3DModelMemoryCache, MASK_3D_CACHE, mutex3D_cache, reload, FILENAME_RESOLVER::ResolvePath(), and S3D_CACHE_ENTRY::sceneData.

Referenced by GetModel(), and Load().

◆ loadCacheData()

bool S3D_CACHE::loadCacheData ( S3D_CACHE_ENTRY aCacheItem)
private

Definition at line 413 of file 3d_cache.cpp.

414 {
415  wxString bname = aCacheItem->GetCacheBaseName();
416 
417  if( bname.empty() )
418  {
419  wxLogTrace( MASK_3D_CACHE,
420  " * [3D model] cannot load cached model; no file hash available" );
421 
422  return false;
423  }
424 
425  if( m_CacheDir.empty() )
426  {
427  wxLogTrace( MASK_3D_CACHE,
428  " * [3D model] cannot load cached model; config directory unknown" );
429 
430  return false;
431  }
432 
433  wxString fname = m_CacheDir + bname + wxT( ".3dc" );
434 
435  if( !wxFileName::FileExists( fname ) )
436  {
437  wxString errmsg = "cannot open file";
438  wxLogTrace( MASK_3D_CACHE, " * [3D model] %s '%s'", errmsg.GetData(), fname.GetData() );
439  return false;
440  }
441 
442  if( nullptr != aCacheItem->sceneData )
443  S3D::DestroyNode( (SGNODE*) aCacheItem->sceneData );
444 
445  aCacheItem->sceneData = (SCENEGRAPH*)S3D::ReadCache( fname.ToUTF8(), m_Plugins, checkTag );
446 
447  if( nullptr == aCacheItem->sceneData )
448  return false;
449 
450  return true;
451 }
SGLIB_API SGNODE * ReadCache(const char *aFileName, void *aPluginMgr, bool(*aTagCheck)(const char *, void *))
Function ReadCache reads a binary cache file and creates an SGNODE tree.
Definition: ifsg_api.cpp:219
#define MASK_3D_CACHE
Definition: 3d_cache.cpp:60
The base class of all Scene Graph nodes.
Definition: sg_node.h:74
const wxString GetCacheBaseName()
Definition: 3d_cache.cpp:178
SGLIB_API void DestroyNode(SGNODE *aNode) noexcept
Function DestroyNode deletes the given SG* class node.
Definition: ifsg_api.cpp:148
wxString m_CacheDir
Definition: 3d_cache.h:180
static bool checkTag(const char *aTag, void *aPluginMgrPtr)
Definition: 3d_cache.cpp:78
SCENEGRAPH * sceneData
Definition: 3d_cache.cpp:135
Define the basic data set required to represent a 3D model.
Definition: scenegraph.h:44
S3D_PLUGIN_MANAGER * m_Plugins
Definition: 3d_cache.h:177

References checkTag(), S3D::DestroyNode(), S3D_CACHE_ENTRY::GetCacheBaseName(), m_CacheDir, m_Plugins, MASK_3D_CACHE, S3D::ReadCache(), and S3D_CACHE_ENTRY::sceneData.

Referenced by checkCache().

◆ saveCacheData()

bool S3D_CACHE::saveCacheData ( S3D_CACHE_ENTRY aCacheItem)
private

Definition at line 454 of file 3d_cache.cpp.

455 {
456  if( nullptr == aCacheItem )
457  {
458  wxLogTrace( MASK_3D_CACHE, "%s:%s:%d\n * NULL passed for aCacheItem",
459  __FILE__, __FUNCTION__, __LINE__ );
460 
461  return false;
462  }
463 
464  if( nullptr == aCacheItem->sceneData )
465  {
466  wxLogTrace( MASK_3D_CACHE, "%s:%s:%d\n * aCacheItem has no valid scene data",
467  __FILE__, __FUNCTION__, __LINE__ );
468 
469  return false;
470  }
471 
472  wxString bname = aCacheItem->GetCacheBaseName();
473 
474  if( bname.empty() )
475  {
476  wxLogTrace( MASK_3D_CACHE,
477  " * [3D model] cannot load cached model; no file hash available" );
478 
479  return false;
480  }
481 
482  if( m_CacheDir.empty() )
483  {
484  wxLogTrace( MASK_3D_CACHE,
485  " * [3D model] cannot load cached model; config directory unknown" );
486 
487  return false;
488  }
489 
490  wxString fname = m_CacheDir + bname + wxT( ".3dc" );
491 
492  if( wxFileName::Exists( fname ) )
493  {
494  if( !wxFileName::FileExists( fname ) )
495  {
496  wxLogTrace( MASK_3D_CACHE, " * [3D model] path exists but is not a regular file '%s'",
497  fname );
498 
499  return false;
500  }
501  }
502 
503  return S3D::WriteCache( fname.ToUTF8(), true, (SGNODE*)aCacheItem->sceneData,
504  aCacheItem->pluginInfo.c_str() );
505 }
std::string pluginInfo
Definition: 3d_cache.cpp:134
#define MASK_3D_CACHE
Definition: 3d_cache.cpp:60
The base class of all Scene Graph nodes.
Definition: sg_node.h:74
const wxString GetCacheBaseName()
Definition: 3d_cache.cpp:178
wxString m_CacheDir
Definition: 3d_cache.h:180
SCENEGRAPH * sceneData
Definition: 3d_cache.cpp:135
SGLIB_API bool WriteCache(const char *aFileName, bool overwrite, SGNODE *aNode, const char *aPluginInfo)
Function WriteCache writes the SGNODE tree to a binary cache file.
Definition: ifsg_api.cpp:156

References S3D_CACHE_ENTRY::GetCacheBaseName(), m_CacheDir, MASK_3D_CACHE, S3D_CACHE_ENTRY::pluginInfo, S3D_CACHE_ENTRY::sceneData, and S3D::WriteCache().

Referenced by checkCache().

◆ Set3DConfigDir()

bool S3D_CACHE::Set3DConfigDir ( const wxString &  aConfigDir)

Sets the configuration directory to be used by the model manager for storing 3D model manager configuration data and the model cache.

The config directory may only be set once in the lifetime of the object.

Parameters
aConfigDiris the configuration directory to use for 3D model manager data
Returns
true on success

Definition at line 508 of file 3d_cache.cpp.

509 {
510  if( !m_ConfigDir.empty() )
511  return false;
512 
513  wxFileName cfgdir( ExpandEnvVarSubstitutions( aConfigDir, m_project ), "" );
514 
515  cfgdir.Normalize();
516 
517  if( !cfgdir.DirExists() )
518  {
519  cfgdir.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL );
520 
521  if( !cfgdir.DirExists() )
522  {
523  wxLogTrace( MASK_3D_CACHE,
524  "%s:%s:%d\n * failed to create 3D configuration directory '%s'",
525  __FILE__, __FUNCTION__, __LINE__, cfgdir.GetPath() );
526 
527  return false;
528  }
529  }
530 
531  m_ConfigDir = cfgdir.GetPath();
532 
533  // inform the file resolver of the config directory
535  {
536  wxLogTrace( MASK_3D_CACHE,
537  "%s:%s:%d\n * could not set 3D Config Directory on filename resolver\n"
538  " * config directory: '%s'",
539  __FILE__, __FUNCTION__, __LINE__, m_ConfigDir );
540  }
541 
542  // 3D cache data must go to a user's cache directory;
543  // unfortunately wxWidgets doesn't seem to provide
544  // functions to retrieve such a directory.
545  //
546  // 1. OSX: ~/Library/Caches/kicad/3d/
547  // 2. Linux: ${XDG_CACHE_HOME}/kicad/3d ~/.cache/kicad/3d/
548  // 3. MSWin: AppData\Local\kicad\3d
549  wxFileName cacheDir;
550  cacheDir.AssignDir( PATHS::GetUserCachePath() );
551  cacheDir.AppendDir( "3d" );
552 
553  if( !cacheDir.DirExists() )
554  {
555  cacheDir.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL );
556 
557  if( !cacheDir.DirExists() )
558  {
559  wxLogTrace( MASK_3D_CACHE, "%s:%s:%d\n * failed to create 3D cache directory '%s'",
560  __FILE__, __FUNCTION__, __LINE__, cacheDir.GetPath() );
561 
562  return false;
563  }
564  }
565 
566  m_CacheDir = cacheDir.GetPathWithSep();
567  return true;
568 }
#define MASK_3D_CACHE
Definition: 3d_cache.cpp:60
static wxString GetUserCachePath()
Gets the stock (install) 3d viewer plugins path.
Definition: paths.cpp:263
const wxString ExpandEnvVarSubstitutions(const wxString &aString, PROJECT *aProject)
Replace any environment variable & text variable references with their values.
Definition: common.cpp:267
FILENAME_RESOLVER * m_FNResolver
Definition: 3d_cache.h:175
wxString m_CacheDir
Definition: 3d_cache.h:180
wxString m_ConfigDir
Definition: 3d_cache.h:181
PROJECT * m_project
Definition: 3d_cache.h:179
bool Set3DConfigDir(const wxString &aConfigDir)
Set the user's configuration directory for 3D models.

References ExpandEnvVarSubstitutions(), PATHS::GetUserCachePath(), m_CacheDir, m_ConfigDir, m_FNResolver, m_project, MASK_3D_CACHE, and FILENAME_RESOLVER::Set3DConfigDir().

◆ SetProgramBase()

void S3D_CACHE::SetProgramBase ( PGM_BASE aBase)

Set the filename resolver's pointer to the application's PGM_BASE instance.

The pointer is used to extract the local environment variables.

Definition at line 599 of file 3d_cache.cpp.

600 {
601  m_FNResolver->SetProgramBase( aBase );
602 }
FILENAME_RESOLVER * m_FNResolver
Definition: 3d_cache.h:175
void SetProgramBase(PGM_BASE *aBase)
Set a pointer to the application's PGM_BASE instance used to extract the local env vars.

References m_FNResolver, and FILENAME_RESOLVER::SetProgramBase().

◆ SetProject()

bool S3D_CACHE::SetProject ( PROJECT aProject)

Set the current project's working directory; this affects the model search path.

Definition at line 571 of file 3d_cache.cpp.

572 {
573  m_project = aProject;
574 
575  bool hasChanged = false;
576 
577  if( m_FNResolver->SetProject( aProject, &hasChanged ) && hasChanged )
578  {
579  m_CacheMap.clear();
580 
581  std::list< S3D_CACHE_ENTRY* >::iterator sL = m_CacheList.begin();
582  std::list< S3D_CACHE_ENTRY* >::iterator eL = m_CacheList.end();
583 
584  while( sL != eL )
585  {
586  delete *sL;
587  ++sL;
588  }
589 
590  m_CacheList.clear();
591 
592  return true;
593  }
594 
595  return false;
596 }
std::map< wxString, S3D_CACHE_ENTRY *, rsort_wxString > m_CacheMap
mapping of file names to cache names and data
Definition: 3d_cache.h:173
FILENAME_RESOLVER * m_FNResolver
Definition: 3d_cache.h:175
std::list< S3D_CACHE_ENTRY * > m_CacheList
cache entries
Definition: 3d_cache.h:170
bool SetProject(PROJECT *aProject, bool *flgChanged=nullptr)
Set the current KiCad project directory as the first entry in the model path list.
PROJECT * m_project
Definition: 3d_cache.h:179

References m_CacheList, m_CacheMap, m_FNResolver, m_project, and FILENAME_RESOLVER::SetProject().

◆ Type()

KICAD_T S3D_CACHE::Type ( )
inlineoverridevirtualnoexcept

Implements PROJECT::_ELEM.

Definition at line 58 of file 3d_cache.h.

59  {
60  return S3D_CACHE_T;
61  }

References S3D_CACHE_T.

Member Data Documentation

◆ m_CacheDir

wxString S3D_CACHE::m_CacheDir
private

Definition at line 180 of file 3d_cache.h.

Referenced by checkCache(), CleanCacheDir(), loadCacheData(), saveCacheData(), and Set3DConfigDir().

◆ m_CacheList

std::list< S3D_CACHE_ENTRY* > S3D_CACHE::m_CacheList
private

cache entries

Definition at line 170 of file 3d_cache.h.

Referenced by checkCache(), FlushCache(), and SetProject().

◆ m_CacheMap

std::map< wxString, S3D_CACHE_ENTRY*, rsort_wxString > S3D_CACHE::m_CacheMap
private

mapping of file names to cache names and data

Definition at line 173 of file 3d_cache.h.

Referenced by checkCache(), FlushCache(), load(), and SetProject().

◆ m_ConfigDir

wxString S3D_CACHE::m_ConfigDir
private

Definition at line 181 of file 3d_cache.h.

Referenced by Set3DConfigDir().

◆ m_FNResolver

FILENAME_RESOLVER* S3D_CACHE::m_FNResolver
private

◆ m_Plugins

S3D_PLUGIN_MANAGER* S3D_CACHE::m_Plugins
private

◆ m_project

PROJECT* S3D_CACHE::m_project
private

Definition at line 179 of file 3d_cache.h.

Referenced by S3D_CACHE(), Set3DConfigDir(), and SetProject().


The documentation for this class was generated from the following files: