Skip to content

Commit 19d65af

Browse files
committed
Merge branch 'RB-10.3' into main
2 parents df5c687 + 31f8216 commit 19d65af

File tree

2 files changed

+95
-39
lines changed

2 files changed

+95
-39
lines changed

contrib/IECoreUSD/src/IECoreUSD/USDScene.cpp

Lines changed: 91 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141

4242
#include "IECoreScene/ShaderNetwork.h"
4343

44+
#include "IECore/LRUCache.h"
4445
#include "IECore/MessageHandler.h"
4546
#include "IECore/SimpleTypedData.h"
4647
#include "IECore/VectorTypedData.h"
@@ -393,6 +394,62 @@ void populateMaterial( pxr::UsdShadeMaterial &mat, const std::map< const Interne
393394
}
394395
}
395396

397+
/// SdfPath is the appropriate cache key for _storage_, but we need a
398+
/// `UsdShadeOutput` for computation. This struct provides the implicit
399+
/// conversion that LRUCache needs to make that possible.
400+
struct ShaderNetworkCacheGetterKey : public pxr::UsdShadeOutput
401+
{
402+
ShaderNetworkCacheGetterKey( const pxr::UsdShadeOutput &output )
403+
: pxr::UsdShadeOutput( output )
404+
{
405+
}
406+
407+
operator pxr::SdfPath () const
408+
{
409+
return GetAttr().GetPath();
410+
}
411+
};
412+
413+
class ShaderNetworkCache : public LRUCache<pxr::SdfPath, IECoreScene::ConstShaderNetworkPtr, LRUCachePolicy::Parallel, ShaderNetworkCacheGetterKey>
414+
{
415+
416+
public :
417+
418+
ShaderNetworkCache( size_t maxBytes )
419+
: LRUCache<pxr::SdfPath, IECoreScene::ConstShaderNetworkPtr, LRUCachePolicy::Parallel, ShaderNetworkCacheGetterKey>( getter, maxBytes )
420+
{
421+
}
422+
423+
private :
424+
425+
static IECoreScene::ConstShaderNetworkPtr getter( const ShaderNetworkCacheGetterKey &key, size_t &cost )
426+
{
427+
IECoreScene::ConstShaderNetworkPtr result;
428+
429+
/// \todo I'm pretty sure that the `readShaderNetwork()` signature is overly complex,
430+
/// and it should just be passed a single `UsdShadeOutput &` like this function.
431+
/// I suspect that `writeShaderNetwork()` could take a single `UsdShadeOutput &` too,
432+
/// for symmetry between the two functions.
433+
434+
pxr::UsdShadeConnectableAPI source;
435+
pxr::TfToken sourceName;
436+
pxr::UsdShadeAttributeType sourceType;
437+
if( key.GetConnectedSource( &source, &sourceName, &sourceType ) )
438+
{
439+
pxr::UsdShadeShader s( source.GetPrim() );
440+
result = ShaderAlgo::readShaderNetwork( source.GetPrim().GetParent().GetPath(), s, sourceName );
441+
}
442+
else
443+
{
444+
result = new IECoreScene::ShaderNetwork();
445+
}
446+
447+
cost = result->Object::memoryUsage();
448+
return result;
449+
}
450+
451+
};
452+
396453
} // namespace
397454

398455
class USDScene::Location : public RefCounted
@@ -408,31 +465,16 @@ class USDScene::IO : public RefCounted
408465
public :
409466

410467
IO( const std::string &fileName, IndexedIO::OpenMode openMode )
411-
: m_fileName( fileName ), m_openMode( openMode )
468+
: IO( fileName, makeStage( fileName, openMode ), openMode )
412469
{
413-
switch( m_openMode )
414-
{
415-
case IndexedIO::Read :
416-
m_stage = pxr::UsdStage::Open( fileName );
417-
if( !m_stage )
418-
{
419-
throw IECore::Exception( boost::str( boost::format( "USDScene : Failed to open USD file: '%1%'" ) % fileName ) );
420-
}
421-
break;
422-
case IndexedIO::Write :
423-
m_stage = pxr::UsdStage::CreateNew( fileName );
424-
break;
425-
default:
426-
throw Exception( "Unsupported OpenMode" );
427-
}
428-
429-
initStage();
430470
}
431471

432-
IO( const pxr::UsdStageRefPtr &stage, IndexedIO::OpenMode openMode )
433-
: m_fileName( "" ), m_openMode( openMode ), m_stage( stage )
472+
IO( const std::string &fileName, const pxr::UsdStageRefPtr &stage, IndexedIO::OpenMode openMode )
473+
: m_fileName( fileName ), m_openMode( openMode ), m_stage( stage ),
474+
m_rootPrim( m_stage->GetPseudoRoot() ),
475+
m_timeCodesPerSecond( m_stage->GetTimeCodesPerSecond() ),
476+
m_shaderNetworkCache( 10 * 1024 * 1024 ) // 10Mb
434477
{
435-
initStage();
436478
}
437479

438480
~IO() override
@@ -447,12 +489,6 @@ class USDScene::IO : public RefCounted
447489
}
448490
}
449491

450-
void initStage()
451-
{
452-
m_timeCodesPerSecond = m_stage->GetTimeCodesPerSecond();
453-
m_rootPrim = m_stage->GetPseudoRoot();
454-
}
455-
456492
const std::string &fileName() const
457493
{
458494
return m_fileName;
@@ -515,8 +551,32 @@ class USDScene::IO : public RefCounted
515551
);
516552
}
517553

554+
IECoreScene::ConstShaderNetworkPtr readShaderNetwork( const pxr::UsdShadeOutput &output )
555+
{
556+
return m_shaderNetworkCache.get( output );
557+
}
558+
518559
private :
519560

561+
static pxr::UsdStageRefPtr makeStage( const std::string &fileName, IndexedIO::OpenMode openMode )
562+
{
563+
switch( openMode )
564+
{
565+
case IndexedIO::Read : {
566+
pxr::UsdStageRefPtr stage = pxr::UsdStage::Open( fileName );
567+
if( !stage )
568+
{
569+
throw IECore::Exception( boost::str( boost::format( "USDScene : Failed to open USD file: '%1%'" ) % fileName ) );
570+
}
571+
return stage;
572+
}
573+
case IndexedIO::Write :
574+
return pxr::UsdStage::CreateNew( fileName );
575+
default:
576+
throw Exception( "Unsupported OpenMode" );
577+
}
578+
}
579+
520580
std::string m_fileName;
521581
IndexedIO::OpenMode m_openMode;
522582
pxr::UsdStageRefPtr m_stage;
@@ -529,6 +589,8 @@ class USDScene::IO : public RefCounted
529589
pxr::UsdShadeMaterialBindingAPI::BindingsCache m_usdBindingsCache;
530590
pxr::UsdShadeMaterialBindingAPI::CollectionQueryCache m_usdCollectionQueryCache;
531591

592+
ShaderNetworkCache m_shaderNetworkCache;
593+
532594
};
533595

534596
USDScene::USDScene( const std::string &fileName, IndexedIO::OpenMode openMode )
@@ -538,7 +600,7 @@ USDScene::USDScene( const std::string &fileName, IndexedIO::OpenMode openMode )
538600
}
539601

540602
USDScene::USDScene( const pxr::UsdStageRefPtr &stage, IndexedIO::OpenMode openMode )
541-
: m_root( new IO( stage, openMode ) ),
603+
: m_root( new IO( "", stage, openMode ) ),
542604
m_location( new Location( m_root->root() ) )
543605
{
544606
}
@@ -917,17 +979,7 @@ ConstObjectPtr USDScene::readAttribute( const SceneInterface::Name &name, double
917979
pxr::UsdShadeOutput o = mat.GetOutput( n );
918980
if( o && pxr::UsdAttribute( o ).IsAuthored() )
919981
{
920-
{
921-
pxr::UsdShadeConnectableAPI source;
922-
pxr::TfToken sourceName;
923-
pxr::UsdShadeAttributeType sourceType;
924-
if( o.GetConnectedSource( &source, &sourceName, &sourceType ) )
925-
{
926-
pxr::UsdShadeShader s( source.GetPrim() );
927-
return ShaderAlgo::readShaderNetwork( source.GetPrim().GetParent().GetPath(), s, sourceName );
928-
}
929-
}
930-
return new IECoreScene::ShaderNetwork();
982+
return m_root->readShaderNetwork( o );
931983
}
932984
}
933985
}

contrib/IECoreUSD/src/IECoreUSD/USDScene.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@
4242

4343
#include "IECore/PathMatcherData.h"
4444

45+
// Included here to avoid it being included indirectly via `stage.h`, inside the
46+
// scope of IECORE_PUSH_DEFAULT_VISIBILITY.
47+
#include "boost/function/function_base.hpp"
48+
4549
IECORE_PUSH_DEFAULT_VISIBILITY
4650
#include "pxr/usd/usd/stage.h"
4751
IECORE_POP_DEFAULT_VISIBILITY

0 commit comments

Comments
 (0)