KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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 <[email protected]>
5 * Copyright (C) 2018-2022 KiCad Developers, see AUTHORS.txt for contributors.
6 * Copyright (C) 2022 CERN
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
26#define GLM_FORCE_RADIANS
27
28#include <mutex>
29#include <utility>
30
31#include <wx/datetime.h>
32#include <wx/dir.h>
33#include <wx/log.h>
34#include <wx/stdpaths.h>
35
36#include <boost/version.hpp>
37
38#if BOOST_VERSION >= 106800
39#include <boost/uuid/detail/sha1.hpp>
40#else
41#include <boost/uuid/sha1.hpp>
42#endif
43
44#include "3d_cache.h"
45#include "3d_info.h"
46#include "3d_plugin_manager.h"
47#include "sg/scenegraph.h"
49
50#include <advanced_config.h>
51#include <common.h> // For ExpandEnvVarSubstitutions
52#include <filename_resolver.h>
53#include <paths.h>
54#include <pgm_base.h>
55#include <project.h>
58#include <wx_filename.h>
59
60
61#define MASK_3D_CACHE "3D_CACHE"
62
63static std::mutex mutex3D_cache;
64
65
66static bool isSHA1Same( const unsigned char* shaA, const unsigned char* shaB ) noexcept
67{
68 for( int i = 0; i < 20; ++i )
69 {
70 if( shaA[i] != shaB[i] )
71 return false;
72 }
73
74 return true;
75}
76
77
78static bool checkTag( const char* aTag, void* aPluginMgrPtr )
79{
80 if( nullptr == aTag || nullptr == aPluginMgrPtr )
81 return false;
82
83 S3D_PLUGIN_MANAGER *pp = (S3D_PLUGIN_MANAGER*) aPluginMgrPtr;
84
85 return pp->CheckTag( aTag );
86}
87
88
89static const wxString sha1ToWXString( const unsigned char* aSHA1Sum )
90{
91 unsigned char uc;
92 unsigned char tmp;
93 char sha1[41];
94 int j = 0;
95
96 for( int i = 0; i < 20; ++i )
97 {
98 uc = aSHA1Sum[i];
99 tmp = uc / 16;
100
101 if( tmp > 9 )
102 tmp += 87;
103 else
104 tmp += 48;
105
106 sha1[j++] = tmp;
107 tmp = uc % 16;
108
109 if( tmp > 9 )
110 tmp += 87;
111 else
112 tmp += 48;
113
114 sha1[j++] = tmp;
115 }
116
117 sha1[j] = 0;
118
119 return wxString::FromUTF8Unchecked( sha1 );
120}
121
122
124{
125public:
128
129 void SetSHA1( const unsigned char* aSHA1Sum );
130 const wxString GetCacheBaseName();
131
132 wxDateTime modTime; // file modification time
133 unsigned char sha1sum[20];
134 std::string pluginInfo; // PluginName:Version string
137
138private:
139 // prohibit assignment and default copy constructor
142
143 wxString m_CacheBaseName; // base name of cache file (a SHA1 digest)
144};
145
146
148{
149 sceneData = nullptr;
150 renderData = nullptr;
151 memset( sha1sum, 0, 20 );
152}
153
154
156{
157 delete sceneData;
158
159 if( nullptr != renderData )
161}
162
163
164void S3D_CACHE_ENTRY::SetSHA1( const unsigned char* aSHA1Sum )
165{
166 if( nullptr == aSHA1Sum )
167 {
168 wxLogTrace( MASK_3D_CACHE, wxT( "%s:%s:%d\n * [BUG] NULL passed for aSHA1Sum" ),
169 __FILE__, __FUNCTION__, __LINE__ );
170
171 return;
172 }
173
174 memcpy( sha1sum, aSHA1Sum, 20 );
175}
176
177
179{
180 if( m_CacheBaseName.empty() )
182
183 return m_CacheBaseName;
184}
185
186
188{
190 m_project = nullptr;
192}
193
194
196{
197 FlushCache();
198
199 delete m_FNResolver;
200 delete m_Plugins;
201}
202
203
204SCENEGRAPH* S3D_CACHE::load( const wxString& aModelFile, const wxString& aBasePath,
205 S3D_CACHE_ENTRY** aCachePtr )
206{
207 if( aCachePtr )
208 *aCachePtr = nullptr;
209
210 wxString full3Dpath = m_FNResolver->ResolvePath( aModelFile, aBasePath );
211
212 if( full3Dpath.empty() )
213 {
214 // the model cannot be found; we cannot proceed
215 wxLogTrace( MASK_3D_CACHE, wxT( "%s:%s:%d\n * [3D model] could not find model '%s'\n" ),
216 __FILE__, __FUNCTION__, __LINE__, aModelFile );
217 return nullptr;
218 }
219
220 // check cache if file is already loaded
221 std::lock_guard<std::mutex> lock( mutex3D_cache );
222
223 std::map< wxString, S3D_CACHE_ENTRY*, rsort_wxString >::iterator mi;
224 mi = m_CacheMap.find( full3Dpath );
225
226 if( mi != m_CacheMap.end() )
227 {
228 wxFileName fname( full3Dpath );
229
230 if( fname.FileExists() ) // Only check if file exists. If not, it will
231 { // use the same model in cache.
233 wxDateTime fmdate = fname.GetModificationTime();
234
235 if( fmdate != mi->second->modTime )
236 {
237 unsigned char hashSum[20];
238 getSHA1( full3Dpath, hashSum );
239 mi->second->modTime = fmdate;
240
241 if( !isSHA1Same( hashSum, mi->second->sha1sum ) )
242 {
243 mi->second->SetSHA1( hashSum );
244 reload = true;
245 }
246 }
247
248 if( reload )
249 {
250 if( nullptr != mi->second->sceneData )
251 {
252 S3D::DestroyNode( mi->second->sceneData );
253 mi->second->sceneData = nullptr;
254 }
255
256 if( nullptr != mi->second->renderData )
257 S3D::Destroy3DModel( &mi->second->renderData );
258
259 mi->second->sceneData = m_Plugins->Load3DModel( full3Dpath,
260 mi->second->pluginInfo );
261 }
262 }
263
264 if( nullptr != aCachePtr )
265 *aCachePtr = mi->second;
266
267 return mi->second->sceneData;
268 }
269
270 // a cache item does not exist; search the Filename->Cachename map
271 return checkCache( full3Dpath, aCachePtr );
272}
273
274
275SCENEGRAPH* S3D_CACHE::Load( const wxString& aModelFile, const wxString& aBasePath )
276{
277 return load( aModelFile, aBasePath );
278}
279
280
281SCENEGRAPH* S3D_CACHE::checkCache( const wxString& aFileName, S3D_CACHE_ENTRY** aCachePtr )
282{
283 if( aCachePtr )
284 *aCachePtr = nullptr;
285
286 unsigned char sha1sum[20];
288 m_CacheList.push_back( ep );
289 wxFileName fname( aFileName );
290 ep->modTime = fname.GetModificationTime();
291
292 if( !getSHA1( aFileName, sha1sum ) || m_CacheDir.empty() )
293 {
294 // just in case we can't get a hash digest (for example, on access issues)
295 // or we do not have a configured cache file directory, we create an
296 // entry to prevent further attempts at loading the file
297
298 if( m_CacheMap.emplace( aFileName, ep ).second == false )
299 {
300 wxLogTrace( MASK_3D_CACHE,
301 wxT( "%s:%s:%d\n * [BUG] duplicate entry in map file; key = '%s'" ),
302 __FILE__, __FUNCTION__, __LINE__, aFileName );
303
304 m_CacheList.pop_back();
305 delete ep;
306 }
307 else
308 {
309 if( aCachePtr )
310 *aCachePtr = ep;
311 }
312
313 return nullptr;
314 }
315
316 if( m_CacheMap.emplace( aFileName, ep ).second == false )
317 {
318 wxLogTrace( MASK_3D_CACHE,
319 wxT( "%s:%s:%d\n * [BUG] duplicate entry in map file; key = '%s'" ),
320 __FILE__, __FUNCTION__, __LINE__, aFileName );
321
322 m_CacheList.pop_back();
323 delete ep;
324 return nullptr;
325 }
326
327 if( aCachePtr )
328 *aCachePtr = ep;
329
330 ep->SetSHA1( sha1sum );
331
332 wxString bname = ep->GetCacheBaseName();
333 wxString cachename = m_CacheDir + bname + wxT( ".3dc" );
334
335 if( !ADVANCED_CFG::GetCfg().m_Skip3DModelFileCache && wxFileName::FileExists( cachename )
336 && loadCacheData( ep ) )
337 return ep->sceneData;
338
339 ep->sceneData = m_Plugins->Load3DModel( aFileName, ep->pluginInfo );
340
341 if( !ADVANCED_CFG::GetCfg().m_Skip3DModelFileCache && nullptr != ep->sceneData )
342 saveCacheData( ep );
343
344 return ep->sceneData;
345}
346
347
348bool S3D_CACHE::getSHA1( const wxString& aFileName, unsigned char* aSHA1Sum )
349{
350 if( aFileName.empty() )
351 {
352 wxLogTrace( MASK_3D_CACHE, wxT( "%s:%s:%d\n * [BUG] empty filename" ),
353 __FILE__, __FUNCTION__, __LINE__ );
354
355 return false;
356 }
357
358 if( nullptr == aSHA1Sum )
359 {
360 wxLogTrace( MASK_3D_CACHE, wxT( "%s\n * [BUG] NULL pointer passed for aMD5Sum" ),
361 __FILE__, __FUNCTION__, __LINE__ );
362
363 return false;
364 }
365
366#ifdef _WIN32
367 FILE* fp = _wfopen( aFileName.wc_str(), L"rb" );
368#else
369 FILE* fp = fopen( aFileName.ToUTF8(), "rb" );
370#endif
371
372 if( nullptr == fp )
373 return false;
374
375 boost::uuids::detail::sha1 dblock;
376 unsigned char block[4096];
377 size_t bsize = 0;
378
379 while( ( bsize = fread( &block, 1, 4096, fp ) ) > 0 )
380 dblock.process_bytes( block, bsize );
381
382 fclose( fp );
383 unsigned int digest[5];
384 dblock.get_digest( digest );
385
386 // ensure MSB order
387 for( int i = 0; i < 5; ++i )
388 {
389 int idx = i << 2;
390 unsigned int tmp = digest[i];
391 aSHA1Sum[idx+3] = tmp & 0xff;
392 tmp >>= 8;
393 aSHA1Sum[idx+2] = tmp & 0xff;
394 tmp >>= 8;
395 aSHA1Sum[idx+1] = tmp & 0xff;
396 tmp >>= 8;
397 aSHA1Sum[idx] = tmp & 0xff;
398 }
399
400 return true;
401}
402
403
405{
406 wxString bname = aCacheItem->GetCacheBaseName();
407
408 if( bname.empty() )
409 {
410 wxLogTrace( MASK_3D_CACHE,
411 wxT( " * [3D model] cannot load cached model; no file hash available" ) );
412
413 return false;
414 }
415
416 if( m_CacheDir.empty() )
417 {
418 wxLogTrace( MASK_3D_CACHE,
419 wxT( " * [3D model] cannot load cached model; config directory unknown" ) );
420
421 return false;
422 }
423
424 wxString fname = m_CacheDir + bname + wxT( ".3dc" );
425
426 if( !wxFileName::FileExists( fname ) )
427 {
428 wxLogTrace( MASK_3D_CACHE, wxT( " * [3D model] cannot open file '%s'" ), fname.GetData() );
429 return false;
430 }
431
432 if( nullptr != aCacheItem->sceneData )
433 S3D::DestroyNode( (SGNODE*) aCacheItem->sceneData );
434
435 aCacheItem->sceneData = (SCENEGRAPH*)S3D::ReadCache( fname.ToUTF8(), m_Plugins, checkTag );
436
437 if( nullptr == aCacheItem->sceneData )
438 return false;
439
440 return true;
441}
442
443
445{
446 if( nullptr == aCacheItem )
447 {
448 wxLogTrace( MASK_3D_CACHE, wxT( "%s:%s:%d\n * NULL passed for aCacheItem" ),
449 __FILE__, __FUNCTION__, __LINE__ );
450
451 return false;
452 }
453
454 if( nullptr == aCacheItem->sceneData )
455 {
456 wxLogTrace( MASK_3D_CACHE, wxT( "%s:%s:%d\n * aCacheItem has no valid scene data" ),
457 __FILE__, __FUNCTION__, __LINE__ );
458
459 return false;
460 }
461
462 wxString bname = aCacheItem->GetCacheBaseName();
463
464 if( bname.empty() )
465 {
466 wxLogTrace( MASK_3D_CACHE,
467 wxT( " * [3D model] cannot load cached model; no file hash available" ) );
468
469 return false;
470 }
471
472 if( m_CacheDir.empty() )
473 {
474 wxLogTrace( MASK_3D_CACHE,
475 wxT( " * [3D model] cannot load cached model; config directory unknown" ) );
476
477 return false;
478 }
479
480 wxString fname = m_CacheDir + bname + wxT( ".3dc" );
481
482 if( wxFileName::Exists( fname ) )
483 {
484 if( !wxFileName::FileExists( fname ) )
485 {
486 wxLogTrace( MASK_3D_CACHE,
487 wxT( " * [3D model] path exists but is not a regular file '%s'" ), fname );
488
489 return false;
490 }
491 }
492
493 return S3D::WriteCache( fname.ToUTF8(), true, (SGNODE*)aCacheItem->sceneData,
494 aCacheItem->pluginInfo.c_str() );
495}
496
497
498bool S3D_CACHE::Set3DConfigDir( const wxString& aConfigDir )
499{
500 if( !m_ConfigDir.empty() )
501 return false;
502
503 wxFileName cfgdir( ExpandEnvVarSubstitutions( aConfigDir, m_project ), wxEmptyString );
504
505 cfgdir.Normalize( FN_NORMALIZE_FLAGS );
506
507 if( !cfgdir.DirExists() )
508 {
509 cfgdir.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL );
510
511 if( !cfgdir.DirExists() )
512 {
513 wxLogTrace( MASK_3D_CACHE,
514 wxT( "%s:%s:%d\n * failed to create 3D configuration directory '%s'" ),
515 __FILE__, __FUNCTION__, __LINE__, cfgdir.GetPath() );
516
517 return false;
518 }
519 }
520
521 m_ConfigDir = cfgdir.GetPath();
522
523 // inform the file resolver of the config directory
525 {
526 wxLogTrace( MASK_3D_CACHE,
527 wxT( "%s:%s:%d\n * could not set 3D Config Directory on filename resolver\n"
528 " * config directory: '%s'" ),
529 __FILE__, __FUNCTION__, __LINE__, m_ConfigDir );
530 }
531
532 // 3D cache data must go to a user's cache directory;
533 // unfortunately wxWidgets doesn't seem to provide
534 // functions to retrieve such a directory.
535 //
536 // 1. OSX: ~/Library/Caches/kicad/3d/
537 // 2. Linux: ${XDG_CACHE_HOME}/kicad/3d ~/.cache/kicad/3d/
538 // 3. MSWin: AppData\Local\kicad\3d
539 wxFileName cacheDir;
540 cacheDir.AssignDir( PATHS::GetUserCachePath() );
541 cacheDir.AppendDir( wxT( "3d" ) );
542
543 if( !cacheDir.DirExists() )
544 {
545 cacheDir.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL );
546
547 if( !cacheDir.DirExists() )
548 {
549 wxLogTrace( MASK_3D_CACHE,
550 wxT( "%s:%s:%d\n * failed to create 3D cache directory '%s'" ),
551 __FILE__, __FUNCTION__, __LINE__, cacheDir.GetPath() );
552
553 return false;
554 }
555 }
556
557 m_CacheDir = cacheDir.GetPathWithSep();
558 return true;
559}
560
561
563{
564 m_project = aProject;
565
566 bool hasChanged = false;
567
568 if( m_FNResolver->SetProject( aProject, &hasChanged ) && hasChanged )
569 {
570 m_CacheMap.clear();
571
572 std::list< S3D_CACHE_ENTRY* >::iterator sL = m_CacheList.begin();
573 std::list< S3D_CACHE_ENTRY* >::iterator eL = m_CacheList.end();
574
575 while( sL != eL )
576 {
577 delete *sL;
578 ++sL;
579 }
580
581 m_CacheList.clear();
582
583 return true;
584 }
585
586 return false;
587}
588
589
591{
593}
594
595
597{
598 return m_FNResolver;
599}
600
601
602std::list< wxString > const* S3D_CACHE::GetFileFilters() const
603{
604 return m_Plugins->GetFileFilters();
605}
606
607
608void S3D_CACHE::FlushCache( bool closePlugins )
609{
610 std::list< S3D_CACHE_ENTRY* >::iterator sCL = m_CacheList.begin();
611 std::list< S3D_CACHE_ENTRY* >::iterator eCL = m_CacheList.end();
612
613 while( sCL != eCL )
614 {
615 delete *sCL;
616 ++sCL;
617 }
618
619 m_CacheList.clear();
620 m_CacheMap.clear();
621
622 if( closePlugins )
623 ClosePlugins();
624}
625
626
628{
629 if( m_Plugins )
631}
632
633
634S3DMODEL* S3D_CACHE::GetModel( const wxString& aModelFileName, const wxString& aBasePath )
635{
636 S3D_CACHE_ENTRY* cp = nullptr;
637 SCENEGRAPH* sp = load( aModelFileName, aBasePath,&cp );
638
639 if( !sp )
640 return nullptr;
641
642 if( !cp )
643 {
644 wxLogTrace( MASK_3D_CACHE,
645 wxT( "%s:%s:%d\n * [BUG] model loaded with no associated S3D_CACHE_ENTRY" ),
646 __FILE__, __FUNCTION__, __LINE__ );
647
648 return nullptr;
649 }
650
651 if( cp->renderData )
652 return cp->renderData;
653
654 S3DMODEL* mp = S3D::GetModel( sp );
655 cp->renderData = mp;
656
657 return mp;
658}
659
660void S3D_CACHE::CleanCacheDir( int aNumDaysOld )
661{
662 wxDir dir;
663 wxString fileSpec = wxT( "*.3dc" );
664 wxArrayString fileList; // Holds list of ".3dc" files found in cache directory
665 size_t numFilesFound = 0;
666
667 wxFileName thisFile;
668 wxDateTime lastAccess, thresholdDate;
669 wxDateSpan durationInDays;
670
671 // Calc the threshold date above which we delete cache files
672 durationInDays.SetDays( aNumDaysOld );
673 thresholdDate = wxDateTime::Now() - durationInDays;
674
675 // If the cache directory can be found and opened, then we'll try and clean it up
676 if( dir.Open( m_CacheDir ) )
677 {
678 thisFile.SetPath( m_CacheDir ); // Set the base path to the cache folder
679
680 // Get a list of all the ".3dc" files in the cache directory
681 numFilesFound = dir.GetAllFiles( m_CacheDir, &fileList, fileSpec );
682
683 for( unsigned int i = 0; i < numFilesFound; i++ )
684 {
685 // Completes path to specific file so we can get its "last access" date
686 thisFile.SetFullName( fileList[i] );
687
688 // Only get "last access" time to compare against. Don't need the other 2 timestamps.
689 if( thisFile.GetTimes( &lastAccess, nullptr, nullptr ) )
690 {
691 if( lastAccess.IsEarlierThan( thresholdDate ) )
692 {
693 // This file is older than the threshold so delete it
694 wxRemoveFile( thisFile.GetFullPath() );
695 }
696 }
697 }
698 }
699}
static bool isSHA1Same(const unsigned char *shaA, const unsigned char *shaB) noexcept
Definition: 3d_cache.cpp:66
#define MASK_3D_CACHE
Definition: 3d_cache.cpp:61
static std::mutex mutex3D_cache
Definition: 3d_cache.cpp:63
static const wxString sha1ToWXString(const unsigned char *aSHA1Sum)
Definition: 3d_cache.cpp:89
static bool checkTag(const char *aTag, void *aPluginMgrPtr)
Definition: 3d_cache.cpp:78
defines the basic data associated with a single 3D model.
manages 3D model plugins
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
Provide an extensible class to resolve 3D model paths.
bool Set3DConfigDir(const wxString &aConfigDir)
Set the user's configuration directory for 3D models.
bool SetProject(PROJECT *aProject, bool *flgChanged=nullptr)
Set the current KiCad project directory as the first entry in the model path list.
void SetProgramBase(PGM_BASE *aBase)
Set a pointer to the application's PGM_BASE instance used to extract the local env vars.
wxString ResolvePath(const wxString &aFileName, const wxString &aWorkingPath)
Determines the full path of the given file name.
static wxString GetUserCachePath()
Gets the stock (install) 3d viewer plugins path.
Definition: paths.cpp:344
Container for data for KiCad programs.
Definition: pgm_base.h:102
Container for project specific data.
Definition: project.h:62
Definition: 3d_cache.cpp:124
void SetSHA1(const unsigned char *aSHA1Sum)
Definition: 3d_cache.cpp:164
S3D_CACHE_ENTRY & operator=(const S3D_CACHE_ENTRY &source)
S3DMODEL * renderData
Definition: 3d_cache.cpp:136
~S3D_CACHE_ENTRY()
Definition: 3d_cache.cpp:155
SCENEGRAPH * sceneData
Definition: 3d_cache.cpp:135
S3D_CACHE_ENTRY(const S3D_CACHE_ENTRY &source)
const wxString GetCacheBaseName()
Definition: 3d_cache.cpp:178
std::string pluginInfo
Definition: 3d_cache.cpp:134
wxString m_CacheBaseName
Definition: 3d_cache.cpp:143
wxDateTime modTime
Definition: 3d_cache.cpp:132
unsigned char sha1sum[20]
Definition: 3d_cache.cpp:133
S3D_CACHE_ENTRY()
Definition: 3d_cache.cpp:147
bool getSHA1(const wxString &aFileName, unsigned char *aSHA1Sum)
Calculate the SHA1 hash of the given file.
Definition: 3d_cache.cpp:348
void SetProgramBase(PGM_BASE *aBase)
Set the filename resolver's pointer to the application's PGM_BASE instance.
Definition: 3d_cache.cpp:590
SCENEGRAPH * load(const wxString &aModelFile, const wxString &aBasePath, S3D_CACHE_ENTRY **aCachePtr=nullptr)
Definition: 3d_cache.cpp:204
wxString m_CacheDir
Definition: 3d_cache.h:181
bool loadCacheData(S3D_CACHE_ENTRY *aCacheItem)
Definition: 3d_cache.cpp:404
virtual ~S3D_CACHE()
Definition: 3d_cache.cpp:195
void FlushCache(bool closePlugins=true)
Free all data in the cache and by default closes all plugins.
Definition: 3d_cache.cpp:608
bool Set3DConfigDir(const wxString &aConfigDir)
Sets the configuration directory to be used by the model manager for storing 3D model manager configu...
Definition: 3d_cache.cpp:498
S3DMODEL * GetModel(const wxString &aModelFileName, const wxString &aBasePath)
Attempt to load the scene data for a model and to translate it into an S3D_MODEL structure for displa...
Definition: 3d_cache.cpp:634
SCENEGRAPH * checkCache(const wxString &aFileName, S3D_CACHE_ENTRY **aCachePtr=nullptr)
Find or create cache entry for file name.
Definition: 3d_cache.cpp:281
PROJECT * m_project
Definition: 3d_cache.h:180
S3D_PLUGIN_MANAGER * m_Plugins
Definition: 3d_cache.h:178
bool saveCacheData(S3D_CACHE_ENTRY *aCacheItem)
Definition: 3d_cache.cpp:444
wxString m_ConfigDir
Definition: 3d_cache.h:182
std::list< wxString > const * GetFileFilters() const
Return the list of file filters retrieved from the plugins.
Definition: 3d_cache.cpp:602
FILENAME_RESOLVER * GetResolver() noexcept
Definition: 3d_cache.cpp:596
std::list< S3D_CACHE_ENTRY * > m_CacheList
cache entries
Definition: 3d_cache.h:171
bool SetProject(PROJECT *aProject)
Set the current project's working directory; this affects the model search path.
Definition: 3d_cache.cpp:562
void CleanCacheDir(int aNumDaysOld)
Delete up old cache files in cache directory.
Definition: 3d_cache.cpp:660
std::map< wxString, S3D_CACHE_ENTRY *, rsort_wxString > m_CacheMap
mapping of file names to cache names and data
Definition: 3d_cache.h:174
SCENEGRAPH * Load(const wxString &aModelFile, const wxString &aBasePath)
Attempt to load the scene data for a model.
Definition: 3d_cache.cpp:275
void ClosePlugins()
Unload plugins to free memory.
Definition: 3d_cache.cpp:627
FILENAME_RESOLVER * m_FNResolver
Definition: 3d_cache.h:176
void ClosePlugins(void)
Iterate through all discovered plugins and closes them to reclaim memory.
SCENEGRAPH * Load3DModel(const wxString &aFileName, std::string &aPluginInfo)
std::list< wxString > const * GetFileFilters(void) const noexcept
Return the list of file filters; this will contain at least the default "All Files (*....
bool CheckTag(const char *aTag)
Check the given tag and returns true if the plugin named in the tag is not loaded or the plugin is lo...
Define the basic data set required to represent a 3D model.
Definition: scenegraph.h:45
The base class of all Scene Graph nodes.
Definition: sg_node.h:75
const wxString ExpandEnvVarSubstitutions(const wxString &aString, const PROJECT *aProject)
Replace any environment variable & text variable references with their values.
Definition: common.cpp:334
The common library.
bool m_Skip3DModelMemoryCache
Skip reading/writing 3D model memory caches.
defines the API calls for the manipulation of SG* classes
SGLIB_API SGNODE * ReadCache(const char *aFileName, void *aPluginMgr, bool(*aTagCheck)(const char *, void *))
Function ReadCache reads a binary cache file and creates an SGNODE tree.
Definition: ifsg_api.cpp:221
SGLIB_API bool WriteCache(const char *aFileName, bool overwrite, SGNODE *aNode, const char *aPluginInfo)
Function WriteCache writes the SGNODE tree to a binary cache file.
Definition: ifsg_api.cpp:157
SGLIB_API void DestroyNode(SGNODE *aNode) noexcept
Function DestroyNode deletes the given SG* class node.
Definition: ifsg_api.cpp:149
SGLIB_API S3DMODEL * GetModel(SCENEGRAPH *aNode)
Function GetModel creates an S3DMODEL representation of aNode (raw data, no transforms)
Definition: ifsg_api.cpp:338
SGLIB_API void Destroy3DModel(S3DMODEL **aModel)
Function Destroy3DModel frees memory used by an S3DMODEL structure and sets the pointer to the struct...
Definition: ifsg_api.cpp:403
see class PGM_BASE
Store the a model based on meshes and materials.
Definition: c3dmodel.h:91
#define FN_NORMALIZE_FLAGS
Default flags to pass to wxFileName::Normalize().
Definition: wx_filename.h:39