KiCad PCB EDA Suite
S3D_CACHE Class Reference

#include <3d_cache.h>

Inheritance diagram for S3D_CACHE:
CACHE_WRAPPER

Public Member Functions

 S3D_CACHE ()
 
virtual ~S3D_CACHE ()
 
bool Set3DConfigDir (const wxString &aConfigDir)
 Function Set3DConfigDir Sets the configuration directory to be used by the model manager for storing 3D model manager configuration data and the model cache. More...
 
wxString Get3DConfigDir (bool createDefault=false)
 Function Get3DConfigDir returns the current 3D configuration directory on success, otherwise it returns wxEmptyString. More...
 
bool SetProjectDir (const wxString &aProjDir)
 Function SetProjectDir sets the current project's working directory; this affects the model search path. More...
 
void SetProgramBase (PGM_BASE *aBase)
 Function SetProgramBase sets the filename resolver's pointer to the application's PGM_BASE instance; the pointer is used to extract the local env vars. More...
 
wxString GetProjectDir (void)
 Function GetProjectDir returns the current project's working directory. More...
 
SCENEGRAPHLoad (const wxString &aModelFile)
 Function Load attempts 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. More...
 
S3D_FILENAME_RESOLVERGetResolver (void)
 
std::list< wxString > const * GetFileFilters (void) const
 Function GetFileFilters returns the list of file filters retrieved from the plugins; this will contain at least the default "All Files (*.*)|*.*". More...
 
void FlushCache (bool closePlugins=true)
 Function FlushCache frees all data in the cache and by default closes all plugins. More...
 
void ClosePlugins (void)
 Function ClosePlugins unloads plugins to free memory. More...
 
S3DMODELGetModel (const wxString &aModelFileName)
 Function GetModel attempts to load the scene data for a model and to translate it into an S3D_MODEL structure for display by a renderer. More...
 
wxString GetModelHash (const wxString &aModelFileName)
 

Private Member Functions

SCENEGRAPHcheckCache (const wxString &aFileName, S3D_CACHE_ENTRY **aCachePtr=NULL)
 Find or create cache entry for file name. More...
 
bool getSHA1 (const wxString &aFileName, unsigned char *aSHA1Sum)
 Function getSHA1 calculates 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=NULL)
 

Private Attributes

std::list< S3D_CACHE_ENTRY * > m_CacheList
 cache entries More...
 
std::map< wxString, S3D_CACHE_ENTRY *, S3D::rsort_wxStringm_CacheMap
 mapping of file names to cache names and data More...
 
S3D_FILENAME_RESOLVERm_FNResolver
 object to resolve file names More...
 
S3D_PLUGIN_MANAGERm_Plugins
 plugin manager More...
 
bool m_DirtyCache
 set true if the cache needs to be updated More...
 
wxString m_CacheDir
 3D cache directory More...
 
wxString m_ConfigDir
 base configuration path for 3D items More...
 
wxString m_ProjDir
 current KiCad project dir More...
 

Detailed Description

Definition at line 50 of file 3d_cache.h.

Constructor & Destructor Documentation

S3D_CACHE::S3D_CACHE ( )

Definition at line 180 of file 3d_cache.cpp.

References m_DirtyCache, m_FNResolver, and m_Plugins.

181 {
182  m_DirtyCache = false;
185 
186  return;
187 }
bool m_DirtyCache
set true if the cache needs to be updated
Definition: 3d_cache.h:66
S3D_FILENAME_RESOLVER * m_FNResolver
object to resolve file names
Definition: 3d_cache.h:60
S3D_PLUGIN_MANAGER * m_Plugins
plugin manager
Definition: 3d_cache.h:63
S3D_CACHE::~S3D_CACHE ( )
virtual

Definition at line 189 of file 3d_cache.cpp.

References FlushCache(), m_FNResolver, and m_Plugins.

190 {
191  FlushCache();
192 
193  if( m_FNResolver )
194  delete m_FNResolver;
195 
196  if( m_Plugins )
197  delete m_Plugins;
198 
199  return;
200 }
void FlushCache(bool closePlugins=true)
Function FlushCache frees all data in the cache and by default closes all plugins.
Definition: 3d_cache.cpp:751
S3D_FILENAME_RESOLVER * m_FNResolver
object to resolve file names
Definition: 3d_cache.h:60
S3D_PLUGIN_MANAGER * m_Plugins
plugin manager
Definition: 3d_cache.h:63

Member Function Documentation

SCENEGRAPH * S3D_CACHE::checkCache ( const wxString &  aFileName,
S3D_CACHE_ENTRY **  aCachePtr = NULL 
)
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
[in]aFileNamefile name (full or partial path)
[out]aCachePtroptional return address for cache entry pointer
Returns
SCENEGRAPH object associated with file name
Return values
NULLon error

Definition at line 277 of file 3d_cache.cpp.

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 GetModelHash(), and load().

278 {
279  if( aCachePtr )
280  *aCachePtr = NULL;
281 
282  unsigned char sha1sum[20];
283 
284  if( !getSHA1( aFileName, sha1sum ) || m_CacheDir.empty() )
285  {
286  // just in case we can't get a hash digest (for example, on access issues)
287  // or we do not have a configured cache file directory, we create an
288  // entry to prevent further attempts at loading the file
290  m_CacheList.push_back( ep );
291  wxFileName fname( aFileName );
292  ep->modTime = fname.GetModificationTime();
293 
294  if( m_CacheMap.insert( std::pair< wxString, S3D_CACHE_ENTRY* >
295  ( aFileName, ep ) ).second == false )
296  {
297  #ifdef DEBUG
298  do {
299  std::ostringstream ostr;
300  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
301  ostr << " * [BUG] duplicate entry in map file; key = '";
302  ostr << aFileName.ToUTF8() << "'";
303  wxLogTrace( MASK_3D_CACHE, "%s\n", ostr.str().c_str() );
304  } while( 0 );
305  #endif
306 
307  m_CacheList.pop_back();
308  delete ep;
309  }
310  else
311  {
312  if( aCachePtr )
313  *aCachePtr = ep;
314 
315  }
316 
317  return NULL;
318  }
319 
321  m_CacheList.push_back( ep );
322  wxFileName fname( aFileName );
323  ep->modTime = fname.GetModificationTime();
324 
325  if( m_CacheMap.insert( std::pair< wxString, S3D_CACHE_ENTRY* >
326  ( aFileName, ep ) ).second == false )
327  {
328  #ifdef DEBUG
329  do {
330  std::ostringstream ostr;
331  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
332  ostr << " * [BUG] duplicate entry in map file; key = '";
333  ostr << aFileName.ToUTF8() << "'";
334  wxLogTrace( MASK_3D_CACHE, "%s\n", ostr.str().c_str() );
335  } while( 0 );
336  #endif
337 
338  m_CacheList.pop_back();
339  delete ep;
340  return NULL;
341  }
342 
343  if( aCachePtr )
344  *aCachePtr = ep;
345 
346  ep->SetSHA1( sha1sum );
347 
348  wxString bname = ep->GetCacheBaseName();
349  wxString cachename = m_CacheDir + bname + wxT( ".3dc" );
350 
351  if( wxFileName::FileExists( cachename ) && loadCacheData( ep ) )
352  return ep->sceneData;
353 
354  ep->sceneData = m_Plugins->Load3DModel( aFileName, ep->pluginInfo );
355 
356  if( NULL != ep->sceneData )
357  saveCacheData( ep );
358 
359  return ep->sceneData;
360 }
std::string pluginInfo
Definition: 3d_cache.cpp:126
#define MASK_3D_CACHE
Definition: 3d_cache.cpp:51
const wxString GetCacheBaseName(void)
Definition: 3d_cache.cpp:171
bool loadCacheData(S3D_CACHE_ENTRY *aCacheItem)
Definition: 3d_cache.cpp:431
SCENEGRAPH * Load3DModel(const wxString &aFileName, std::string &aPluginInfo)
std::map< wxString, S3D_CACHE_ENTRY *, S3D::rsort_wxString > m_CacheMap
mapping of file names to cache names and data
Definition: 3d_cache.h:57
bool saveCacheData(S3D_CACHE_ENTRY *aCacheItem)
Definition: 3d_cache.cpp:474
wxDateTime modTime
Definition: 3d_cache.cpp:124
wxString m_CacheDir
3D cache directory
Definition: 3d_cache.h:69
void SetSHA1(const unsigned char *aSHA1Sum)
Definition: 3d_cache.cpp:150
bool getSHA1(const wxString &aFileName, unsigned char *aSHA1Sum)
Function getSHA1 calculates the SHA1 hash of the given file.
Definition: 3d_cache.cpp:363
SCENEGRAPH * sceneData
Definition: 3d_cache.cpp:127
std::list< S3D_CACHE_ENTRY * > m_CacheList
cache entries
Definition: 3d_cache.h:54
Definition: 3d_cache.cpp:108
S3D_PLUGIN_MANAGER * m_Plugins
plugin manager
Definition: 3d_cache.h:63
void S3D_CACHE::ClosePlugins ( void  )

Function ClosePlugins unloads plugins to free memory.

Definition at line 772 of file 3d_cache.cpp.

References S3D_PLUGIN_MANAGER::ClosePlugins(), and m_Plugins.

Referenced by FlushCache().

773 {
774  if( NULL != m_Plugins )
776 
777  return;
778 }
void ClosePlugins(void)
Function ClosePlugins iterates through all discovered plugins and closes them to reclaim memory...
S3D_PLUGIN_MANAGER * m_Plugins
plugin manager
Definition: 3d_cache.h:63
void S3D_CACHE::FlushCache ( bool  closePlugins = true)

Function FlushCache frees all data in the cache and by default closes all plugins.

Definition at line 751 of file 3d_cache.cpp.

References ClosePlugins(), m_CacheList, and m_CacheMap.

Referenced by ~S3D_CACHE().

752 {
753  std::list< S3D_CACHE_ENTRY* >::iterator sCL = m_CacheList.begin();
754  std::list< S3D_CACHE_ENTRY* >::iterator eCL = m_CacheList.end();
755 
756  while( sCL != eCL )
757  {
758  delete *sCL;
759  ++sCL;
760  }
761 
762  m_CacheList.clear();
763  m_CacheMap.clear();
764 
765  if( closePlugins )
766  ClosePlugins();
767 
768  return;
769 }
std::map< wxString, S3D_CACHE_ENTRY *, S3D::rsort_wxString > m_CacheMap
mapping of file names to cache names and data
Definition: 3d_cache.h:57
std::list< S3D_CACHE_ENTRY * > m_CacheList
cache entries
Definition: 3d_cache.h:54
void ClosePlugins(void)
Function ClosePlugins unloads plugins to free memory.
Definition: 3d_cache.cpp:772
wxString S3D_CACHE::Get3DConfigDir ( bool  createDefault = false)

Function Get3DConfigDir returns the current 3D configuration directory on success, otherwise it returns wxEmptyString.

If the directory was not previously set via Set3DConfigDir() then a default is used which is based on kicad's configuration directory code as of September 2015.

Definition at line 642 of file 3d_cache.cpp.

References ExpandEnvVarSubstitutions(), m_ConfigDir, MASK_3D_CACHE, and Set3DConfigDir().

643 {
644  if( !m_ConfigDir.empty() || !createDefault )
645  return m_ConfigDir;
646 
647  // note: duplicated from common/common.cpp GetKicadConfigPath() to avoid
648  // code coupling; ideally the instantiating code should call
649  // Set3DConfigDir() to set the directory rather than relying on this
650  // directory remaining the same in future KiCad releases.
651  wxFileName cfgpath;
652 
653  // From the wxWidgets wxStandardPaths::GetUserConfigDir() help:
654  // Unix: ~ (the home directory)
655  // Windows: "C:\Documents and Settings\username\Application Data"
656  // Mac: ~/Library/Preferences
657  cfgpath.AssignDir( wxStandardPaths::Get().GetUserConfigDir() );
658 
659 #if !defined( __WINDOWS__ ) && !defined( __WXMAC__ )
660  wxString envstr = ExpandEnvVarSubstitutions( "${XDG_CONFIG_HOME}" );
661 
662  if( envstr.IsEmpty() || envstr == "${XDG_CONFIG_HOME}" )
663  {
664  // XDG_CONFIG_HOME is not set, so use the fallback
665  cfgpath.AppendDir( wxT( ".config" ) );
666  }
667  else
668  {
669  // Override the assignment above with XDG_CONFIG_HOME
670  cfgpath.AssignDir( envstr );
671  }
672 #endif
673 
674  cfgpath.AppendDir( wxT( "kicad" ) );
675  cfgpath.AppendDir( wxT( "3d" ) );
676 
677  if( !cfgpath.DirExists() )
678  {
679  cfgpath.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL );
680  }
681 
682  if( !cfgpath.DirExists() )
683  {
684  std::ostringstream ostr;
685  wxString errmsg = "failed to create 3D configuration directory";
686  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
687  ostr << " * " << errmsg.ToUTF8();
688  wxLogTrace( MASK_3D_CACHE, "%s\n", ostr.str().c_str() );
689 
690  return wxT( "" );
691  }
692 
693  if( Set3DConfigDir( cfgpath.GetPath() ) )
694  return m_ConfigDir;
695 
696  return wxEmptyString;
697 }
#define MASK_3D_CACHE
Definition: 3d_cache.cpp:51
const wxString ExpandEnvVarSubstitutions(const wxString &aString)
Function ExpandEnvVarSubstitutions replaces any environment variable references with their values...
Definition: common.cpp:254
bool Set3DConfigDir(const wxString &aConfigDir)
Function Set3DConfigDir Sets the configuration directory to be used by the model manager for storing ...
Definition: 3d_cache.cpp:542
wxString m_ConfigDir
base configuration path for 3D items
Definition: 3d_cache.h:72
std::list< wxString > const * S3D_CACHE::GetFileFilters ( void  ) const

Function GetFileFilters returns 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 745 of file 3d_cache.cpp.

References S3D_PLUGIN_MANAGER::GetFileFilters(), and m_Plugins.

746 {
747  return m_Plugins->GetFileFilters();
748 }
std::list< wxString > const * GetFileFilters(void) const
Function GetFileFilters returns the list of file filters; this will contain at least the default "All...
S3D_PLUGIN_MANAGER * m_Plugins
plugin manager
Definition: 3d_cache.h:63
S3DMODEL * S3D_CACHE::GetModel ( const wxString &  aModelFileName)

Function GetModel attempts 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 781 of file 3d_cache.cpp.

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

Referenced by C3D_RENDER_OGL_LEGACY::load_3D_models(), C3D_RENDER_RAYTRACING::load_3D_models(), and C3D_MODEL_VIEWER::Set3DModel().

782 {
783  S3D_CACHE_ENTRY* cp = NULL;
784  SCENEGRAPH* sp = load( aModelFileName, &cp );
785 
786  if( !sp )
787  return NULL;
788 
789  if( !cp )
790  {
791  #ifdef DEBUG
792  do {
793  std::ostringstream ostr;
794  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
795  ostr << " * [BUG] model loaded with no associated S3D_CACHE_ENTRY";
796  wxLogTrace( MASK_3D_CACHE, "%s\n", ostr.str().c_str() );
797  } while( 0 );
798  #endif
799 
800  return NULL;
801  }
802 
803  if( cp->renderData )
804  return cp->renderData;
805 
806  S3DMODEL* mp = S3D::GetModel( sp );
807  cp->renderData = mp;
808 
809  return mp;
810 }
#define MASK_3D_CACHE
Definition: 3d_cache.cpp:51
SCENEGRAPH * load(const wxString &aModelFile, S3D_CACHE_ENTRY **aCachePtr=NULL)
Definition: 3d_cache.cpp:203
S3DMODEL * renderData
Definition: 3d_cache.cpp:128
Store the a model based on meshes and materials.
Definition: c3dmodel.h:90
Definition: 3d_cache.cpp:108
SGLIB_API S3DMODEL * GetModel(SCENEGRAPH *aNode)
Function GetModel creates an S3DMODEL representation of aNode (raw data, no transforms) ...
Definition: ifsg_api.cpp:478
wxString S3D_CACHE::GetModelHash ( const wxString &  aModelFileName)

Definition at line 813 of file 3d_cache.cpp.

References checkCache(), S3D_CACHE_ENTRY::GetCacheBaseName(), m_CacheMap, m_FNResolver, and S3D_FILENAME_RESOLVER::ResolvePath().

814 {
815  wxString full3Dpath = m_FNResolver->ResolvePath( aModelFileName );
816 
817  if( full3Dpath.empty() || !wxFileName::FileExists( full3Dpath ) )
818  return wxEmptyString;
819 
820  // check cache if file is already loaded
821  std::map< wxString, S3D_CACHE_ENTRY*, S3D::rsort_wxString >::iterator mi;
822  mi = m_CacheMap.find( full3Dpath );
823 
824  if( mi != m_CacheMap.end() )
825  return mi->second->GetCacheBaseName();
826 
827  // a cache item does not exist; search the Filename->Cachename map
828  S3D_CACHE_ENTRY* cp = NULL;
829  checkCache( full3Dpath, &cp );
830 
831  if( NULL != cp )
832  return cp->GetCacheBaseName();
833 
834  return wxEmptyString;
835 }
const wxString GetCacheBaseName(void)
Definition: 3d_cache.cpp:171
std::map< wxString, S3D_CACHE_ENTRY *, S3D::rsort_wxString > m_CacheMap
mapping of file names to cache names and data
Definition: 3d_cache.h:57
SCENEGRAPH * checkCache(const wxString &aFileName, S3D_CACHE_ENTRY **aCachePtr=NULL)
Find or create cache entry for file name.
Definition: 3d_cache.cpp:277
wxString ResolvePath(const wxString &aFileName)
Function ResolvePath determines the full path of the given file name.
S3D_FILENAME_RESOLVER * m_FNResolver
object to resolve file names
Definition: 3d_cache.h:60
Definition: 3d_cache.cpp:108
wxString S3D_CACHE::GetProjectDir ( void  )

Function GetProjectDir returns the current project's working directory.

Definition at line 733 of file 3d_cache.cpp.

References S3D_FILENAME_RESOLVER::GetProjectDir(), and m_FNResolver.

734 {
735  return m_FNResolver->GetProjectDir();
736 }
S3D_FILENAME_RESOLVER * m_FNResolver
object to resolve file names
Definition: 3d_cache.h:60
S3D_FILENAME_RESOLVER * S3D_CACHE::GetResolver ( void  )

Definition at line 739 of file 3d_cache.cpp.

References m_FNResolver.

Referenced by export_vrml_module(), and PANEL_PREV_3D::PANEL_PREV_3D().

740 {
741  return m_FNResolver;
742 }
S3D_FILENAME_RESOLVER * m_FNResolver
object to resolve file names
Definition: 3d_cache.h:60
bool S3D_CACHE::getSHA1 ( const wxString &  aFileName,
unsigned char *  aSHA1Sum 
)
private

Function getSHA1 calculates the SHA1 hash of the given file.

Parameters
[in]aFileNamefile name (full path)
[out]aSHA1Suma 20 byte character array to hold the SHA1 hash
Return values
truesuccess
falsefailure

Definition at line 363 of file 3d_cache.cpp.

References MASK_3D_CACHE.

Referenced by checkCache(), and load().

364 {
365  if( aFileName.empty() )
366  {
367  #ifdef DEBUG
368  do {
369  std::ostringstream ostr;
370  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
371  ostr << " * [BUG] empty filename";
372  wxLogTrace( MASK_3D_CACHE, "%s\n", ostr.str().c_str() );
373  } while( 0 );
374  #endif
375 
376  return false;
377  }
378 
379  if( NULL == aSHA1Sum )
380  {
381  #ifdef DEBUG
382  do {
383  std::ostringstream ostr;
384  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
385  ostr << " * [BUG] NULL pointer passed for aMD5Sum";
386  wxLogTrace( MASK_3D_CACHE, "%s\n", ostr.str().c_str() );
387  } while( 0 );
388  #endif
389 
390  return false;
391  }
392 
393  #ifdef WIN32
394  FILE* fp = _wfopen( aFileName.wc_str(), L"rb" );
395  #else
396  FILE* fp = fopen( aFileName.ToUTF8(), "rb" );
397  #endif
398 
399  if( NULL == fp )
400  return false;
401 
402  boost::uuids::detail::sha1 dblock;
403  unsigned char block[4096];
404  size_t bsize = 0;
405 
406  while( ( bsize = fread( &block, 1, 4096, fp ) ) > 0 )
407  dblock.process_bytes( block, bsize );
408 
409  fclose( fp );
410  unsigned int digest[5];
411  dblock.get_digest( digest );
412 
413  // ensure MSB order
414  for( int i = 0; i < 5; ++i )
415  {
416  int idx = i << 2;
417  unsigned int tmp = digest[i];
418  aSHA1Sum[idx+3] = tmp & 0xff;
419  tmp >>= 8;
420  aSHA1Sum[idx+2] = tmp & 0xff;
421  tmp >>= 8;
422  aSHA1Sum[idx+1] = tmp & 0xff;
423  tmp >>= 8;
424  aSHA1Sum[idx] = tmp & 0xff;
425  }
426 
427  return true;
428 }
#define MASK_3D_CACHE
Definition: 3d_cache.cpp:51
Definition: solve.cpp:178
SCENEGRAPH * S3D_CACHE::load ( const wxString &  aModelFile,
S3D_CACHE_ENTRY **  aCachePtr = NULL 
)
private

Definition at line 203 of file 3d_cache.cpp.

References checkCache(), S3D::Destroy3DModel(), S3D::DestroyNode(), getSHA1(), isSHA1Same(), S3D_PLUGIN_MANAGER::Load3DModel(), lock3D_cache, m_CacheMap, m_FNResolver, m_Plugins, MASK_3D_CACHE, S3D_FILENAME_RESOLVER::ResolvePath(), and S3D_CACHE_ENTRY::sceneData.

Referenced by GetModel(), and Load().

204 {
205  if( aCachePtr )
206  *aCachePtr = NULL;
207 
208  wxString full3Dpath = m_FNResolver->ResolvePath( aModelFile );
209 
210  if( full3Dpath.empty() )
211  {
212  // the model cannot be found; we cannot proceed
213  wxLogTrace( MASK_3D_CACHE, " * [3D model] could not find model '%s'\n",
214  aModelFile.GetData() );
215  return NULL;
216  }
217 
218  // check cache if file is already loaded
219  wxCriticalSectionLocker lock( lock3D_cache );
220  std::map< wxString, S3D_CACHE_ENTRY*, S3D::rsort_wxString >::iterator mi;
221  mi = m_CacheMap.find( full3Dpath );
222 
223  if( mi != m_CacheMap.end() )
224  {
225  wxFileName fname( full3Dpath );
226 
227  if( fname.FileExists() ) // Only check if file exists. If not, it will
228  { // use the same model in cache.
229  bool reload = false;
230  wxDateTime fmdate = fname.GetModificationTime();
231 
232  if( fmdate != mi->second->modTime )
233  {
234  unsigned char hashSum[20];
235  getSHA1( full3Dpath, hashSum );
236  mi->second->modTime = fmdate;
237 
238  if( !isSHA1Same( hashSum, mi->second->sha1sum ) )
239  {
240  mi->second->SetSHA1( hashSum );
241  reload = true;
242  }
243  }
244 
245  if( reload )
246  {
247  if( NULL != mi->second->sceneData )
248  {
249  S3D::DestroyNode( mi->second->sceneData );
250  mi->second->sceneData = NULL;
251  }
252 
253  if( NULL != mi->second->renderData )
254  S3D::Destroy3DModel( &mi->second->renderData );
255 
256  mi->second->sceneData = m_Plugins->Load3DModel( full3Dpath, mi->second->pluginInfo );
257  }
258  }
259 
260  if( NULL != aCachePtr )
261  *aCachePtr = mi->second;
262 
263  return mi->second->sceneData;
264  }
265 
266  // a cache item does not exist; search the Filename->Cachename map
267  return checkCache( full3Dpath, aCachePtr );
268 }
#define MASK_3D_CACHE
Definition: 3d_cache.cpp:51
static bool isSHA1Same(const unsigned char *shaA, const unsigned char *shaB)
Definition: 3d_cache.cpp:55
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:543
SCENEGRAPH * Load3DModel(const wxString &aFileName, std::string &aPluginInfo)
std::map< wxString, S3D_CACHE_ENTRY *, S3D::rsort_wxString > m_CacheMap
mapping of file names to cache names and data
Definition: 3d_cache.h:57
bool getSHA1(const wxString &aFileName, unsigned char *aSHA1Sum)
Function getSHA1 calculates the SHA1 hash of the given file.
Definition: 3d_cache.cpp:363
SCENEGRAPH * checkCache(const wxString &aFileName, S3D_CACHE_ENTRY **aCachePtr=NULL)
Find or create cache entry for file name.
Definition: 3d_cache.cpp:277
SCENEGRAPH * sceneData
Definition: 3d_cache.cpp:127
wxString ResolvePath(const wxString &aFileName)
Function ResolvePath determines the full path of the given file name.
SGLIB_API void DestroyNode(SGNODE *aNode)
Function DestroyNode deletes the given SG* class node.
Definition: ifsg_api.cpp:214
static wxCriticalSection lock3D_cache
Definition: 3d_cache.cpp:53
S3D_FILENAME_RESOLVER * m_FNResolver
object to resolve file names
Definition: 3d_cache.h:60
S3D_PLUGIN_MANAGER * m_Plugins
plugin manager
Definition: 3d_cache.h:63
SCENEGRAPH * S3D_CACHE::Load ( const wxString &  aModelFile)

Function Load attempts 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.

Parameters
aModelFile[in] is the partial or full path to the model to be loaded
Returns
true if the model was successfully loaded, otherwise false. The model may fail to load if, for example, the plugin does not support rendering of the 3D model.

Definition at line 271 of file 3d_cache.cpp.

References load().

Referenced by export_vrml_module().

272 {
273  return load( aModelFile );
274 }
SCENEGRAPH * load(const wxString &aModelFile, S3D_CACHE_ENTRY **aCachePtr=NULL)
Definition: 3d_cache.cpp:203
bool S3D_CACHE::loadCacheData ( S3D_CACHE_ENTRY aCacheItem)
private

Definition at line 431 of file 3d_cache.cpp.

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().

432 {
433  wxString bname = aCacheItem->GetCacheBaseName();
434 
435  if( bname.empty() )
436  {
437  #ifdef DEBUG
438  wxLogTrace( MASK_3D_CACHE, " * [3D model] cannot load cached model; no file hash available\n" );
439  #endif
440 
441  return false;
442  }
443 
444  if( m_CacheDir.empty() )
445  {
446  wxString errmsg = "cannot load cached model; config directory unknown";
447  wxLogTrace( MASK_3D_CACHE, " * [3D model] %s\n", errmsg.GetData() );
448 
449  return false;
450  }
451 
452  wxString fname = m_CacheDir + bname + wxT( ".3dc" );
453 
454  if( !wxFileName::FileExists( fname ) )
455  {
456  wxString errmsg = "cannot open file";
457  wxLogTrace( MASK_3D_CACHE, " * [3D model] %s '%s'\n",
458  errmsg.GetData(), fname.GetData() );
459  return false;
460  }
461 
462  if( NULL != aCacheItem->sceneData )
463  S3D::DestroyNode( (SGNODE*) aCacheItem->sceneData );
464 
465  aCacheItem->sceneData = (SCENEGRAPH*)S3D::ReadCache( fname.ToUTF8(), m_Plugins, checkTag );
466 
467  if( NULL == aCacheItem->sceneData )
468  return false;
469 
470  return true;
471 }
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:328
#define MASK_3D_CACHE
Definition: 3d_cache.cpp:51
const wxString GetCacheBaseName(void)
Definition: 3d_cache.cpp:171
Class SGNODE represents the base class of all Scene Graph nodes.
Definition: sg_node.h:76
wxString m_CacheDir
3D cache directory
Definition: 3d_cache.h:69
static bool checkTag(const char *aTag, void *aPluginMgrPtr)
Definition: 3d_cache.cpp:64
SCENEGRAPH * sceneData
Definition: 3d_cache.cpp:127
SGLIB_API void DestroyNode(SGNODE *aNode)
Function DestroyNode deletes the given SG* class node.
Definition: ifsg_api.cpp:214
S3D_PLUGIN_MANAGER * m_Plugins
plugin manager
Definition: 3d_cache.h:63
bool S3D_CACHE::saveCacheData ( S3D_CACHE_ENTRY aCacheItem)
private

Definition at line 474 of file 3d_cache.cpp.

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

Referenced by checkCache().

475 {
476  if( NULL == aCacheItem )
477  {
478  #ifdef DEBUG
479  do {
480  std::ostringstream ostr;
481  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
482  ostr << " * NULL passed for aCacheItem";
483  wxLogTrace( MASK_3D_CACHE, "%s\n", ostr.str().c_str() );
484  } while( 0 );
485  #endif
486 
487  return false;
488  }
489 
490  if( NULL == aCacheItem->sceneData )
491  {
492  #ifdef DEBUG
493  do {
494  std::ostringstream ostr;
495  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
496  ostr << " * aCacheItem has no valid scene data";
497  wxLogTrace( MASK_3D_CACHE, "%s\n", ostr.str().c_str() );
498  } while( 0 );
499  #endif
500 
501  return false;
502  }
503 
504  wxString bname = aCacheItem->GetCacheBaseName();
505 
506  if( bname.empty() )
507  {
508  #ifdef DEBUG
509  wxLogTrace( MASK_3D_CACHE, " * [3D model] cannot load cached model; no file hash available\n" );
510  #endif
511 
512  return false;
513  }
514 
515  if( m_CacheDir.empty() )
516  {
517  wxString errmsg = "cannot load cached model; config directory unknown";
518  wxLogTrace( MASK_3D_CACHE, " * [3D model] %s\n", errmsg.GetData() );
519 
520  return false;
521  }
522 
523  wxString fname = m_CacheDir + bname + wxT( ".3dc" );
524 
525  if( wxFileName::Exists( fname ) )
526  {
527  if( !wxFileName::FileExists( fname ) )
528  {
529  wxString errmsg = _( "path exists but is not a regular file" );
530  wxLogTrace( MASK_3D_CACHE, " * [3D model] %s '%s'\n", errmsg.GetData(),
531  fname.ToUTF8() );
532 
533  return false;
534  }
535  }
536 
537  return S3D::WriteCache( fname.ToUTF8(), true, (SGNODE*)aCacheItem->sceneData,
538  aCacheItem->pluginInfo.c_str() );
539 }
std::string pluginInfo
Definition: 3d_cache.cpp:126
#define MASK_3D_CACHE
Definition: 3d_cache.cpp:51
const wxString GetCacheBaseName(void)
Definition: 3d_cache.cpp:171
Class SGNODE represents the base class of all Scene Graph nodes.
Definition: sg_node.h:76
wxString m_CacheDir
3D cache directory
Definition: 3d_cache.h:69
SCENEGRAPH * sceneData
Definition: 3d_cache.cpp:127
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:236
bool S3D_CACHE::Set3DConfigDir ( const wxString &  aConfigDir)

Function Set3DConfigDir 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 542 of file 3d_cache.cpp.

References ExpandEnvVarSubstitutions(), m_CacheDir, m_ConfigDir, m_FNResolver, MASK_3D_CACHE, and S3D_FILENAME_RESOLVER::Set3DConfigDir().

Referenced by Get3DConfigDir().

543 {
544  if( !m_ConfigDir.empty() )
545  return false;
546 
547  wxFileName cfgdir;
548 
549  if( aConfigDir.StartsWith( "${" ) || aConfigDir.StartsWith( "$(" ) )
550  cfgdir.Assign( ExpandEnvVarSubstitutions( aConfigDir ), "" );
551  else
552  cfgdir.Assign( aConfigDir, "" );
553 
554  cfgdir.Normalize();
555 
556  if( !cfgdir.DirExists() )
557  {
558  cfgdir.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL );
559 
560  if( !cfgdir.DirExists() )
561  {
562  std::ostringstream ostr;
563  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
564  wxString errmsg = _( "failed to create 3D configuration directory" );
565  ostr << " * " << errmsg.ToUTF8() << "\n";
566  errmsg = _( "config directory" );
567  ostr << " * " << errmsg.ToUTF8() << " '";
568  ostr << cfgdir.GetPath().ToUTF8() << "'";
569  wxLogTrace( MASK_3D_CACHE, "%s\n", ostr.str().c_str() );
570 
571  return false;
572  }
573  }
574 
575  m_ConfigDir = cfgdir.GetPath();
576 
577  // inform the file resolver of the config directory
579  {
580  #ifdef DEBUG
581  do {
582  std::ostringstream ostr;
583  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
584  ostr << " * could not set 3D Config Directory on filename resolver\n";
585  ostr << " * config directory: '" << m_ConfigDir.ToUTF8() << "'";
586  wxLogTrace( MASK_3D_CACHE, "%s\n", ostr.str().c_str() );
587  } while( 0 );
588  #endif
589  }
590 
591  // 3D cache data must go to a user's cache directory;
592  // unfortunately wxWidgets doesn't seem to provide
593  // functions to retrieve such a directory.
594  //
595  // 1. OSX: ~/Library/Caches/kicad/3d/
596  // 2. Linux: ${XDG_CACHE_HOME}/kicad/3d ~/.cache/kicad/3d/
597  // 3. MSWin: AppData\Local\kicad\3d
598  wxString cacheDir;
599 
600  #if defined(_WIN32)
601  wxStandardPaths::Get().UseAppInfo( wxStandardPaths::AppInfo_None );
602  cacheDir = wxStandardPaths::Get().GetUserLocalDataDir();
603  cacheDir.append( "\\kicad\\3d" );
604  #elif defined(__APPLE)
605  cacheDir = "${HOME}/Library/Caches/kicad/3d";
606  #else // assume Linux
607  cacheDir = ExpandEnvVarSubstitutions( "${XDG_CACHE_HOME}" );
608 
609  if( cacheDir.empty() || cacheDir == "${XDG_CACHE_HOME}" )
610  cacheDir = "${HOME}/.cache";
611 
612  cacheDir.append( "/kicad/3d" );
613  #endif
614 
615  cacheDir = ExpandEnvVarSubstitutions( cacheDir );
616  cfgdir.Assign( cacheDir, "" );
617 
618  if( !cfgdir.DirExists() )
619  {
620  cfgdir.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL );
621 
622  if( !cfgdir.DirExists() )
623  {
624  std::ostringstream ostr;
625  ostr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
626  wxString errmsg = "failed to create 3D cache directory";
627  ostr << " * " << errmsg.ToUTF8() << "\n";
628  errmsg = "cache directory";
629  ostr << " * " << errmsg.ToUTF8() << " '";
630  ostr << cfgdir.GetPath().ToUTF8() << "'";
631  wxLogTrace( MASK_3D_CACHE, "%s\n", ostr.str().c_str() );
632 
633  return false;
634  }
635  }
636 
637  m_CacheDir = cfgdir.GetPathWithSep();
638  return true;
639 }
#define MASK_3D_CACHE
Definition: 3d_cache.cpp:51
const wxString ExpandEnvVarSubstitutions(const wxString &aString)
Function ExpandEnvVarSubstitutions replaces any environment variable references with their values...
Definition: common.cpp:254
wxString m_CacheDir
3D cache directory
Definition: 3d_cache.h:69
wxString m_ConfigDir
base configuration path for 3D items
Definition: 3d_cache.h:72
S3D_FILENAME_RESOLVER * m_FNResolver
object to resolve file names
Definition: 3d_cache.h:60
bool Set3DConfigDir(const wxString &aConfigDir)
Function Set3DConfigDir sets the user's configuration directory for 3D models.
void S3D_CACHE::SetProgramBase ( PGM_BASE aBase)

Function SetProgramBase sets the filename resolver's pointer to the application's PGM_BASE instance; the pointer is used to extract the local env vars.

Definition at line 726 of file 3d_cache.cpp.

References m_FNResolver, and S3D_FILENAME_RESOLVER::SetProgramBase().

727 {
728  m_FNResolver->SetProgramBase( aBase );
729  return;
730 }
void SetProgramBase(PGM_BASE *aBase)
Function SetProgramBase sets a pointer to the application's PGM_BASE instance; the pointer is used to...
S3D_FILENAME_RESOLVER * m_FNResolver
object to resolve file names
Definition: 3d_cache.h:60
bool S3D_CACHE::SetProjectDir ( const wxString &  aProjDir)

Function SetProjectDir sets the current project's working directory; this affects the model search path.

Definition at line 700 of file 3d_cache.cpp.

References m_CacheList, m_CacheMap, m_FNResolver, and S3D_FILENAME_RESOLVER::SetProjectDir().

701 {
702  bool hasChanged = false;
703 
704  if( m_FNResolver->SetProjectDir( aProjDir, &hasChanged ) && hasChanged )
705  {
706  m_CacheMap.clear();
707 
708  std::list< S3D_CACHE_ENTRY* >::iterator sL = m_CacheList.begin();
709  std::list< S3D_CACHE_ENTRY* >::iterator eL = m_CacheList.end();
710 
711  while( sL != eL )
712  {
713  delete *sL;
714  ++sL;
715  }
716 
717  m_CacheList.clear();
718 
719  return true;
720  }
721 
722  return false;
723 }
std::map< wxString, S3D_CACHE_ENTRY *, S3D::rsort_wxString > m_CacheMap
mapping of file names to cache names and data
Definition: 3d_cache.h:57
bool SetProjectDir(const wxString &aProjDir, bool *flgChanged=NULL)
Function SetProjectDir sets the current KiCad project directory as the first entry in the model path ...
std::list< S3D_CACHE_ENTRY * > m_CacheList
cache entries
Definition: 3d_cache.h:54
S3D_FILENAME_RESOLVER * m_FNResolver
object to resolve file names
Definition: 3d_cache.h:60

Member Data Documentation

wxString S3D_CACHE::m_CacheDir
private

3D cache directory

Definition at line 69 of file 3d_cache.h.

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

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

cache entries

Definition at line 54 of file 3d_cache.h.

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

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

mapping of file names to cache names and data

Definition at line 57 of file 3d_cache.h.

Referenced by checkCache(), FlushCache(), GetModelHash(), load(), and SetProjectDir().

wxString S3D_CACHE::m_ConfigDir
private

base configuration path for 3D items

Definition at line 72 of file 3d_cache.h.

Referenced by Get3DConfigDir(), and Set3DConfigDir().

bool S3D_CACHE::m_DirtyCache
private

set true if the cache needs to be updated

Definition at line 66 of file 3d_cache.h.

Referenced by S3D_CACHE().

S3D_FILENAME_RESOLVER* S3D_CACHE::m_FNResolver
private

object to resolve file names

Definition at line 60 of file 3d_cache.h.

Referenced by GetModelHash(), GetProjectDir(), GetResolver(), load(), S3D_CACHE(), Set3DConfigDir(), SetProgramBase(), SetProjectDir(), and ~S3D_CACHE().

S3D_PLUGIN_MANAGER* S3D_CACHE::m_Plugins
private

plugin manager

Definition at line 63 of file 3d_cache.h.

Referenced by checkCache(), ClosePlugins(), GetFileFilters(), load(), loadCacheData(), S3D_CACHE(), and ~S3D_CACHE().

wxString S3D_CACHE::m_ProjDir
private

current KiCad project dir

Definition at line 75 of file 3d_cache.h.


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