From 8e6bcd85002c5d04ac525ee72a12d81777b3749b Mon Sep 17 00:00:00 2001 From: John Haddon Date: Thu, 31 Mar 2022 16:20:33 +0100 Subject: [PATCH 1/5] USD : Drop support for USD prior to version 20.08 --- .../IECoreUSD/src/IECoreUSD/PointInstancerAlgo.cpp | 4 ---- contrib/IECoreUSD/src/IECoreUSD/PrimitiveAlgo.cpp | 14 +------------- .../src/IECoreUSD/SceneCacheFileFormat.cpp | 4 ---- contrib/IECoreUSD/src/IECoreUSD/USDScene.cpp | 13 ++----------- 4 files changed, 3 insertions(+), 32 deletions(-) diff --git a/contrib/IECoreUSD/src/IECoreUSD/PointInstancerAlgo.cpp b/contrib/IECoreUSD/src/IECoreUSD/PointInstancerAlgo.cpp index d6513d0c12..e866662635 100644 --- a/contrib/IECoreUSD/src/IECoreUSD/PointInstancerAlgo.cpp +++ b/contrib/IECoreUSD/src/IECoreUSD/PointInstancerAlgo.cpp @@ -95,13 +95,11 @@ IECore::ObjectPtr readPointInstancer( pxr::UsdGeomPointInstancer &pointInstancer newPoints->variables["velocity"] = IECoreScene::PrimitiveVariable( IECoreScene::PrimitiveVariable::Vertex, velocityData ); } -#if USD_VERSION >= 1911 if( auto accelerationData = DataAlgo::fromUSD( pointInstancer.GetAccelerationsAttr(), time ) ) { Canceller::check( canceller ); newPoints->variables["acceleration"] = IECoreScene::PrimitiveVariable( IECoreScene::PrimitiveVariable::Vertex, accelerationData ); } -#endif if( auto angularVelocityData = DataAlgo::fromUSD( pointInstancer.GetAngularVelocitiesAttr(), time ) ) { @@ -137,9 +135,7 @@ bool pointInstancerMightBeTimeVarying( pxr::UsdGeomPointInstancer &instancer ) instancer.GetOrientationsAttr().ValueMightBeTimeVarying() || instancer.GetScalesAttr().ValueMightBeTimeVarying() || instancer.GetVelocitiesAttr().ValueMightBeTimeVarying() || -#if USD_VERSION >= 1911 instancer.GetAccelerationsAttr().ValueMightBeTimeVarying() || -#endif instancer.GetAngularVelocitiesAttr().ValueMightBeTimeVarying() ; } diff --git a/contrib/IECoreUSD/src/IECoreUSD/PrimitiveAlgo.cpp b/contrib/IECoreUSD/src/IECoreUSD/PrimitiveAlgo.cpp index 22ebdbd49e..63175e0a5c 100644 --- a/contrib/IECoreUSD/src/IECoreUSD/PrimitiveAlgo.cpp +++ b/contrib/IECoreUSD/src/IECoreUSD/PrimitiveAlgo.cpp @@ -54,12 +54,6 @@ IECORE_PUSH_DEFAULT_VISIBILITY #include "pxr/usd/usdSkel/root.h" IECORE_POP_DEFAULT_VISIBILITY - -/// \todo Use the standard PXR_VERSION instead. We can't do that until -/// everyone is using USD 19.11 though, because prior to that PXR_VERSION -/// was malformed (octal, and not comparable in any way). -#define USD_VERSION ( PXR_MAJOR_VERSION * 10000 + PXR_MINOR_VERSION * 100 + PXR_PATCH_VERSION ) - using namespace std; using namespace pxr; using namespace IECore; @@ -136,12 +130,10 @@ void IECoreUSD::PrimitiveAlgo::writePrimitiveVariable( const std::string &name, { pointBased.CreateVelocitiesAttr().Set( PrimitiveAlgo::toUSDExpanded( value ), time ); } -#if USD_VERSION >= 1911 else if( name == "acceleration" ) { pointBased.CreateAccelerationsAttr().Set( PrimitiveAlgo::toUSDExpanded( value ), time ); } -#endif else { writePrimitiveVariable( name, value, static_cast( pointBased ), time ); @@ -329,7 +321,7 @@ bool readPrimitiveVariables( const pxr::UsdSkelRoot &skelRoot, const pxr::UsdGeo } Canceller::check( canceller ); -#if USD_VERSION < 2011 +#if PXR_VERSION < 2011 ::skelCache()->Populate( skelRoot ); #else ::skelCache()->Populate( skelRoot, pxr::UsdTraverseInstanceProxies() ); @@ -498,12 +490,10 @@ void IECoreUSD::PrimitiveAlgo::readPrimitiveVariables( const pxr::UsdGeomPointBa primitive->variables["velocity"] = IECoreScene::PrimitiveVariable( IECoreScene::PrimitiveVariable::Vertex, v ); } -#if USD_VERSION >= 1911 if( auto a = boost::static_pointer_cast( DataAlgo::fromUSD( pointBased.GetAccelerationsAttr(), time ) ) ) { primitive->variables["acceleration"] = IECoreScene::PrimitiveVariable( IECoreScene::PrimitiveVariable::Vertex, a ); } -#endif } bool IECoreUSD::PrimitiveAlgo::primitiveVariablesMightBeTimeVarying( const pxr::UsdGeomPrimvarsAPI &primvarsAPI ) @@ -524,9 +514,7 @@ bool IECoreUSD::PrimitiveAlgo::primitiveVariablesMightBeTimeVarying( const pxr:: pointBased.GetPointsAttr().ValueMightBeTimeVarying() || pointBased.GetNormalsAttr().ValueMightBeTimeVarying() || pointBased.GetVelocitiesAttr().ValueMightBeTimeVarying() || -#if USD_VERSION >= 1911 pointBased.GetAccelerationsAttr().ValueMightBeTimeVarying() || -#endif primitiveVariablesMightBeTimeVarying( pxr::UsdGeomPrimvarsAPI( pointBased.GetPrim() ) ) || skelAnimMightBeTimeVarying( pointBased.GetPrim() ) ; diff --git a/contrib/IECoreUSD/src/IECoreUSD/SceneCacheFileFormat.cpp b/contrib/IECoreUSD/src/IECoreUSD/SceneCacheFileFormat.cpp index 49feb81c60..76e10720f7 100644 --- a/contrib/IECoreUSD/src/IECoreUSD/SceneCacheFileFormat.cpp +++ b/contrib/IECoreUSD/src/IECoreUSD/SceneCacheFileFormat.cpp @@ -237,11 +237,7 @@ void UsdSceneCacheFileFormat::writeLocation( inChild->path( currentPath ); SdfPath primPath = USDScene::toUSD(currentPath); - #if PXR_VERSION < 2007 - if( primPath.AbsoluteRootPath() != SdfPath( "/" ) ) - #else if( !primPath.IsAbsoluteRootPath() ) - #endif { if( const auto linkedOutScene = runTimeCast( outChild.get() ) ) { diff --git a/contrib/IECoreUSD/src/IECoreUSD/USDScene.cpp b/contrib/IECoreUSD/src/IECoreUSD/USDScene.cpp index e1c2d9ebd6..6f3ad01beb 100644 --- a/contrib/IECoreUSD/src/IECoreUSD/USDScene.cpp +++ b/contrib/IECoreUSD/src/IECoreUSD/USDScene.cpp @@ -84,16 +84,7 @@ using namespace IECore; using namespace IECoreScene; using namespace IECoreUSD; -/// \todo Use the standard PXR_VERSION instead. We can't do that until -/// everyone is using USD 19.11 though, because prior to that PXR_VERSION -/// was malformed (octal, and not comparable in any way). -#define USD_VERSION ( PXR_MAJOR_VERSION * 10000 + PXR_MINOR_VERSION * 100 + PXR_PATCH_VERSION ) - -#if USD_VERSION < 1903 -#define HasAuthoredValue HasAuthoredValueOpinion -#endif - -#if USD_VERSION < 2011 +#if PXR_VERSION < 2011 #define GetPrimInPrototype GetPrimInMaster #endif @@ -204,7 +195,7 @@ void writeSetInternal( const pxr::UsdPrim &prim, const pxr::TfToken &name, const targets.push_back( USDScene::toUSD( *it, /* relative = */ true ) ); } -#if USD_VERSION < 2009 +#if PXR_VERSION < 2009 pxr::UsdCollectionAPI collection = pxr::UsdCollectionAPI::ApplyCollection( prim, validName( name ), pxr::UsdTokens->explicitOnly ); From 9f86796b5010694045ff055931ed4284a8c9dddb Mon Sep 17 00:00:00 2001 From: John Haddon Date: Thu, 31 Mar 2022 15:28:36 +0100 Subject: [PATCH 2/5] USD ShaderAlgo : Refactor shader reading - Simplify `readShaderNetwork()` public interface, and move "does the output have a connection?" logic from USDScene into ShaderAlgo. - Introduce `readShaderNetworkWalk()` overload which takes an output and returns a handle for that output. This removes the repetition of the `DEFAULT_OUTPUT` special case. - Simplify connection handling by building `vector` directly, rather than packing and unpacking a recipe for making a connection. - Remove unused `inputs` variable. - Remove bogus comment - there is no such variable as `handles[0]`. --- .../IECoreUSD/include/IECoreUSD/ShaderAlgo.h | 8 +- .../IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp | 81 ++++++++++--------- contrib/IECoreUSD/src/IECoreUSD/USDScene.cpp | 21 +---- 3 files changed, 46 insertions(+), 64 deletions(-) diff --git a/contrib/IECoreUSD/include/IECoreUSD/ShaderAlgo.h b/contrib/IECoreUSD/include/IECoreUSD/ShaderAlgo.h index 15389c73d7..9415c72f73 100644 --- a/contrib/IECoreUSD/include/IECoreUSD/ShaderAlgo.h +++ b/contrib/IECoreUSD/include/IECoreUSD/ShaderAlgo.h @@ -53,12 +53,8 @@ namespace ShaderAlgo /// Write ShaderNetwork to USD, placing the shaders under the Prim `shaderContainer` IECOREUSD_API pxr::UsdShadeOutput writeShaderNetwork( const IECoreScene::ShaderNetwork *shaderNetwork, pxr::UsdPrim shaderContainer ); -/// Read ShaderNetwork from a USD node ( and its connected inputs ) -/// `anchorPath` is the ancestor path that shaders will be named relative to -/// `outputHandle` specifies which output of the USD node is being used ( the ShaderNetwork must have -/// a corresponding output set ) -IECoreScene::ShaderNetworkPtr readShaderNetwork( const pxr::SdfPath &anchorPath, const pxr::UsdShadeShader &outputShader, const pxr::TfToken &outputHandle ); - +/// Reads a ShaderNetwork from a material output, typically obtained from `UsdShadeMaterial::GetOutput()`. +IECoreScene::ShaderNetworkPtr readShaderNetwork( const pxr::UsdShadeOutput &output ); } // namespace ShaderAlgo diff --git a/contrib/IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp b/contrib/IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp index 9f93f417ec..a68a245187 100644 --- a/contrib/IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp +++ b/contrib/IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp @@ -53,6 +53,8 @@ namespace pxr::TfToken g_adapterLabelToken( IECoreScene::ShaderNetworkAlgo::componentConnectionAdapterLabel().string() ); +IECoreScene::ShaderNetwork::Parameter readShaderNetworkWalk( const pxr::SdfPath &anchorPath, const pxr::UsdShadeOutput &output, IECoreScene::ShaderNetwork &shaderNetwork ); + IECore::InternedString readShaderNetworkWalk( const pxr::SdfPath &anchorPath, const pxr::UsdShadeShader &usdShader, IECoreScene::ShaderNetwork &shaderNetwork ) { IECore::InternedString handle( usdShader.GetPath().MakeRelativePath( anchorPath ).GetString() ); @@ -84,8 +86,7 @@ IECore::InternedString readShaderNetworkWalk( const pxr::SdfPath &anchorPath, co IECore::CompoundDataPtr parametersData = new IECore::CompoundData(); IECore::CompoundDataMap ¶meters = parametersData->writable(); - std::vector< std::tuple< IECore::InternedString, pxr::UsdShadeConnectableAPI, IECore::InternedString > > connections; - std::vector< pxr::UsdShadeInput > inputs = usdShader.GetInputs(); + std::vector connections; for( pxr::UsdShadeInput &i : usdShader.GetInputs() ) { pxr::UsdShadeConnectableAPI usdSource; @@ -95,9 +96,14 @@ IECore::InternedString readShaderNetworkWalk( const pxr::SdfPath &anchorPath, co pxr::UsdAttribute valueAttribute = i; if( i.GetConnectedSource( &usdSource, &usdSourceName, &usdSourceType ) ) { - if( !usdSource.IsContainer() ) + if( usdSourceType == pxr::UsdShadeAttributeType::Output ) { - connections.push_back( { i.GetBaseName().GetString(), usdSource, usdSourceName.GetString() } ); + const IECoreScene::ShaderNetwork::Parameter sourceHandle = readShaderNetworkWalk( + anchorPath, usdSource.GetOutput( usdSourceName ), shaderNetwork + ); + connections.push_back( { + sourceHandle, { handle, IECore::InternedString( i.GetBaseName().GetString() ) } + } ); } else { @@ -124,33 +130,28 @@ IECore::InternedString readShaderNetworkWalk( const pxr::SdfPath &anchorPath, co } shaderNetwork.addShader( handle, std::move( newShader ) ); + // Can only add connections after we've added the shader. for( const auto &c : connections ) { - IECore::InternedString attributeName; - pxr::UsdShadeConnectableAPI usdSource; - IECore::InternedString sourceAttributeName; - std::tie( attributeName, usdSource, sourceAttributeName ) = c; - IECore::InternedString sourceHandle = readShaderNetworkWalk( anchorPath, pxr::UsdShadeShader( usdSource.GetPrim() ), shaderNetwork ); - - if( sourceAttributeName == "DEFAULT_OUTPUT" ) - { - shaderNetwork.addConnection( IECoreScene::ShaderNetwork::Connection( - { sourceHandle, "" }, - { handle, attributeName } - ) ); - } - else - { - shaderNetwork.addConnection( IECoreScene::ShaderNetwork::Connection( - { sourceHandle, sourceAttributeName }, - { handle, attributeName } - ) ); - } + shaderNetwork.addConnection( c ); } return handle; } +IECoreScene::ShaderNetwork::Parameter readShaderNetworkWalk( const pxr::SdfPath &anchorPath, const pxr::UsdShadeOutput &output, IECoreScene::ShaderNetwork &shaderNetwork ) +{ + IECore::InternedString shaderHandle = readShaderNetworkWalk( anchorPath, pxr::UsdShadeShader( output.GetPrim() ), shaderNetwork ); + if( output.GetBaseName() != "DEFAULT_OUTPUT" ) + { + return IECoreScene::ShaderNetwork::Parameter( shaderHandle, output.GetBaseName().GetString() ); + } + else + { + return IECoreScene::ShaderNetwork::Parameter( shaderHandle ); + } +} + } // namespace pxr::UsdShadeOutput IECoreUSD::ShaderAlgo::writeShaderNetwork( const IECoreScene::ShaderNetwork *shaderNetwork, pxr::UsdPrim shaderContainer ) @@ -249,10 +250,21 @@ pxr::UsdShadeOutput IECoreUSD::ShaderAlgo::writeShaderNetwork( const IECoreScene return networkOutUsd; } -IECoreScene::ShaderNetworkPtr IECoreUSD::ShaderAlgo::readShaderNetwork( const pxr::SdfPath &anchorPath, const pxr::UsdShadeShader &outputShader, const pxr::TfToken &outputParameter ) +IECoreScene::ShaderNetworkPtr IECoreUSD::ShaderAlgo::readShaderNetwork( const pxr::UsdShadeOutput &output ) { + pxr::UsdShadeConnectableAPI usdSource; + pxr::TfToken usdSourceName; + pxr::UsdShadeAttributeType usdSourceType; + if( + !output.GetConnectedSource( &usdSource, &usdSourceName, &usdSourceType ) || + usdSourceType != pxr::UsdShadeAttributeType::Output + ) + { + return new IECoreScene::ShaderNetwork(); + } + IECoreScene::ShaderNetworkPtr result = new IECoreScene::ShaderNetwork(); - IECore::InternedString outputHandle = readShaderNetworkWalk( anchorPath, outputShader, *result ); + IECoreScene::ShaderNetwork::Parameter outputHandle = readShaderNetworkWalk( usdSource.GetPrim().GetParent().GetPath(), usdSource.GetOutput( usdSourceName ), *result ); // For the output shader, set the type to "ai:surface" if it is "ai:shader". // This is complete nonsense - there is nothing to suggest that this shader is @@ -265,22 +277,15 @@ IECoreScene::ShaderNetworkPtr IECoreUSD::ShaderAlgo::readShaderNetwork( const px // don't use the suffix of the shader type for anything, and we should just set // everything to prefix:shader ( aside from lights, which are a bit of a // different question ) - if( result->getShader( outputHandle )->getType() == "ai:shader" ) + const IECoreScene::Shader *outputShader = result->getShader( outputHandle.shader ); + if( outputShader->getType() == "ai:shader" ) { - IECoreScene::ShaderPtr o = result->getShader( outputHandle )->copy(); + IECoreScene::ShaderPtr o = outputShader->copy(); o->setType( "ai:surface" ); - result->setShader( outputHandle, std::move( o ) ); + result->setShader( outputHandle.shader, std::move( o ) ); } - // handles[0] is the handle of the first shader added, which is always the output shader - if( outputParameter.GetString() != "DEFAULT_OUTPUT" ) - { - result->setOutput( IECoreScene::ShaderNetwork::Parameter( outputHandle, outputParameter.GetString() ) ); - } - else - { - result->setOutput( IECoreScene::ShaderNetwork::Parameter( outputHandle ) ); - } + result->setOutput( outputHandle ); IECoreScene::ShaderNetworkAlgo::removeComponentConnectionAdapters( result.get() ); diff --git a/contrib/IECoreUSD/src/IECoreUSD/USDScene.cpp b/contrib/IECoreUSD/src/IECoreUSD/USDScene.cpp index 6f3ad01beb..b3931ddf2f 100644 --- a/contrib/IECoreUSD/src/IECoreUSD/USDScene.cpp +++ b/contrib/IECoreUSD/src/IECoreUSD/USDScene.cpp @@ -415,26 +415,7 @@ class ShaderNetworkCache : public LRUCacheObject::memoryUsage(); return result; } From 66814534872956052c4a2886c1afebb6822ca85a Mon Sep 17 00:00:00 2001 From: John Haddon Date: Mon, 28 Mar 2022 14:40:10 +0100 Subject: [PATCH 3/5] USDScene : Add basic support for reading lights We only support this for USD 21.11 and greater, because that version introduces UsdLuxLightAPI which lets us load lights using the same UsdShadeConnectable API that we use for materials. At this point we're making no attempt to conform the lights to Gaffer's conventions for Arnold (or any other renderer), so in the short term this is mostly useful for "data smithing" - converting stuff manually after loading. An upcoming ShaderQuery node in Gaffer should provide a useful tool for doing that. --- SConstruct | 1 + .../IECoreUSD/include/IECoreUSD/ShaderAlgo.h | 7 +++ .../IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp | 38 +++++++++++-- contrib/IECoreUSD/src/IECoreUSD/USDScene.cpp | 40 ++++++++++++++ .../IECoreUSD/test/IECoreUSD/USDSceneTest.py | 54 +++++++++++++++++-- 5 files changed, 133 insertions(+), 7 deletions(-) diff --git a/SConstruct b/SConstruct index bcbccd2a62..eac574c050 100644 --- a/SConstruct +++ b/SConstruct @@ -2996,6 +2996,7 @@ else : usdLibs = [ "usd", "usdGeom", + "usdLux", "usdSkel", "usdShade", "sdf", diff --git a/contrib/IECoreUSD/include/IECoreUSD/ShaderAlgo.h b/contrib/IECoreUSD/include/IECoreUSD/ShaderAlgo.h index 9415c72f73..036a90d52f 100644 --- a/contrib/IECoreUSD/include/IECoreUSD/ShaderAlgo.h +++ b/contrib/IECoreUSD/include/IECoreUSD/ShaderAlgo.h @@ -42,6 +42,9 @@ IECORE_PUSH_DEFAULT_VISIBILITY #include "pxr/usd/usdShade/material.h" #include "pxr/usd/usdShade/output.h" +#if PXR_VERSION >= 2111 +#include "pxr/usd/usdLux/lightAPI.h" +#endif IECORE_POP_DEFAULT_VISIBILITY namespace IECoreUSD @@ -56,6 +59,10 @@ IECOREUSD_API pxr::UsdShadeOutput writeShaderNetwork( const IECoreScene::ShaderN /// Reads a ShaderNetwork from a material output, typically obtained from `UsdShadeMaterial::GetOutput()`. IECoreScene::ShaderNetworkPtr readShaderNetwork( const pxr::UsdShadeOutput &output ); +#if PXR_VERSION >= 2111 +/// Reads a ShaderNetwork from a light. +IECoreScene::ShaderNetworkPtr readShaderNetwork( const pxr::UsdLuxLightAPI &light ); +#endif } // namespace ShaderAlgo diff --git a/contrib/IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp b/contrib/IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp index a68a245187..1b727cff93 100644 --- a/contrib/IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp +++ b/contrib/IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp @@ -53,9 +53,26 @@ namespace pxr::TfToken g_adapterLabelToken( IECoreScene::ShaderNetworkAlgo::componentConnectionAdapterLabel().string() ); +pxr::TfToken shaderId( const pxr::UsdShadeConnectableAPI &connectable ) +{ + pxr::TfToken result; + if( auto shader = pxr::UsdShadeShader( connectable ) ) + { + shader.GetShaderId( &result ); + } +#if PXR_VERSION >= 2111 + else if( auto light = pxr::UsdLuxLightAPI( connectable ) ) + { + light.GetShaderIdAttr().Get( &result ); + } +#endif + + return result; +} + IECoreScene::ShaderNetwork::Parameter readShaderNetworkWalk( const pxr::SdfPath &anchorPath, const pxr::UsdShadeOutput &output, IECoreScene::ShaderNetwork &shaderNetwork ); -IECore::InternedString readShaderNetworkWalk( const pxr::SdfPath &anchorPath, const pxr::UsdShadeShader &usdShader, IECoreScene::ShaderNetwork &shaderNetwork ) +IECore::InternedString readShaderNetworkWalk( const pxr::SdfPath &anchorPath, const pxr::UsdShadeConnectableAPI &usdShader, IECoreScene::ShaderNetwork &shaderNetwork ) { IECore::InternedString handle( usdShader.GetPath().MakeRelativePath( anchorPath ).GetString() ); @@ -64,10 +81,10 @@ IECore::InternedString readShaderNetworkWalk( const pxr::SdfPath &anchorPath, co return handle; } - pxr::TfToken id; + const pxr::TfToken id = shaderId( usdShader ); std::string shaderName = "defaultsurface"; std::string shaderType = "surface"; - if( usdShader.GetShaderId( &id ) ) + if( id.size() ) { std::string name = id.GetString(); size_t colonPos = name.find( ":" ); @@ -141,7 +158,7 @@ IECore::InternedString readShaderNetworkWalk( const pxr::SdfPath &anchorPath, co IECoreScene::ShaderNetwork::Parameter readShaderNetworkWalk( const pxr::SdfPath &anchorPath, const pxr::UsdShadeOutput &output, IECoreScene::ShaderNetwork &shaderNetwork ) { - IECore::InternedString shaderHandle = readShaderNetworkWalk( anchorPath, pxr::UsdShadeShader( output.GetPrim() ), shaderNetwork ); + IECore::InternedString shaderHandle = readShaderNetworkWalk( anchorPath, pxr::UsdShadeConnectableAPI( output.GetPrim() ), shaderNetwork ); if( output.GetBaseName() != "DEFAULT_OUTPUT" ) { return IECoreScene::ShaderNetwork::Parameter( shaderHandle, output.GetBaseName().GetString() ); @@ -291,3 +308,16 @@ IECoreScene::ShaderNetworkPtr IECoreUSD::ShaderAlgo::readShaderNetwork( const px return result; } + +#if PXR_VERSION >= 2111 + +IECoreScene::ShaderNetworkPtr IECoreUSD::ShaderAlgo::readShaderNetwork( const pxr::UsdLuxLightAPI &light ) +{ + IECoreScene::ShaderNetworkPtr result = new IECoreScene::ShaderNetwork(); + IECoreScene::ShaderNetwork::Parameter lightHandle = readShaderNetworkWalk( light.GetPath().GetParentPath(), pxr::UsdShadeConnectableAPI( light ), *result ); + result->setOutput( lightHandle ); + IECoreScene::ShaderNetworkAlgo::removeComponentConnectionAdapters( result.get() ); + return result; +} + +#endif diff --git a/contrib/IECoreUSD/src/IECoreUSD/USDScene.cpp b/contrib/IECoreUSD/src/IECoreUSD/USDScene.cpp index b3931ddf2f..4c771f84cc 100644 --- a/contrib/IECoreUSD/src/IECoreUSD/USDScene.cpp +++ b/contrib/IECoreUSD/src/IECoreUSD/USDScene.cpp @@ -63,6 +63,9 @@ IECORE_PUSH_DEFAULT_VISIBILITY #include "pxr/usd/usdGeom/scope.h" #include "pxr/usd/usdGeom/tokens.h" #include "pxr/usd/usdGeom/xform.h" +#if PXR_VERSION >= 2111 +#include "pxr/usd/usdLux/lightAPI.h" +#endif #include "pxr/usd/usdShade/material.h" #include "pxr/usd/usdShade/materialBindingAPI.h" #include "pxr/usd/usdShade/connectableAPI.h" @@ -223,8 +226,25 @@ IECore::PathMatcher readSchemaTypeSet( const pxr::UsdPrim &prim ) return result; } +template +IECore::PathMatcher readAPISchemaSet( const pxr::UsdPrim &prim ) +{ + IECore::PathMatcher result; + for( const auto &descendant : prim.GetDescendants() ) + { + if( descendant.HasAPI() ) + { + result.addPath( USDScene::fromUSD( descendant.GetPath() ) ); + } + } + return result; +} + boost::container::flat_map g_schemaTypeSetReaders = { { "__cameras", readSchemaTypeSet }, +#if PXR_VERSION >= 2111 + { "__lights", readAPISchemaSet }, +#endif { "usd:pointInstancers", readSchemaTypeSet } }; @@ -775,6 +795,7 @@ namespace const IECore::InternedString g_purposeAttributeName( "usd:purpose" ); const IECore::InternedString g_kindAttributeName( "usd:kind" ); +const IECore::InternedString g_lightAttributeName( "light" ); } // namespace @@ -800,6 +821,12 @@ bool USDScene::hasAttribute( const SceneInterface::Name &name ) const pxr::TfToken kind; return model.GetKind( &kind ); } +#if PXR_VERSION >= 2111 + else if( name == g_lightAttributeName ) + { + return m_location->prim.HasAPI(); + } +#endif else if( auto attribute = AttributeAlgo::findUSDAttribute( m_location->prim, name.string() ) ) { return attribute.HasAuthoredValue(); @@ -848,6 +875,13 @@ void USDScene::attributeNames( SceneInterface::NameList &attrs ) const attrs.push_back( g_kindAttributeName ); } +#if PXR_VERSION >= 2111 + if( m_location->prim.HasAPI() ) + { + attrs.push_back( g_lightAttributeName ); + } +#endif + std::vector attributes = m_location->prim.GetAuthoredAttributes(); for( const auto &attribute : attributes ) { @@ -924,6 +958,12 @@ ConstObjectPtr USDScene::readAttribute( const SceneInterface::Name &name, double pxr::TfToken value; attr.Get( &value ); return new StringData( value.GetString() ); } +#if PXR_VERSION >= 2111 + else if( name == g_lightAttributeName ) + { + return ShaderAlgo::readShaderNetwork( pxr::UsdLuxLightAPI( m_location->prim ) ); + } +#endif else if( name == g_kindAttributeName ) { pxr::TfToken kind; diff --git a/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py b/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py index dfb2448f99..6d5d3de58d 100644 --- a/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py +++ b/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py @@ -1890,6 +1890,13 @@ def testCanReferenceTags( self ) : grandChild = child.child( "grandChild" ) self.assertSetNamesEqual( grandChild.readTags(), [ "tagB", "tagC" ] ) + def __expectedLightSets( self ) : + + if pxr.Usd.GetVersion() >= ( 0, 21, 11 ) : + return [ "__lights" ] + else : + return [] + def testTagSetEquivalence( self ) : # Location Tags Sets @@ -1955,7 +1962,7 @@ def checkHasTag( scene ) : self.assertSetNamesEqual( root.readTags( root.AncestorTag ), [] ) self.assertSetNamesEqual( root.readTags( root.LocalTag ), [] ) - self.assertSetNamesEqual( root.readTags( root.DescendantTag ), allTags + [ "__cameras", "usd:pointInstancers" ] ) + self.assertSetNamesEqual( root.readTags( root.DescendantTag ), allTags + [ "__cameras", "usd:pointInstancers" ] + self.__expectedLightSets() ) checkHasTag( root ) a = root.child( "a" ) @@ -2003,7 +2010,7 @@ def testSchemaTypeSetsAndTags( self ) : instancerGroup = group.child( "instancerGroup" ) instancer = instancerGroup.child( "instancer" ) - self.assertSetNamesEqual( root.setNames(), [ "__cameras", "usd:pointInstancers" ] ) + self.assertSetNamesEqual( root.setNames(), [ "__cameras", "usd:pointInstancers" ] + self.__expectedLightSets() ) self.assertSetNamesEqual( group.setNames(), [] ) self.assertSetNamesEqual( camera.setNames(), [] ) self.assertSetNamesEqual( instancerGroup.setNames(), [] ) @@ -2025,7 +2032,7 @@ def testSchemaTypeSetsAndTags( self ) : self.assertSetNamesEqual( root.readTags( root.AncestorTag ), [] ) self.assertSetNamesEqual( root.readTags( root.LocalTag ), [] ) - self.assertSetNamesEqual( root.readTags( root.DescendantTag ), [ "__cameras", "usd:pointInstancers" ] ) + self.assertSetNamesEqual( root.readTags( root.DescendantTag ), [ "__cameras", "usd:pointInstancers" ] + self.__expectedLightSets() ) self.assertSetNamesEqual( group.readTags( root.AncestorTag ), [] ) self.assertSetNamesEqual( group.readTags( root.LocalTag ), [] ) @@ -2967,5 +2974,46 @@ def testExposedShaderInput( self ) : self.assertEqual( network.getOutput(), "surface" ) self.assertEqual( network.getShader( "surface" ).parameters["diffuse_roughness"].value, 0.75 ) + @unittest.skipIf( pxr.Usd.GetVersion() < ( 0, 21, 11 ), "UsdLuxLightAPI not available" ) + def testLightsSet( self ) : + + scene = IECoreScene.SceneInterface.create( + os.path.join( os.path.dirname( __file__ ), "data", "sphereLight.usda" ), + IECore.IndexedIO.OpenMode.Read + ) + + self.assertIn( "__lights", scene.setNames() ) + self.assertEqual( scene.readSet( "__lights" ), IECore.PathMatcher( [ "/SpotLight23" ] ) ) + + @unittest.skipIf( pxr.Usd.GetVersion() < ( 0, 21, 11 ), "UsdLuxLightAPI not available" ) + def testLightAttribute( self ) : + + scene = IECoreScene.SceneInterface.create( + os.path.join( os.path.dirname( __file__ ), "data", "sphereLight.usda" ), + IECore.IndexedIO.OpenMode.Read + ) + light = scene.child( "SpotLight23" ) + self.assertIn( "light", light.attributeNames() ) + self.assertTrue( light.hasAttribute( "light" ) ) + + shader = light.readAttribute( "light", 0 ) + self.assertIsInstance( shader, IECoreScene.ShaderNetwork ) + self.assertEqual( shader.size(), 1 ) + self.assertEqual( shader.getOutput(), "SpotLight23" ) + + self.assertEqual( + shader.getShader( "SpotLight23" ).parameters, + IECore.CompoundData( { + "color" : imath.Color3f( 1, 1, 1 ), + "colorTemperature" : 6500.0, + "enableColorTemperature" : False, + "exposure" : 0.0, + "intensity" : 30000.0, + "radius" : 0.0, + "shaping:cone:angle" : 66.0, + "shaping:cone:softness" : 1.0 + } ) + ) + if __name__ == "__main__": unittest.main() From 798e7af80f1eb1d6f73a7bdf27f12dd0b22bd248 Mon Sep 17 00:00:00 2001 From: John Haddon Date: Tue, 19 Apr 2022 11:24:53 +0100 Subject: [PATCH 4/5] USDScene : Improve naming of set reading functions --- contrib/IECoreUSD/src/IECoreUSD/USDScene.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/contrib/IECoreUSD/src/IECoreUSD/USDScene.cpp b/contrib/IECoreUSD/src/IECoreUSD/USDScene.cpp index 4c771f84cc..5e902821dc 100644 --- a/contrib/IECoreUSD/src/IECoreUSD/USDScene.cpp +++ b/contrib/IECoreUSD/src/IECoreUSD/USDScene.cpp @@ -213,7 +213,7 @@ void writeSetInternal( const pxr::UsdPrim &prim, const pxr::TfToken &name, const } template -IECore::PathMatcher readSchemaTypeSet( const pxr::UsdPrim &prim ) +IECore::PathMatcher descendantsWithType( const pxr::UsdPrim &prim ) { IECore::PathMatcher result; for( const auto &descendant : prim.GetDescendants() ) @@ -226,13 +226,13 @@ IECore::PathMatcher readSchemaTypeSet( const pxr::UsdPrim &prim ) return result; } -template -IECore::PathMatcher readAPISchemaSet( const pxr::UsdPrim &prim ) +template +IECore::PathMatcher descendantsWithAPI( const pxr::UsdPrim &prim ) { IECore::PathMatcher result; for( const auto &descendant : prim.GetDescendants() ) { - if( descendant.HasAPI() ) + if( descendant.HasAPI() ) { result.addPath( USDScene::fromUSD( descendant.GetPath() ) ); } @@ -241,11 +241,11 @@ IECore::PathMatcher readAPISchemaSet( const pxr::UsdPrim &prim ) } boost::container::flat_map g_schemaTypeSetReaders = { - { "__cameras", readSchemaTypeSet }, + { "__cameras", descendantsWithType }, #if PXR_VERSION >= 2111 - { "__lights", readAPISchemaSet }, + { "__lights", descendantsWithAPI }, #endif - { "usd:pointInstancers", readSchemaTypeSet } + { "usd:pointInstancers", descendantsWithType } }; IECore::PathMatcher readSetInternal( const pxr::UsdPrim &prim, const pxr::TfToken &name, bool includeDescendantSets, const Canceller *canceller ) From 5d233baa639e50b9b139391f6e128620a0ab5db3 Mon Sep 17 00:00:00 2001 From: John Haddon Date: Thu, 21 Apr 2022 09:20:12 +0100 Subject: [PATCH 5/5] USDSceneTest test : Add missing test file --- .../test/IECoreUSD/data/sphereLight.usda | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 contrib/IECoreUSD/test/IECoreUSD/data/sphereLight.usda diff --git a/contrib/IECoreUSD/test/IECoreUSD/data/sphereLight.usda b/contrib/IECoreUSD/test/IECoreUSD/data/sphereLight.usda new file mode 100644 index 0000000000..c31f421ee1 --- /dev/null +++ b/contrib/IECoreUSD/test/IECoreUSD/data/sphereLight.usda @@ -0,0 +1,19 @@ +#usda 1.0 + +def SphereLight "SpotLight23" ( + apiSchemas = ["ShapingAPI"] +) +{ + color3f inputs:color = (1, 1, 1) + float inputs:colorTemperature = 6500 + bool inputs:enableColorTemperature = 0 + float inputs:exposure = 0 + float inputs:intensity = 30000 + float inputs:radius = 0 + float inputs:shaping:cone:angle = 66 + float inputs:shaping:cone:softness = 1 + bool treatAsPoint = 1 + token visibility = "inherited" + matrix4d xformOp:transform = ( (0.9672808051109314, -0.21715188026428223, 0.1311977356672287, 0), (-0.05085674673318863, 0.3406679034233093, 0.9388070106506348, 0), (-0.24855859577655792, -0.9147622585296631, 0.3184778690338135, 0), (20949.08203125, 2227.8759765625, 528.5748901367188, 1) ) + uniform token[] xformOpOrder = ["xformOp:transform"] +}