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;
187  m_FNResolver = new FILENAME_RESOLVER;
188  m_Plugins = new S3D_PLUGIN_MANAGER;
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
536  if( !m_FNResolver->Set3DConfigDir( m_ConfigDir ) )
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 )
719  m_Plugins->ClosePlugins();
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:149
#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, otherwise it returns wxEmptyString.
Definition: 3d_cache.cpp:589
void SetProgramBase(PGM_BASE *aBase)
Function SetProgramBase sets the filename resolver&#39;s pointer to the application&#39;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.
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
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
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)
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
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
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&#39;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:442
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
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
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
S3DMODEL * renderData
Definition: 3d_cache.cpp:138
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
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.
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&#39;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
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