KiCad PCB EDA Suite
3d_cache.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2015-2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
5  * Copyright (C) 2018 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
25 #define GLM_FORCE_RADIANS
26 
27 #include <iostream>
28 #include <sstream>
29 #include <fstream>
30 #include <utility>
31 #include <iterator>
32 
33 #include <wx/datetime.h>
34 #include <wx/filename.h>
35 #include <wx/log.h>
36 #include <wx/stdpaths.h>
37 
38 #include <boost/version.hpp>
39 
40 #if BOOST_VERSION >= 106800
41 #include <boost/uuid/detail/sha1.hpp>
42 #else
43 #include <boost/uuid/sha1.hpp>
44 #endif
45 
46 #include <glm/glm.hpp>
47 #include <glm/ext.hpp>
48 
49 #include "common.h"
50 #include "3d_cache.h"
51 #include "3d_info.h"
52 #include "sg/scenegraph.h"
53 #include "filename_resolver.h"
54 #include "3d_plugin_manager.h"
55 #include "plugins/3dapi/ifsg_api.h"
56 
57 
58 #define MASK_3D_CACHE "3D_CACHE"
59 
60 static wxCriticalSection lock3D_cache;
61 
62 
63 static bool isSHA1Same( const unsigned char* shaA, const unsigned char* shaB )
64 {
65  for( int i = 0; i < 20; ++i )
66  if( shaA[i] != shaB[i] )
67  return false;
68 
69  return true;
70 }
71 
72 
73 static bool checkTag( const char* aTag, void* aPluginMgrPtr )
74 {
75  if( NULL == aTag || NULL == aPluginMgrPtr )
76  return false;
77 
78  S3D_PLUGIN_MANAGER *pp = (S3D_PLUGIN_MANAGER*) aPluginMgrPtr;
79 
80  return pp->CheckTag( aTag );
81 }
82 
83 
84 static const wxString sha1ToWXString( const unsigned char* aSHA1Sum )
85 {
86  unsigned char uc;
87  unsigned char tmp;
88  char sha1[41];
89  int j = 0;
90 
91  for( int i = 0; i < 20; ++i )
92  {
93  uc = aSHA1Sum[i];
94  tmp = uc / 16;
95 
96  if( tmp > 9 )
97  tmp += 87;
98  else
99  tmp += 48;
100 
101  sha1[j++] = tmp;
102  tmp = uc % 16;
103 
104  if( tmp > 9 )
105  tmp += 87;
106  else
107  tmp += 48;
108 
109  sha1[j++] = tmp;
110  }
111 
112  sha1[j] = 0;
113 
114  return wxString::FromUTF8Unchecked( sha1 );
115 }
116 
117 
119 {
120 private:
121  // prohibit assignment and default copy constructor
122  S3D_CACHE_ENTRY( const S3D_CACHE_ENTRY& source );
123  S3D_CACHE_ENTRY& operator=( const S3D_CACHE_ENTRY& source );
124 
125  wxString m_CacheBaseName; // base name of cache file (a SHA1 digest)
126 
127 public:
128  S3D_CACHE_ENTRY();
130 
131  void SetSHA1( const unsigned char* aSHA1Sum );
132  const wxString GetCacheBaseName( void );
133 
134  wxDateTime modTime; // file modification time
135  unsigned char sha1sum[20];
136  std::string pluginInfo; // PluginName:Version string
139 };
140 
141 
143 {
144  sceneData = NULL;
145  renderData = NULL;
146  memset( sha1sum, 0, 20 );
147 }
148 
149 
151 {
152  if( NULL != sceneData )
153  delete sceneData;
154 
155  if( NULL != renderData )
157 }
158 
159 
160 void S3D_CACHE_ENTRY::SetSHA1( const unsigned char* aSHA1Sum )
161 {
162  if( NULL == aSHA1Sum )
163  {
164  wxLogTrace( MASK_3D_CACHE, "%s:%s:%d\n * [BUG] NULL passed for aSHA1Sum",
165  __FILE__, __FUNCTION__, __LINE__ );
166 
167  return;
168  }
169 
170  memcpy( sha1sum, aSHA1Sum, 20 );
171  return;
172 }
173 
174 
175 const wxString S3D_CACHE_ENTRY::GetCacheBaseName( void )
176 {
177  if( m_CacheBaseName.empty() )
179 
180  return m_CacheBaseName;
181 }
182 
183 
185 {
186  m_DirtyCache = false;
189 
190  return;
191 }
192 
193 
195 {
196  FlushCache();
197 
198  if( m_FNResolver )
199  delete m_FNResolver;
200 
201  if( m_Plugins )
202  delete m_Plugins;
203 
204  return;
205 }
206 
207 
208 SCENEGRAPH* S3D_CACHE::load( const wxString& aModelFile, S3D_CACHE_ENTRY** aCachePtr )
209 {
210  if( aCachePtr )
211  *aCachePtr = NULL;
212 
213  wxString full3Dpath = m_FNResolver->ResolvePath( aModelFile );
214 
215  if( full3Dpath.empty() )
216  {
217  // the model cannot be found; we cannot proceed
218  wxLogTrace( MASK_3D_CACHE, "%s:%s:%d\n * [3D model] could not find model '%s'\n",
219  __FILE__, __FUNCTION__, __LINE__, aModelFile );
220  return NULL;
221  }
222 
223  // check cache if file is already loaded
224  wxCriticalSectionLocker lock( lock3D_cache );
225  std::map< wxString, S3D_CACHE_ENTRY*, rsort_wxString >::iterator mi;
226  mi = m_CacheMap.find( full3Dpath );
227 
228  if( mi != m_CacheMap.end() )
229  {
230  wxFileName fname( full3Dpath );
231 
232  if( fname.FileExists() ) // Only check if file exists. If not, it will
233  { // use the same model in cache.
234  bool reload = false;
235  wxDateTime fmdate = fname.GetModificationTime();
236 
237  if( fmdate != mi->second->modTime )
238  {
239  unsigned char hashSum[20];
240  getSHA1( full3Dpath, hashSum );
241  mi->second->modTime = fmdate;
242 
243  if( !isSHA1Same( hashSum, mi->second->sha1sum ) )
244  {
245  mi->second->SetSHA1( hashSum );
246  reload = true;
247  }
248  }
249 
250  if( reload )
251  {
252  if( NULL != mi->second->sceneData )
253  {
254  S3D::DestroyNode( mi->second->sceneData );
255  mi->second->sceneData = NULL;
256  }
257 
258  if( NULL != mi->second->renderData )
259  S3D::Destroy3DModel( &mi->second->renderData );
260 
261  mi->second->sceneData = m_Plugins->Load3DModel( full3Dpath, mi->second->pluginInfo );
262  }
263  }
264 
265  if( NULL != aCachePtr )
266  *aCachePtr = mi->second;
267 
268  return mi->second->sceneData;
269  }
270 
271  // a cache item does not exist; search the Filename->Cachename map
272  return checkCache( full3Dpath, aCachePtr );
273 }
274 
275 
276 SCENEGRAPH* S3D_CACHE::Load( const wxString& aModelFile )
277 {
278  return load( aModelFile );
279 }
280 
281 
282 SCENEGRAPH* S3D_CACHE::checkCache( const wxString& aFileName, S3D_CACHE_ENTRY** aCachePtr )
283 {
284  if( aCachePtr )
285  *aCachePtr = NULL;
286 
287  unsigned char sha1sum[20];
288 
289  if( !getSHA1( aFileName, sha1sum ) || m_CacheDir.empty() )
290  {
291  // just in case we can't get a hash digest (for example, on access issues)
292  // or we do not have a configured cache file directory, we create an
293  // entry to prevent further attempts at loading the file
295  m_CacheList.push_back( ep );
296  wxFileName fname( aFileName );
297  ep->modTime = fname.GetModificationTime();
298 
299  if( m_CacheMap.insert( std::pair< wxString, S3D_CACHE_ENTRY* >
300  ( aFileName, ep ) ).second == false )
301  {
302  wxLogTrace( MASK_3D_CACHE, "%s:%s:%d\n * [BUG] duplicate entry in map file; key = '%s'",
303  __FILE__, __FUNCTION__, __LINE__, aFileName );
304 
305  m_CacheList.pop_back();
306  delete ep;
307  }
308  else
309  {
310  if( aCachePtr )
311  *aCachePtr = ep;
312 
313  }
314 
315  return NULL;
316  }
317 
319  m_CacheList.push_back( ep );
320  wxFileName fname( aFileName );
321  ep->modTime = fname.GetModificationTime();
322 
323  if( m_CacheMap.insert( std::pair< wxString, S3D_CACHE_ENTRY* >
324  ( aFileName, ep ) ).second == false )
325  {
326  wxLogTrace( MASK_3D_CACHE, "%s:%s:%d\n * [BUG] duplicate entry in map file; key = '%s'",
327  __FILE__, __FUNCTION__, __LINE__, aFileName );
328 
329  m_CacheList.pop_back();
330  delete ep;
331  return NULL;
332  }
333 
334  if( aCachePtr )
335  *aCachePtr = ep;
336 
337  ep->SetSHA1( sha1sum );
338 
339  wxString bname = ep->GetCacheBaseName();
340  wxString cachename = m_CacheDir + bname + wxT( ".3dc" );
341 
342  if( wxFileName::FileExists( cachename ) && loadCacheData( ep ) )
343  return ep->sceneData;
344 
345  ep->sceneData = m_Plugins->Load3DModel( aFileName, ep->pluginInfo );
346 
347  if( NULL != ep->sceneData )
348  saveCacheData( ep );
349 
350  return ep->sceneData;
351 }
352 
353 
354 bool S3D_CACHE::getSHA1( const wxString& aFileName, unsigned char* aSHA1Sum )
355 {
356  if( aFileName.empty() )
357  {
358  wxLogTrace( MASK_3D_CACHE, "%s:%s:%d\n * [BUG] empty filename",
359  __FILE__, __FUNCTION__, __LINE__ );
360 
361  return false;
362  }
363 
364  if( NULL == aSHA1Sum )
365  {
366  wxLogTrace( MASK_3D_CACHE, "%s\n * [BUG] NULL pointer passed for aMD5Sum",
367  __FILE__, __FUNCTION__, __LINE__ );
368 
369  return false;
370  }
371 
372  #ifdef _WIN32
373  FILE* fp = _wfopen( aFileName.wc_str(), L"rb" );
374  #else
375  FILE* fp = fopen( aFileName.ToUTF8(), "rb" );
376  #endif
377 
378  if( NULL == fp )
379  return false;
380 
381  boost::uuids::detail::sha1 dblock;
382  unsigned char block[4096];
383  size_t bsize = 0;
384 
385  while( ( bsize = fread( &block, 1, 4096, fp ) ) > 0 )
386  dblock.process_bytes( block, bsize );
387 
388  fclose( fp );
389  unsigned int digest[5];
390  dblock.get_digest( digest );
391 
392  // ensure MSB order
393  for( int i = 0; i < 5; ++i )
394  {
395  int idx = i << 2;
396  unsigned int tmp = digest[i];
397  aSHA1Sum[idx+3] = tmp & 0xff;
398  tmp >>= 8;
399  aSHA1Sum[idx+2] = tmp & 0xff;
400  tmp >>= 8;
401  aSHA1Sum[idx+1] = tmp & 0xff;
402  tmp >>= 8;
403  aSHA1Sum[idx] = tmp & 0xff;
404  }
405 
406  return true;
407 }
408 
409 
411 {
412  wxString bname = aCacheItem->GetCacheBaseName();
413 
414  if( bname.empty() )
415  {
416  wxLogTrace( MASK_3D_CACHE,
417  " * [3D model] cannot load cached model; no file hash available" );
418 
419  return false;
420  }
421 
422  if( m_CacheDir.empty() )
423  {
424  wxLogTrace( MASK_3D_CACHE,
425  " * [3D model] cannot load cached model; config directory unknown" );
426 
427  return false;
428  }
429 
430  wxString fname = m_CacheDir + bname + wxT( ".3dc" );
431 
432  if( !wxFileName::FileExists( fname ) )
433  {
434  wxString errmsg = "cannot open file";
435  wxLogTrace( MASK_3D_CACHE, " * [3D model] %s '%s'", errmsg.GetData(), fname.GetData() );
436  return false;
437  }
438 
439  if( NULL != aCacheItem->sceneData )
440  S3D::DestroyNode( (SGNODE*) aCacheItem->sceneData );
441 
442  aCacheItem->sceneData = (SCENEGRAPH*)S3D::ReadCache( fname.ToUTF8(), m_Plugins, checkTag );
443 
444  if( NULL == aCacheItem->sceneData )
445  return false;
446 
447  return true;
448 }
449 
450 
452 {
453  if( NULL == aCacheItem )
454  {
455  wxLogTrace( MASK_3D_CACHE, "%s:%s:%d\n * NULL passed for aCacheItem",
456  __FILE__, __FUNCTION__, __LINE__ );
457 
458  return false;
459  }
460 
461  if( NULL == aCacheItem->sceneData )
462  {
463  wxLogTrace( MASK_3D_CACHE, "%s:%s:%d\n * aCacheItem has no valid scene data",
464  __FILE__, __FUNCTION__, __LINE__ );
465 
466  return false;
467  }
468 
469  wxString bname = aCacheItem->GetCacheBaseName();
470 
471  if( bname.empty() )
472  {
473  wxLogTrace( MASK_3D_CACHE,
474  " * [3D model] cannot load cached model; no file hash available" );
475 
476  return false;
477  }
478 
479  if( m_CacheDir.empty() )
480  {
481  wxLogTrace( MASK_3D_CACHE,
482  " * [3D model] cannot load cached model; config directory unknown" );
483 
484  return false;
485  }
486 
487  wxString fname = m_CacheDir + bname + wxT( ".3dc" );
488 
489  if( wxFileName::Exists( fname ) )
490  {
491  if( !wxFileName::FileExists( fname ) )
492  {
493  wxLogTrace( MASK_3D_CACHE, " * [3D model] path exists but is not a regular file '%s'",
494  fname );
495 
496  return false;
497  }
498  }
499 
500  return S3D::WriteCache( fname.ToUTF8(), true, (SGNODE*)aCacheItem->sceneData,
501  aCacheItem->pluginInfo.c_str() );
502 }
503 
504 
505 bool S3D_CACHE::Set3DConfigDir( const wxString& aConfigDir )
506 {
507  if( !m_ConfigDir.empty() )
508  return false;
509 
510  wxFileName cfgdir;
511 
512  if( aConfigDir.StartsWith( "${" ) || aConfigDir.StartsWith( "$(" ) )
513  cfgdir.Assign( ExpandEnvVarSubstitutions( aConfigDir ), "" );
514  else
515  cfgdir.Assign( aConfigDir, "" );
516 
517  cfgdir.Normalize();
518 
519  if( !cfgdir.DirExists() )
520  {
521  cfgdir.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL );
522 
523  if( !cfgdir.DirExists() )
524  {
525  wxLogTrace( MASK_3D_CACHE,
526  "%s:%s:%d\n * failed to create 3D configuration directory '%s'",
527  __FILE__, __FUNCTION__, __LINE__, cfgdir.GetPath() );
528 
529  return false;
530  }
531  }
532 
533  m_ConfigDir = cfgdir.GetPath();
534 
535  // inform the file resolver of the config directory
537  {
538  wxLogTrace( MASK_3D_CACHE,
539  "%s:%s:%d\n * could not set 3D Config Directory on filename resolver\n"
540  " * config directory: '%s'",
541  __FILE__, __FUNCTION__, __LINE__, m_ConfigDir );
542  }
543 
544  // 3D cache data must go to a user's cache directory;
545  // unfortunately wxWidgets doesn't seem to provide
546  // functions to retrieve such a directory.
547  //
548  // 1. OSX: ~/Library/Caches/kicad/3d/
549  // 2. Linux: ${XDG_CACHE_HOME}/kicad/3d ~/.cache/kicad/3d/
550  // 3. MSWin: AppData\Local\kicad\3d
551  wxString cacheDir;
552 
553 #if defined(_WIN32)
554  wxStandardPaths::Get().UseAppInfo( wxStandardPaths::AppInfo_None );
555  cacheDir = wxStandardPaths::Get().GetUserLocalDataDir();
556  cacheDir.append( "\\kicad\\3d" );
557 #elif defined(__APPLE)
558  cacheDir = "${HOME}/Library/Caches/kicad/3d";
559 #else // assume Linux
560  cacheDir = ExpandEnvVarSubstitutions( "${XDG_CACHE_HOME}" );
561 
562  if( cacheDir.empty() || cacheDir == "${XDG_CACHE_HOME}" )
563  cacheDir = "${HOME}/.cache";
564 
565  cacheDir.append( "/kicad/3d" );
566 #endif
567 
568  cacheDir = ExpandEnvVarSubstitutions( cacheDir );
569  cfgdir.Assign( cacheDir, "" );
570 
571  if( !cfgdir.DirExists() )
572  {
573  cfgdir.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL );
574 
575  if( !cfgdir.DirExists() )
576  {
577  wxLogTrace( MASK_3D_CACHE, "%s:%s:%d\n * failed to create 3D cache directory '%s'",
578  __FILE__, __FUNCTION__, __LINE__, cfgdir.GetPath() );
579 
580  return false;
581  }
582  }
583 
584  m_CacheDir = cfgdir.GetPathWithSep();
585  return true;
586 }
587 
588 
589 wxString S3D_CACHE::Get3DConfigDir( bool createDefault )
590 {
591  if( !m_ConfigDir.empty() || !createDefault )
592  return m_ConfigDir;
593 
594  // note: duplicated from common/common.cpp GetKicadConfigPath() to avoid
595  // code coupling; ideally the instantiating code should call
596  // Set3DConfigDir() to set the directory rather than relying on this
597  // directory remaining the same in future KiCad releases.
598  wxFileName cfgpath;
599 
600  // From the wxWidgets wxStandardPaths::GetUserConfigDir() help:
601  // Unix: ~ (the home directory)
602  // Windows: "C:\Documents and Settings\username\Application Data"
603  // Mac: ~/Library/Preferences
604  cfgpath.AssignDir( wxStandardPaths::Get().GetUserConfigDir() );
605 
606 #if !defined( __WINDOWS__ ) && !defined( __WXMAC__ )
607  wxString envstr = ExpandEnvVarSubstitutions( "${XDG_CONFIG_HOME}" );
608 
609  if( envstr.IsEmpty() || envstr == "${XDG_CONFIG_HOME}" )
610  {
611  // XDG_CONFIG_HOME is not set, so use the fallback
612  cfgpath.AppendDir( wxT( ".config" ) );
613  }
614  else
615  {
616  // Override the assignment above with XDG_CONFIG_HOME
617  cfgpath.AssignDir( envstr );
618  }
619 #endif
620 
621  cfgpath.AppendDir( wxT( "kicad" ) );
622  cfgpath.AppendDir( wxT( "3d" ) );
623 
624  if( !cfgpath.DirExists() )
625  {
626  cfgpath.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL );
627  }
628 
629  if( !cfgpath.DirExists() )
630  {
631  wxLogTrace( MASK_3D_CACHE, "%s:%s:%d\n * failed to create 3D configuration directory '%s'",
632  __FILE__, __FUNCTION__, __LINE__, cfgpath.GetPath() );
633 
634  return wxT( "" );
635  }
636 
637  if( Set3DConfigDir( cfgpath.GetPath() ) )
638  return m_ConfigDir;
639 
640  return wxEmptyString;
641 }
642 
643 
644 bool S3D_CACHE::SetProjectDir( const wxString& aProjDir )
645 {
646  bool hasChanged = false;
647 
648  if( m_FNResolver->SetProjectDir( aProjDir, &hasChanged ) && hasChanged )
649  {
650  m_CacheMap.clear();
651 
652  std::list< S3D_CACHE_ENTRY* >::iterator sL = m_CacheList.begin();
653  std::list< S3D_CACHE_ENTRY* >::iterator eL = m_CacheList.end();
654 
655  while( sL != eL )
656  {
657  delete *sL;
658  ++sL;
659  }
660 
661  m_CacheList.clear();
662 
663  return true;
664  }
665 
666  return false;
667 }
668 
669 
671 {
672  m_FNResolver->SetProgramBase( aBase );
673  return;
674 }
675 
676 
677 wxString S3D_CACHE::GetProjectDir( void )
678 {
679  return m_FNResolver->GetProjectDir();
680 }
681 
682 
684 {
685  return m_FNResolver;
686 }
687 
688 
689 std::list< wxString > const* S3D_CACHE::GetFileFilters( void ) const
690 {
691  return m_Plugins->GetFileFilters();
692 }
693 
694 
695 void S3D_CACHE::FlushCache( bool closePlugins )
696 {
697  std::list< S3D_CACHE_ENTRY* >::iterator sCL = m_CacheList.begin();
698  std::list< S3D_CACHE_ENTRY* >::iterator eCL = m_CacheList.end();
699 
700  while( sCL != eCL )
701  {
702  delete *sCL;
703  ++sCL;
704  }
705 
706  m_CacheList.clear();
707  m_CacheMap.clear();
708 
709  if( closePlugins )
710  ClosePlugins();
711 
712  return;
713 }
714 
715 
717 {
718  if( NULL != m_Plugins )
720 
721  return;
722 }
723 
724 
725 S3DMODEL* S3D_CACHE::GetModel( const wxString& aModelFileName )
726 {
727  S3D_CACHE_ENTRY* cp = NULL;
728  SCENEGRAPH* sp = load( aModelFileName, &cp );
729 
730  if( !sp )
731  return NULL;
732 
733  if( !cp )
734  {
735  wxLogTrace( MASK_3D_CACHE,
736  "%s:%s:%d\n * [BUG] model loaded with no associated S3D_CACHE_ENTRY",
737  __FILE__, __FUNCTION__, __LINE__ );
738 
739  return NULL;
740  }
741 
742  if( cp->renderData )
743  return cp->renderData;
744 
745  S3DMODEL* mp = S3D::GetModel( sp );
746  cp->renderData = mp;
747 
748  return mp;
749 }
750 
751 
752 wxString S3D_CACHE::GetModelHash( const wxString& aModelFileName )
753 {
754  wxString full3Dpath = m_FNResolver->ResolvePath( aModelFileName );
755 
756  if( full3Dpath.empty() || !wxFileName::FileExists( full3Dpath ) )
757  return wxEmptyString;
758 
759  // check cache if file is already loaded
760  std::map< wxString, S3D_CACHE_ENTRY*, rsort_wxString >::iterator mi;
761  mi = m_CacheMap.find( full3Dpath );
762 
763  if( mi != m_CacheMap.end() )
764  return mi->second->GetCacheBaseName();
765 
766  // a cache item does not exist; search the Filename->Cachename map
767  S3D_CACHE_ENTRY* cp = NULL;
768  checkCache( full3Dpath, &cp );
769 
770  if( NULL != cp )
771  return cp->GetCacheBaseName();
772 
773  return wxEmptyString;
774 }
static const wxString sha1ToWXString(const unsigned char *aSHA1Sum)
Definition: 3d_cache.cpp:84
wxString m_CacheBaseName
Definition: 3d_cache.cpp:125
std::string pluginInfo
Definition: 3d_cache.cpp:136
S3D_CACHE_ENTRY()
Definition: 3d_cache.cpp:142
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:321
Class PGM_BASE keeps program (whole process) data for KiCad programs.
Definition: pgm_base.h:151
#define MASK_3D_CACHE
Definition: 3d_cache.cpp:58
const wxString GetCacheBaseName(void)
Definition: 3d_cache.cpp:175
wxString Get3DConfigDir(bool createDefault=false)
Function Get3DConfigDir returns the current 3D configuration directory on success,...
Definition: 3d_cache.cpp:589
void SetProgramBase(PGM_BASE *aBase)
Function SetProgramBase sets the filename resolver's pointer to the application's PGM_BASE instance; ...
Definition: 3d_cache.cpp:670
static bool isSHA1Same(const unsigned char *shaA, const unsigned char *shaB)
Definition: 3d_cache.cpp:63
provides an extensible class to resolve 3D model paths.
bool SetProjectDir(const wxString &aProjDir, bool *flgChanged=NULL)
Function SetProjectDir sets the current KiCad project directory as the first entry in the model path ...
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:536
std::map< wxString, S3D_CACHE_ENTRY *, rsort_wxString > m_CacheMap
mapping of file names to cache names and data
Definition: 3d_cache.h:56
bool loadCacheData(S3D_CACHE_ENTRY *aCacheItem)
Definition: 3d_cache.cpp:410
Class SGNODE represents the base class of all Scene Graph nodes.
Definition: sg_node.h:76
SCENEGRAPH * Load3DModel(const wxString &aFileName, std::string &aPluginInfo)
defines the basic data associated with a single 3D model.
wxString GetModelHash(const wxString &aModelFileName)
Definition: 3d_cache.cpp:752
defines the basic data set required to represent a 3D model; this model must remain compatible with V...
S3D_CACHE_ENTRY & operator=(const S3D_CACHE_ENTRY &source)
FILENAME_RESOLVER * m_FNResolver
object to resolve file names
Definition: 3d_cache.h:59
std::list< wxString > const * GetFileFilters(void) const
Function GetFileFilters returns the list of file filters; this will contain at least the default "All...
S3DMODEL * GetModel(const wxString &aModelFileName)
Function GetModel attempts to load the scene data for a model and to translate it into an S3D_MODEL s...
Definition: 3d_cache.cpp:725
bool saveCacheData(S3D_CACHE_ENTRY *aCacheItem)
Definition: 3d_cache.cpp:451
void FlushCache(bool closePlugins=true)
Function FlushCache frees all data in the cache and by default closes all plugins.
Definition: 3d_cache.cpp:695
wxDateTime modTime
Definition: 3d_cache.cpp:134
bool SetProjectDir(const wxString &aProjDir)
Function SetProjectDir sets the current project's working directory; this affects the model search pa...
Definition: 3d_cache.cpp:644
const wxString ExpandEnvVarSubstitutions(const wxString &aString)
Replace any environment variable references with their values.
Definition: common.cpp:458
wxString m_CacheDir
3D cache directory
Definition: 3d_cache.h:68
void SetSHA1(const unsigned char *aSHA1Sum)
Definition: 3d_cache.cpp:160
static bool checkTag(const char *aTag, void *aPluginMgrPtr)
Definition: 3d_cache.cpp:73
~S3D_CACHE_ENTRY()
Definition: 3d_cache.cpp:150
wxString GetProjectDir(void)
bool getSHA1(const wxString &aFileName, unsigned char *aSHA1Sum)
Function getSHA1 calculates the SHA1 hash of the given file.
Definition: 3d_cache.cpp:354
SCENEGRAPH * checkCache(const wxString &aFileName, S3D_CACHE_ENTRY **aCachePtr=NULL)
Find or create cache entry for file name.
Definition: 3d_cache.cpp:282
bool m_DirtyCache
set true if the cache needs to be updated
Definition: 3d_cache.h:65
virtual ~S3D_CACHE()
Definition: 3d_cache.cpp:194
SCENEGRAPH * sceneData
Definition: 3d_cache.cpp:137
defines the API calls for the manipulation of SG* classes
Definition: solve.cpp:178
bool CheckTag(const char *aTag)
Function CheckTag checks the given tag and returns true if the plugin named in the tag is not loaded ...
SCENEGRAPH * load(const wxString &aModelFile, S3D_CACHE_ENTRY **aCachePtr=NULL)
Definition: 3d_cache.cpp:208
wxString ResolvePath(const wxString &aFileName)
Function ResolvePath determines the full path of the given file name.
S3DMODEL * renderData
Definition: 3d_cache.cpp:138
std::list< S3D_CACHE_ENTRY * > m_CacheList
cache entries
Definition: 3d_cache.h:53
manages 3D model plugins
bool Set3DConfigDir(const wxString &aConfigDir)
Function Set3DConfigDir Sets the configuration directory to be used by the model manager for storing ...
Definition: 3d_cache.cpp:505
wxString m_ConfigDir
base configuration path for 3D items
Definition: 3d_cache.h:71
size_t i
Definition: json11.cpp:597
SGLIB_API void DestroyNode(SGNODE *aNode)
Function DestroyNode deletes the given SG* class node.
Definition: ifsg_api.cpp:210
defines the display data cache manager for 3D models
The common library.
void ClosePlugins(void)
Function ClosePlugins iterates through all discovered plugins and closes them to reclaim memory.
bool Set3DConfigDir(const wxString &aConfigDir)
Function Set3DConfigDir sets the user's configuration directory for 3D models.
static wxCriticalSection lock3D_cache
Definition: 3d_cache.cpp:60
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:232
wxString GetProjectDir(void)
Function GetProjectDir returns the current project's working directory.
Definition: 3d_cache.cpp:677
FILENAME_RESOLVER * GetResolver(void)
Definition: 3d_cache.cpp:683
unsigned char sha1sum[20]
Definition: 3d_cache.cpp:135
void ClosePlugins(void)
Function ClosePlugins unloads plugins to free memory.
Definition: 3d_cache.cpp:716
Store the a model based on meshes and materials.
Definition: c3dmodel.h:90
void SetProgramBase(PGM_BASE *aBase)
Function SetProgramBase sets a pointer to the application's PGM_BASE instance; the pointer is used to...
SCENEGRAPH * Load(const wxString &aModelFile)
Function Load attempts to load the scene data for a model; it will consult the internal cache list an...
Definition: 3d_cache.cpp:276
Definition: 3d_cache.cpp:118
SGLIB_API S3DMODEL * GetModel(SCENEGRAPH *aNode)
Function GetModel creates an S3DMODEL representation of aNode (raw data, no transforms)
Definition: ifsg_api.cpp:471
std::list< wxString > const * GetFileFilters(void) const
Function GetFileFilters returns the list of file filters retrieved from the plugins; this will contai...
Definition: 3d_cache.cpp:689
S3D_PLUGIN_MANAGER * m_Plugins
plugin manager
Definition: 3d_cache.h:62