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 <[email protected]>
5 * Copyright (C) 2018-2022 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 <mutex>
28#include <utility>
29
30#include <wx/datetime.h>
31#include <wx/dir.h>
32#include <wx/log.h>
33#include <wx/stdpaths.h>
34
35#include <boost/version.hpp>
36
37#if BOOST_VERSION >= 106800
38#include <boost/uuid/detail/sha1.hpp>
39#else
40#include <boost/uuid/sha1.hpp>
41#endif
42
43#include "3d_cache.h"
44#include "3d_info.h"
45#include "3d_plugin_manager.h"
46#include "sg/scenegraph.h"
48
49#include <advanced_config.h>
50#include <common.h> // For ExpandEnvVarSubstitutions
51#include <filename_resolver.h>
52#include <paths.h>
53#include <pgm_base.h>
54#include <project.h>
57#include <wx_filename.h>
58
59
60#define MASK_3D_CACHE "3D_CACHE"
61
62static std::mutex mutex3D_cache;
63static std::mutex mutex3D_cacheManager;
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 // We'll delete ".3dc" cache files older than this many days
200 int clearCacheInterval = 0;
201
202 if( Pgm().GetCommonSettings() )
203 clearCacheInterval = Pgm().GetCommonSettings()->m_System.clear_3d_cache_interval;
204
205 // An interval of zero means the user doesn't want to ever clear the cache
206
207 if( clearCacheInterval > 0 )
208 CleanCacheDir( clearCacheInterval );
209
210 delete m_FNResolver;
211 delete m_Plugins;
212}
213
214
215SCENEGRAPH* S3D_CACHE::load( const wxString& aModelFile, const wxString& aBasePath,
216 S3D_CACHE_ENTRY** aCachePtr )
217{
218 if( aCachePtr )
219 *aCachePtr = nullptr;
220
221 wxString full3Dpath = m_FNResolver->ResolvePath( aModelFile, aBasePath );
222
223 if( full3Dpath.empty() )
224 {
225 // the model cannot be found; we cannot proceed
226 wxLogTrace( MASK_3D_CACHE, wxT( "%s:%s:%d\n * [3D model] could not find model '%s'\n" ),
227 __FILE__, __FUNCTION__, __LINE__, aModelFile );
228 return nullptr;
229 }
230
231 // check cache if file is already loaded
232 std::lock_guard<std::mutex> lock( mutex3D_cache );
233
234 std::map< wxString, S3D_CACHE_ENTRY*, rsort_wxString >::iterator mi;
235 mi = m_CacheMap.find( full3Dpath );
236
237 if( mi != m_CacheMap.end() )
238 {
239 wxFileName fname( full3Dpath );
240
241 if( fname.FileExists() ) // Only check if file exists. If not, it will
242 { // use the same model in cache.
244 wxDateTime fmdate = fname.GetModificationTime();
245
246 if( fmdate != mi->second->modTime )
247 {
248 unsigned char hashSum[20];
249 getSHA1( full3Dpath, hashSum );
250 mi->second->modTime = fmdate;
251
252 if( !isSHA1Same( hashSum, mi->second->sha1sum ) )
253 {
254 mi->second->SetSHA1( hashSum );
255 reload = true;
256 }
257 }
258
259 if( reload )
260 {
261 if( nullptr != mi->second->sceneData )
262 {
263 S3D::DestroyNode( mi->second->sceneData );
264 mi->second->sceneData = nullptr;
265 }
266
267 if( nullptr != mi->second->renderData )
268 S3D::Destroy3DModel( &mi->second->renderData );
269
270 mi->second->sceneData = m_Plugins->Load3DModel( full3Dpath,
271 mi->second->pluginInfo );
272 }
273 }
274
275 if( nullptr != aCachePtr )
276 *aCachePtr = mi->second;
277
278 return mi->second->sceneData;
279 }
280
281 // a cache item does not exist; search the Filename->Cachename map
282 return checkCache( full3Dpath, aCachePtr );
283}
284
285
286SCENEGRAPH* S3D_CACHE::Load( const wxString& aModelFile, const wxString& aBasePath )
287{
288 return load( aModelFile, aBasePath );
289}
290
291
292SCENEGRAPH* S3D_CACHE::checkCache( const wxString& aFileName, S3D_CACHE_ENTRY** aCachePtr )
293{
294 if( aCachePtr )
295 *aCachePtr = nullptr;
296
297 unsigned char sha1sum[20];
299 m_CacheList.push_back( ep );
300 wxFileName fname( aFileName );
301 ep->modTime = fname.GetModificationTime();
302
303 if( !getSHA1( aFileName, sha1sum ) || m_CacheDir.empty() )
304 {
305 // just in case we can't get a hash digest (for example, on access issues)
306 // or we do not have a configured cache file directory, we create an
307 // entry to prevent further attempts at loading the file
308
309 if( m_CacheMap.emplace( aFileName, ep ).second == false )
310 {
311 wxLogTrace( MASK_3D_CACHE,
312 wxT( "%s:%s:%d\n * [BUG] duplicate entry in map file; key = '%s'" ),
313 __FILE__, __FUNCTION__, __LINE__, aFileName );
314
315 m_CacheList.pop_back();
316 delete ep;
317 }
318 else
319 {
320 if( aCachePtr )
321 *aCachePtr = ep;
322 }
323
324 return nullptr;
325 }
326
327 if( m_CacheMap.emplace( aFileName, ep ).second == false )
328 {
329 wxLogTrace( MASK_3D_CACHE,
330 wxT( "%s:%s:%d\n * [BUG] duplicate entry in map file; key = '%s'" ),
331 __FILE__, __FUNCTION__, __LINE__, aFileName );
332
333 m_CacheList.pop_back();
334 delete ep;
335 return nullptr;
336 }
337
338 if( aCachePtr )
339 *aCachePtr = ep;
340
341 ep->SetSHA1( sha1sum );
342
343 wxString bname = ep->GetCacheBaseName();
344 wxString cachename = m_CacheDir + bname + wxT( ".3dc" );
345
346 if( !ADVANCED_CFG::GetCfg().m_Skip3DModelFileCache && wxFileName::FileExists( cachename )
347 && loadCacheData( ep ) )
348 return ep->sceneData;
349
350 ep->sceneData = m_Plugins->Load3DModel( aFileName, ep->pluginInfo );
351
352 if( !ADVANCED_CFG::GetCfg().m_Skip3DModelFileCache && nullptr != ep->sceneData )
353 saveCacheData( ep );
354
355 return ep->sceneData;
356}
357
358
359bool S3D_CACHE::getSHA1( const wxString& aFileName, unsigned char* aSHA1Sum )
360{
361 if( aFileName.empty() )
362 {
363 wxLogTrace( MASK_3D_CACHE, wxT( "%s:%s:%d\n * [BUG] empty filename" ),
364 __FILE__, __FUNCTION__, __LINE__ );
365
366 return false;
367 }
368
369 if( nullptr == aSHA1Sum )
370 {
371 wxLogTrace( MASK_3D_CACHE, wxT( "%s\n * [BUG] NULL pointer passed for aMD5Sum" ),
372 __FILE__, __FUNCTION__, __LINE__ );
373
374 return false;
375 }
376
377#ifdef _WIN32
378 FILE* fp = _wfopen( aFileName.wc_str(), L"rb" );
379#else
380 FILE* fp = fopen( aFileName.ToUTF8(), "rb" );
381#endif
382
383 if( nullptr == fp )
384 return false;
385
386 boost::uuids::detail::sha1 dblock;
387 unsigned char block[4096];
388 size_t bsize = 0;
389
390 while( ( bsize = fread( &block, 1, 4096, fp ) ) > 0 )
391 dblock.process_bytes( block, bsize );
392
393 fclose( fp );
394 unsigned int digest[5];
395 dblock.get_digest( digest );
396
397 // ensure MSB order
398 for( int i = 0; i < 5; ++i )
399 {
400 int idx = i << 2;
401 unsigned int tmp = digest[i];
402 aSHA1Sum[idx+3] = tmp & 0xff;
403 tmp >>= 8;
404 aSHA1Sum[idx+2] = tmp & 0xff;
405 tmp >>= 8;
406 aSHA1Sum[idx+1] = tmp & 0xff;
407 tmp >>= 8;
408 aSHA1Sum[idx] = tmp & 0xff;
409 }
410
411 return true;
412}
413
414
416{
417 wxString bname = aCacheItem->GetCacheBaseName();
418
419 if( bname.empty() )
420 {
421 wxLogTrace( MASK_3D_CACHE,
422 wxT( " * [3D model] cannot load cached model; no file hash available" ) );
423
424 return false;
425 }
426
427 if( m_CacheDir.empty() )
428 {
429 wxLogTrace( MASK_3D_CACHE,
430 wxT( " * [3D model] cannot load cached model; config directory unknown" ) );
431
432 return false;
433 }
434
435 wxString fname = m_CacheDir + bname + wxT( ".3dc" );
436
437 if( !wxFileName::FileExists( fname ) )
438 {
439 wxLogTrace( MASK_3D_CACHE, wxT( " * [3D model] cannot open file '%s'" ), fname.GetData() );
440 return false;
441 }
442
443 if( nullptr != aCacheItem->sceneData )
444 S3D::DestroyNode( (SGNODE*) aCacheItem->sceneData );
445
446 aCacheItem->sceneData = (SCENEGRAPH*)S3D::ReadCache( fname.ToUTF8(), m_Plugins, checkTag );
447
448 if( nullptr == aCacheItem->sceneData )
449 return false;
450
451 return true;
452}
453
454
456{
457 if( nullptr == aCacheItem )
458 {
459 wxLogTrace( MASK_3D_CACHE, wxT( "%s:%s:%d\n * NULL passed for aCacheItem" ),
460 __FILE__, __FUNCTION__, __LINE__ );
461
462 return false;
463 }
464
465 if( nullptr == aCacheItem->sceneData )
466 {
467 wxLogTrace( MASK_3D_CACHE, wxT( "%s:%s:%d\n * aCacheItem has no valid scene data" ),
468 __FILE__, __FUNCTION__, __LINE__ );
469
470 return false;
471 }
472
473 wxString bname = aCacheItem->GetCacheBaseName();
474
475 if( bname.empty() )
476 {
477 wxLogTrace( MASK_3D_CACHE,
478 wxT( " * [3D model] cannot load cached model; no file hash available" ) );
479
480 return false;
481 }
482
483 if( m_CacheDir.empty() )
484 {
485 wxLogTrace( MASK_3D_CACHE,
486 wxT( " * [3D model] cannot load cached model; config directory unknown" ) );
487
488 return false;
489 }
490
491 wxString fname = m_CacheDir + bname + wxT( ".3dc" );
492
493 if( wxFileName::Exists( fname ) )
494 {
495 if( !wxFileName::FileExists( fname ) )
496 {
497 wxLogTrace( MASK_3D_CACHE,
498 wxT( " * [3D model] path exists but is not a regular file '%s'" ), fname );
499
500 return false;
501 }
502 }
503
504 return S3D::WriteCache( fname.ToUTF8(), true, (SGNODE*)aCacheItem->sceneData,
505 aCacheItem->pluginInfo.c_str() );
506}
507
508
509bool S3D_CACHE::Set3DConfigDir( const wxString& aConfigDir )
510{
511 if( !m_ConfigDir.empty() )
512 return false;
513
514 wxFileName cfgdir( ExpandEnvVarSubstitutions( aConfigDir, m_project ), wxEmptyString );
515
516 cfgdir.Normalize( FN_NORMALIZE_FLAGS );
517
518 if( !cfgdir.DirExists() )
519 {
520 cfgdir.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL );
521
522 if( !cfgdir.DirExists() )
523 {
524 wxLogTrace( MASK_3D_CACHE,
525 wxT( "%s:%s:%d\n * failed to create 3D configuration directory '%s'" ),
526 __FILE__, __FUNCTION__, __LINE__, cfgdir.GetPath() );
527
528 return false;
529 }
530 }
531
532 m_ConfigDir = cfgdir.GetPath();
533
534 // inform the file resolver of the config directory
536 {
537 wxLogTrace( MASK_3D_CACHE,
538 wxT( "%s:%s:%d\n * could not set 3D Config Directory on filename resolver\n"
539 " * config directory: '%s'" ),
540 __FILE__, __FUNCTION__, __LINE__, m_ConfigDir );
541 }
542
543 // 3D cache data must go to a user's cache directory;
544 // unfortunately wxWidgets doesn't seem to provide
545 // functions to retrieve such a directory.
546 //
547 // 1. OSX: ~/Library/Caches/kicad/3d/
548 // 2. Linux: ${XDG_CACHE_HOME}/kicad/3d ~/.cache/kicad/3d/
549 // 3. MSWin: AppData\Local\kicad\3d
550 wxFileName cacheDir;
551 cacheDir.AssignDir( PATHS::GetUserCachePath() );
552 cacheDir.AppendDir( wxT( "3d" ) );
553
554 if( !cacheDir.DirExists() )
555 {
556 cacheDir.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL );
557
558 if( !cacheDir.DirExists() )
559 {
560 wxLogTrace( MASK_3D_CACHE,
561 wxT( "%s:%s:%d\n * failed to create 3D cache directory '%s'" ),
562 __FILE__, __FUNCTION__, __LINE__, cacheDir.GetPath() );
563
564 return false;
565 }
566 }
567
568 m_CacheDir = cacheDir.GetPathWithSep();
569 return true;
570}
571
572
574{
575 m_project = aProject;
576
577 bool hasChanged = false;
578
579 if( m_FNResolver->SetProject( aProject, &hasChanged ) && hasChanged )
580 {
581 m_CacheMap.clear();
582
583 std::list< S3D_CACHE_ENTRY* >::iterator sL = m_CacheList.begin();
584 std::list< S3D_CACHE_ENTRY* >::iterator eL = m_CacheList.end();
585
586 while( sL != eL )
587 {
588 delete *sL;
589 ++sL;
590 }
591
592 m_CacheList.clear();
593
594 return true;
595 }
596
597 return false;
598}
599
600
602{
604}
605
606
608{
609 return m_FNResolver;
610}
611
612
613std::list< wxString > const* S3D_CACHE::GetFileFilters() const
614{
615 return m_Plugins->GetFileFilters();
616}
617
618
619void S3D_CACHE::FlushCache( bool closePlugins )
620{
621 std::list< S3D_CACHE_ENTRY* >::iterator sCL = m_CacheList.begin();
622 std::list< S3D_CACHE_ENTRY* >::iterator eCL = m_CacheList.end();
623
624 while( sCL != eCL )
625 {
626 delete *sCL;
627 ++sCL;
628 }
629
630 m_CacheList.clear();
631 m_CacheMap.clear();
632
633 if( closePlugins )
634 ClosePlugins();
635}
636
637
639{
640 if( m_Plugins )
642}
643
644
645S3DMODEL* S3D_CACHE::GetModel( const wxString& aModelFileName, const wxString& aBasePath )
646{
647 S3D_CACHE_ENTRY* cp = nullptr;
648 SCENEGRAPH* sp = load( aModelFileName, aBasePath,&cp );
649
650 if( !sp )
651 return nullptr;
652
653 if( !cp )
654 {
655 wxLogTrace( MASK_3D_CACHE,
656 wxT( "%s:%s:%d\n * [BUG] model loaded with no associated S3D_CACHE_ENTRY" ),
657 __FILE__, __FUNCTION__, __LINE__ );
658
659 return nullptr;
660 }
661
662 if( cp->renderData )
663 return cp->renderData;
664
665 S3DMODEL* mp = S3D::GetModel( sp );
666 cp->renderData = mp;
667
668 return mp;
669}
670
671void S3D_CACHE::CleanCacheDir( int aNumDaysOld )
672{
673 wxDir dir;
674 wxString fileSpec = wxT( "*.3dc" );
675 wxArrayString fileList; // Holds list of ".3dc" files found in cache directory
676 size_t numFilesFound = 0;
677
678 wxFileName thisFile;
679 wxDateTime lastAccess, thresholdDate;
680 wxDateSpan durationInDays;
681
682 // Calc the threshold date above which we delete cache files
683 durationInDays.SetDays( aNumDaysOld );
684 thresholdDate = wxDateTime::Now() - durationInDays;
685
686 // If the cache directory can be found and opened, then we'll try and clean it up
687 if( dir.Open( m_CacheDir ) )
688 {
689 thisFile.SetPath( m_CacheDir ); // Set the base path to the cache folder
690
691 // Get a list of all the ".3dc" files in the cache directory
692 numFilesFound = dir.GetAllFiles( m_CacheDir, &fileList, fileSpec );
693
694 for( unsigned int i = 0; i < numFilesFound; i++ )
695 {
696 // Completes path to specific file so we can get its "last access" date
697 thisFile.SetFullName( fileList[i] );
698
699 // Only get "last access" time to compare against. Don't need the other 2 timestamps.
700 if( thisFile.GetTimes( &lastAccess, nullptr, nullptr ) )
701 {
702 if( lastAccess.IsEarlierThan( thresholdDate ) )
703 {
704 // This file is older than the threshold so delete it
705 wxRemoveFile( thisFile.GetFullPath() );
706 }
707 }
708 }
709 }
710}
711
712
713S3D_CACHE* PROJECT::Get3DCacheManager( bool aUpdateProjDir )
714{
715 std::lock_guard<std::mutex> lock( mutex3D_cacheManager );
716
717 // Get the existing cache from the project
718 S3D_CACHE* cache = dynamic_cast<S3D_CACHE*>( GetElem( ELEM_3DCACHE ) );
719
720 if( !cache )
721 {
722 // Create a cache if there is not one already
723 cache = new S3D_CACHE();
724
725 wxFileName cfgpath;
726 cfgpath.AssignDir( SETTINGS_MANAGER::GetUserSettingsPath() );
727 cfgpath.AppendDir( wxT( "3d" ) );
728
729 cache->SetProgramBase( &Pgm() );
730 cache->Set3DConfigDir( cfgpath.GetFullPath() );
731
732 SetElem( ELEM_3DCACHE, cache );
733 aUpdateProjDir = true;
734 }
735
736 if( aUpdateProjDir )
737 cache->SetProject( this );
738
739 return cache;
740}
741
742
743FILENAME_RESOLVER* PROJECT::Get3DFilenameResolver()
744{
745 return Get3DCacheManager()->GetResolver();
746}
static bool isSHA1Same(const unsigned char *shaA, const unsigned char *shaB) noexcept
Definition: 3d_cache.cpp:66
static std::mutex mutex3D_cacheManager
Definition: 3d_cache.cpp:63
#define MASK_3D_CACHE
Definition: 3d_cache.cpp:60
static std::mutex mutex3D_cache
Definition: 3d_cache.cpp:62
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
bool m_Skip3DModelMemoryCache
Skip reading/writing 3d model memory caches This ensures 3d models are always reloaded from disk even...
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:321
Container for data for KiCad programs.
Definition: pgm_base.h:94
Container for project specific data.
Definition: project.h:63
virtual _ELEM * GetElem(ELEM_T aIndex)
Get and set the elements for this project.
Definition: project.cpp:284
virtual void SetElem(ELEM_T aIndex, _ELEM *aElem)
Definition: project.cpp:294
@ ELEM_3DCACHE
Definition: project.h:209
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
Cache for storing the 3D shapes.
Definition: 3d_cache.h:53
bool getSHA1(const wxString &aFileName, unsigned char *aSHA1Sum)
Calculate the SHA1 hash of the given file.
Definition: 3d_cache.cpp:359
void SetProgramBase(PGM_BASE *aBase)
Set the filename resolver's pointer to the application's PGM_BASE instance.
Definition: 3d_cache.cpp:601
SCENEGRAPH * load(const wxString &aModelFile, const wxString &aBasePath, S3D_CACHE_ENTRY **aCachePtr=nullptr)
Definition: 3d_cache.cpp:215
wxString m_CacheDir
Definition: 3d_cache.h:181
bool loadCacheData(S3D_CACHE_ENTRY *aCacheItem)
Definition: 3d_cache.cpp:415
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:619
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:509
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:645
SCENEGRAPH * checkCache(const wxString &aFileName, S3D_CACHE_ENTRY **aCachePtr=nullptr)
Find or create cache entry for file name.
Definition: 3d_cache.cpp:292
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:455
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:613
FILENAME_RESOLVER * GetResolver() noexcept
Definition: 3d_cache.cpp:607
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:573
void CleanCacheDir(int aNumDaysOld)
Delete up old cache files in cache directory.
Definition: 3d_cache.cpp:671
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:286
void ClosePlugins()
Unload plugins to free memory.
Definition: 3d_cache.cpp:638
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
static wxString GetUserSettingsPath()
Return the user configuration path used to store KiCad's configuration files.
The base class of all Scene Graph nodes.
Definition: sg_node.h:75
const wxString ExpandEnvVarSubstitutions(const wxString &aString, PROJECT *aProject)
Replace any environment variable & text variable references with their values.
Definition: common.cpp:267
The common library.
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
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:111
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:38