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

187 {
189  m_project = nullptr;
191 }
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 194 of file 3d_cache.cpp.

195 {
196  COMMON_SETTINGS* commonSettings = Pgm().GetCommonSettings();
197 
198  FlushCache();
199 
200  // We'll delete ".3dc" cache files older than this many days
201  int clearCacheInterval = commonSettings->m_System.clear_3d_cache_interval;
202 
203  // An interval of zero means the user doesn't want to ever clear the cache
204 
205  if( clearCacheInterval > 0 )
206  CleanCacheDir( clearCacheInterval );
207 
208  delete m_FNResolver;
209  delete m_Plugins;
210 }
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:620
void CleanCacheDir(int aNumDaysOld)
Delete up old cache files in cache directory.
Definition: 3d_cache.cpp:672
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 289 of file 3d_cache.cpp.

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

References S3D_CACHE_ENTRY::GetCacheBaseName(), 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 672 of file 3d_cache.cpp.

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

640 {
641  if( m_Plugins )
643 }
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 620 of file 3d_cache.cpp.

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

615 {
616  return m_Plugins->GetFileFilters();
617 }
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 DLG_SELECT_3DMODEL::DLG_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 646 of file 3d_cache.cpp.

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

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

Referenced by RENDER_3D_LEGACY::load3dModels(), RENDER_3D_RAYTRACE::loadModels(), and C3D_MODEL_VIEWER::Set3DModel().

◆ GetResolver()

FILENAME_RESOLVER * S3D_CACHE::GetResolver ( )
noexcept

Definition at line 608 of file 3d_cache.cpp.

609 {
610  return m_FNResolver;
611 }
FILENAME_RESOLVER * m_FNResolver
Definition: 3d_cache.h:175

References m_FNResolver.

Referenced by DLG_SELECT_3DMODEL::DLG_SELECT_3DMODEL(), and 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 360 of file 3d_cache.cpp.

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

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

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

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

214 {
215  if( aCachePtr )
216  *aCachePtr = nullptr;
217 
218  wxString full3Dpath = m_FNResolver->ResolvePath( aModelFile );
219 
220  if( full3Dpath.empty() )
221  {
222  // the model cannot be found; we cannot proceed
223  wxLogTrace( MASK_3D_CACHE, "%s:%s:%d\n * [3D model] could not find model '%s'\n",
224  __FILE__, __FUNCTION__, __LINE__, aModelFile );
225  return nullptr;
226  }
227 
228  // check cache if file is already loaded
229  std::lock_guard<std::mutex> lock( mutex3D_cache );
230 
231  std::map< wxString, S3D_CACHE_ENTRY*, rsort_wxString >::iterator mi;
232  mi = m_CacheMap.find( full3Dpath );
233 
234  if( mi != m_CacheMap.end() )
235  {
236  wxFileName fname( full3Dpath );
237 
238  if( fname.FileExists() ) // Only check if file exists. If not, it will
239  { // use the same model in cache.
240  bool reload = false;
241  wxDateTime fmdate = fname.GetModificationTime();
242 
243  if( fmdate != mi->second->modTime )
244  {
245  unsigned char hashSum[20];
246  getSHA1( full3Dpath, hashSum );
247  mi->second->modTime = fmdate;
248 
249  if( !isSHA1Same( hashSum, mi->second->sha1sum ) )
250  {
251  mi->second->SetSHA1( hashSum );
252  reload = true;
253  }
254  }
255 
256  if( reload )
257  {
258  if( nullptr != mi->second->sceneData )
259  {
260  S3D::DestroyNode( mi->second->sceneData );
261  mi->second->sceneData = nullptr;
262  }
263 
264  if( nullptr != mi->second->renderData )
265  S3D::Destroy3DModel( &mi->second->renderData );
266 
267  mi->second->sceneData = m_Plugins->Load3DModel( full3Dpath,
268  mi->second->pluginInfo );
269  }
270  }
271 
272  if( nullptr != aCachePtr )
273  *aCachePtr = mi->second;
274 
275  return mi->second->sceneData;
276  }
277 
278  // a cache item does not exist; search the Filename->Cachename map
279  return checkCache( full3Dpath, aCachePtr );
280 }
#define MASK_3D_CACHE
Definition: 3d_cache.cpp:59
static std::mutex mutex3D_cache
Definition: 3d_cache.cpp:61
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:289
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:360
SCENEGRAPH * sceneData
Definition: 3d_cache.cpp:134
wxString ResolvePath(const wxString &aFileName)
Determines the full path of the given file name.
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:65

References checkCache(), S3D::Destroy3DModel(), S3D::DestroyNode(), getSHA1(), isSHA1Same(), S3D_PLUGIN_MANAGER::Load3DModel(), m_CacheMap, m_FNResolver, m_Plugins, 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 416 of file 3d_cache.cpp.

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

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

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

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

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