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:619
void CleanCacheDir(int aNumDaysOld)
Delete up old cache files in cache directory.
Definition: 3d_cache.cpp:671
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,
311  wxT( "%s:%s:%d\n * [BUG] duplicate entry in map file; key = '%s'" ),
312  __FILE__, __FUNCTION__, __LINE__, aFileName );
313 
314  m_CacheList.pop_back();
315  delete ep;
316  }
317  else
318  {
319  if( aCachePtr )
320  *aCachePtr = ep;
321  }
322 
323  return nullptr;
324  }
325 
326  if( m_CacheMap.insert( std::pair< wxString, S3D_CACHE_ENTRY* >
327  ( aFileName, ep ) ).second == false )
328  {
329  wxLogTrace( MASK_3D_CACHE,
330  wxT( "%s:%s:%d\n * [BUG] duplicate entry in map file; key = '%s'" ),
331  __FILE__, __FUNCTION__, __LINE__, aFileName );
332 
333  m_CacheList.pop_back();
334  delete ep;
335  return nullptr;
336  }
337 
338  if( aCachePtr )
339  *aCachePtr = ep;
340 
341  ep->SetSHA1( sha1sum );
342 
343  wxString bname = ep->GetCacheBaseName();
344  wxString cachename = m_CacheDir + bname + wxT( ".3dc" );
345 
346  if( !ADVANCED_CFG::GetCfg().m_Skip3DModelFileCache && wxFileName::FileExists( cachename )
347  && loadCacheData( ep ) )
348  return ep->sceneData;
349 
350  ep->sceneData = m_Plugins->Load3DModel( aFileName, ep->pluginInfo );
351 
352  if( !ADVANCED_CFG::GetCfg().m_Skip3DModelFileCache && nullptr != ep->sceneData )
353  saveCacheData( ep );
354 
355  return ep->sceneData;
356 }
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:415
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:455
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:359
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 671 of file 3d_cache.cpp.

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

639 {
640  if( m_Plugins )
642 }
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 619 of file 3d_cache.cpp.

620 {
621  std::list< S3D_CACHE_ENTRY* >::iterator sCL = m_CacheList.begin();
622  std::list< S3D_CACHE_ENTRY* >::iterator eCL = m_CacheList.end();
623 
624  while( sCL != eCL )
625  {
626  delete *sCL;
627  ++sCL;
628  }
629 
630  m_CacheList.clear();
631  m_CacheMap.clear();
632 
633  if( closePlugins )
634  ClosePlugins();
635 }
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:638
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 613 of file 3d_cache.cpp.

614 {
615  return m_Plugins->GetFileFilters();
616 }
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 645 of file 3d_cache.cpp.

646 {
647  S3D_CACHE_ENTRY* cp = nullptr;
648  SCENEGRAPH* sp = load( aModelFileName, &cp );
649 
650  if( !sp )
651  return nullptr;
652 
653  if( !cp )
654  {
655  wxLogTrace( MASK_3D_CACHE,
656  wxT( "%s:%s:%d\n * [BUG] model loaded with no associated S3D_CACHE_ENTRY" ),
657  __FILE__, __FUNCTION__, __LINE__ );
658 
659  return nullptr;
660  }
661 
662  if( cp->renderData )
663  return cp->renderData;
664 
665  S3DMODEL* mp = S3D::GetModel( sp );
666  cp->renderData = mp;
667 
668  return mp;
669 }
#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:338
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_OPENGL::load3dModels(), and EDA_3D_MODEL_VIEWER::Set3DModel().

◆ GetResolver()

FILENAME_RESOLVER * S3D_CACHE::GetResolver ( )
noexcept

Definition at line 607 of file 3d_cache.cpp.

608 {
609  return m_FNResolver;
610 }
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 359 of file 3d_cache.cpp.

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

416 {
417  wxString bname = aCacheItem->GetCacheBaseName();
418 
419  if( bname.empty() )
420  {
421  wxLogTrace( MASK_3D_CACHE,
422  wxT( " * [3D model] cannot load cached model; no file hash available" ) );
423 
424  return false;
425  }
426 
427  if( m_CacheDir.empty() )
428  {
429  wxLogTrace( MASK_3D_CACHE,
430  wxT( " * [3D model] cannot load cached model; config directory unknown" ) );
431 
432  return false;
433  }
434 
435  wxString fname = m_CacheDir + bname + wxT( ".3dc" );
436 
437  if( !wxFileName::FileExists( fname ) )
438  {
439  wxLogTrace( MASK_3D_CACHE, wxT( " * [3D model] cannot open file '%s'" ), fname.GetData() );
440  return false;
441  }
442 
443  if( nullptr != aCacheItem->sceneData )
444  S3D::DestroyNode( (SGNODE*) aCacheItem->sceneData );
445 
446  aCacheItem->sceneData = (SCENEGRAPH*)S3D::ReadCache( fname.ToUTF8(), m_Plugins, checkTag );
447 
448  if( nullptr == aCacheItem->sceneData )
449  return false;
450 
451  return true;
452 }
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:221
#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:149
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 455 of file 3d_cache.cpp.

456 {
457  if( nullptr == aCacheItem )
458  {
459  wxLogTrace( MASK_3D_CACHE, wxT( "%s:%s:%d\n * NULL passed for aCacheItem" ),
460  __FILE__, __FUNCTION__, __LINE__ );
461 
462  return false;
463  }
464 
465  if( nullptr == aCacheItem->sceneData )
466  {
467  wxLogTrace( MASK_3D_CACHE, wxT( "%s:%s:%d\n * aCacheItem has no valid scene data" ),
468  __FILE__, __FUNCTION__, __LINE__ );
469 
470  return false;
471  }
472 
473  wxString bname = aCacheItem->GetCacheBaseName();
474 
475  if( bname.empty() )
476  {
477  wxLogTrace( MASK_3D_CACHE,
478  wxT( " * [3D model] cannot load cached model; no file hash available" ) );
479 
480  return false;
481  }
482 
483  if( m_CacheDir.empty() )
484  {
485  wxLogTrace( MASK_3D_CACHE,
486  wxT( " * [3D model] cannot load cached model; config directory unknown" ) );
487 
488  return false;
489  }
490 
491  wxString fname = m_CacheDir + bname + wxT( ".3dc" );
492 
493  if( wxFileName::Exists( fname ) )
494  {
495  if( !wxFileName::FileExists( fname ) )
496  {
497  wxLogTrace( MASK_3D_CACHE,
498  wxT( " * [3D model] path exists but is not a regular file '%s'" ), fname );
499 
500  return false;
501  }
502  }
503 
504  return S3D::WriteCache( fname.ToUTF8(), true, (SGNODE*)aCacheItem->sceneData,
505  aCacheItem->pluginInfo.c_str() );
506 }
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:157

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 509 of file 3d_cache.cpp.

510 {
511  if( !m_ConfigDir.empty() )
512  return false;
513 
514  wxFileName cfgdir( ExpandEnvVarSubstitutions( aConfigDir, m_project ), wxEmptyString );
515 
516  cfgdir.Normalize();
517 
518  if( !cfgdir.DirExists() )
519  {
520  cfgdir.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL );
521 
522  if( !cfgdir.DirExists() )
523  {
524  wxLogTrace( MASK_3D_CACHE,
525  wxT( "%s:%s:%d\n * failed to create 3D configuration directory '%s'" ),
526  __FILE__, __FUNCTION__, __LINE__, cfgdir.GetPath() );
527 
528  return false;
529  }
530  }
531 
532  m_ConfigDir = cfgdir.GetPath();
533 
534  // inform the file resolver of the config directory
536  {
537  wxLogTrace( MASK_3D_CACHE,
538  wxT( "%s:%s:%d\n * could not set 3D Config Directory on filename resolver\n"
539  " * config directory: '%s'" ),
540  __FILE__, __FUNCTION__, __LINE__, m_ConfigDir );
541  }
542 
543  // 3D cache data must go to a user's cache directory;
544  // unfortunately wxWidgets doesn't seem to provide
545  // functions to retrieve such a directory.
546  //
547  // 1. OSX: ~/Library/Caches/kicad/3d/
548  // 2. Linux: ${XDG_CACHE_HOME}/kicad/3d ~/.cache/kicad/3d/
549  // 3. MSWin: AppData\Local\kicad\3d
550  wxFileName cacheDir;
551  cacheDir.AssignDir( PATHS::GetUserCachePath() );
552  cacheDir.AppendDir( wxT( "3d" ) );
553 
554  if( !cacheDir.DirExists() )
555  {
556  cacheDir.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL );
557 
558  if( !cacheDir.DirExists() )
559  {
560  wxLogTrace( MASK_3D_CACHE,
561  wxT( "%s:%s:%d\n * failed to create 3D cache directory '%s'" ),
562  __FILE__, __FUNCTION__, __LINE__, cacheDir.GetPath() );
563 
564  return false;
565  }
566  }
567 
568  m_CacheDir = cacheDir.GetPathWithSep();
569  return true;
570 }
#define MASK_3D_CACHE
Definition: 3d_cache.cpp:60
static wxString GetUserCachePath()
Gets the stock (install) 3d viewer plugins path.
Definition: paths.cpp:313
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 601 of file 3d_cache.cpp.

602 {
603  m_FNResolver->SetProgramBase( aBase );
604 }
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 573 of file 3d_cache.cpp.

574 {
575  m_project = aProject;
576 
577  bool hasChanged = false;
578 
579  if( m_FNResolver->SetProject( aProject, &hasChanged ) && hasChanged )
580  {
581  m_CacheMap.clear();
582 
583  std::list< S3D_CACHE_ENTRY* >::iterator sL = m_CacheList.begin();
584  std::list< S3D_CACHE_ENTRY* >::iterator eL = m_CacheList.end();
585 
586  while( sL != eL )
587  {
588  delete *sL;
589  ++sL;
590  }
591 
592  m_CacheList.clear();
593 
594  return true;
595  }
596 
597  return false;
598 }
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: