From 9afe1de9d3f7e1ebaf59d2488909574ed27ddc9b Mon Sep 17 00:00:00 2001 From: John Haddon Date: Thu, 14 Jul 2022 12:56:24 +0100 Subject: [PATCH 1/2] USDScene : Load `treatAsPoint` and `treatAsLine` for UsdLuxLights --- .../IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp | 27 +++++++++++++++++++ .../IECoreUSD/test/IECoreUSD/USDSceneTest.py | 1 + 2 files changed, 28 insertions(+) diff --git a/contrib/IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp b/contrib/IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp index 1b727cff93..90ef73a9df 100644 --- a/contrib/IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp +++ b/contrib/IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp @@ -41,6 +41,11 @@ #include "IECore/MessageHandler.h" #include "IECore/SimpleTypedData.h" +#if PXR_VERSION >= 2111 +#include "pxr/usd/usdLux/cylinderLight.h" +#include "pxr/usd/usdLux/sphereLight.h" +#endif + #include "boost/algorithm/string/replace.hpp" #include "boost/pointer_cast.hpp" @@ -70,6 +75,26 @@ pxr::TfToken shaderId( const pxr::UsdShadeConnectableAPI &connectable ) return result; } +void readAdditionalLightParameters( const pxr::UsdPrim &prim, IECore::CompoundDataMap ¶meters ) +{ + // Just to keep us on our toes, not all light parameters are stored as UsdShade inputs, + // so we have special-case code for loading those here. +#if PXR_VERSION >= 2111 + if( auto sphereLight = pxr::UsdLuxSphereLight( prim ) ) + { + bool treatAsPoint = false; + sphereLight.GetTreatAsPointAttr().Get( &treatAsPoint ); + parameters["treatAsPoint"] = new IECore::BoolData( treatAsPoint ); + } + else if( auto cylinderLight = pxr::UsdLuxCylinderLight( prim ) ) + { + bool treatAsLine = false; + cylinderLight.GetTreatAsLineAttr().Get( &treatAsLine ); + parameters["treatAsLine"] = new IECore::BoolData( treatAsLine ); + } +#endif +} + IECoreScene::ShaderNetwork::Parameter readShaderNetworkWalk( const pxr::SdfPath &anchorPath, const pxr::UsdShadeOutput &output, IECoreScene::ShaderNetwork &shaderNetwork ); IECore::InternedString readShaderNetworkWalk( const pxr::SdfPath &anchorPath, const pxr::UsdShadeConnectableAPI &usdShader, IECoreScene::ShaderNetwork &shaderNetwork ) @@ -137,6 +162,8 @@ IECore::InternedString readShaderNetworkWalk( const pxr::SdfPath &anchorPath, co } } + readAdditionalLightParameters( usdShader.GetPrim(), parameters ); + parametersData = boost::const_pointer_cast< IECore::CompoundData >( IECoreScene::ShaderNetworkAlgo::collapseSplineParameters( parametersData ) ); IECoreScene::ShaderPtr newShader = new IECoreScene::Shader( shaderName, shaderType, parametersData ); diff --git a/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py b/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py index d6b805f1ec..86f1a8d677 100644 --- a/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py +++ b/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py @@ -3031,6 +3031,7 @@ def testLightAttribute( self ) : "exposure" : 0.0, "intensity" : 30000.0, "radius" : 0.0, + "treatAsPoint" : True, "shaping:cone:angle" : 66.0, "shaping:cone:softness" : 1.0 } ) From be838696e5d16f7718792c3250b06356120a1f3f Mon Sep 17 00:00:00 2001 From: John Haddon Date: Fri, 15 Jul 2022 11:32:10 +0100 Subject: [PATCH 2/2] USD ShaderAlgo : Ensure lights load with `light` shader type Although we are generally trying to follow OSL's lead and treat shader type as irrelevant, we still have a few dependencies on it. One is in Gaffer's StandardLightVisualiser, where it is used to look up the metadata used to visualise a light, so it's worth getting this right. --- contrib/IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp | 16 +++++++++------- contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py | 3 +++ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/contrib/IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp b/contrib/IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp index 90ef73a9df..112b9b7b57 100644 --- a/contrib/IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp +++ b/contrib/IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp @@ -58,21 +58,24 @@ namespace pxr::TfToken g_adapterLabelToken( IECoreScene::ShaderNetworkAlgo::componentConnectionAdapterLabel().string() ); -pxr::TfToken shaderId( const pxr::UsdShadeConnectableAPI &connectable ) +std::pair shaderIdAndType( const pxr::UsdShadeConnectableAPI &connectable ) { - pxr::TfToken result; + pxr::TfToken id; + std::string type; if( auto shader = pxr::UsdShadeShader( connectable ) ) { - shader.GetShaderId( &result ); + shader.GetShaderId( &id ); + type = "surface"; } #if PXR_VERSION >= 2111 else if( auto light = pxr::UsdLuxLightAPI( connectable ) ) { - light.GetShaderIdAttr().Get( &result ); + light.GetShaderIdAttr().Get( &id ); + type = "light"; } #endif - return result; + return std::make_pair( id, type ); } void readAdditionalLightParameters( const pxr::UsdPrim &prim, IECore::CompoundDataMap ¶meters ) @@ -106,9 +109,8 @@ IECore::InternedString readShaderNetworkWalk( const pxr::SdfPath &anchorPath, co return handle; } - const pxr::TfToken id = shaderId( usdShader ); + auto [id, shaderType] = shaderIdAndType( usdShader ); std::string shaderName = "defaultsurface"; - std::string shaderType = "surface"; if( id.size() ) { std::string name = id.GetString(); diff --git a/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py b/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py index 86f1a8d677..54401ca39f 100644 --- a/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py +++ b/contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py @@ -3022,6 +3022,9 @@ def testLightAttribute( self ) : self.assertEqual( shader.size(), 1 ) self.assertEqual( shader.getOutput(), "SpotLight23" ) + self.assertEqual( shader.getShader( "SpotLight23" ).name, "SphereLight" ) + self.assertEqual( shader.getShader( "SpotLight23" ).type, "light" ) + self.assertEqual( shader.getShader( "SpotLight23" ).parameters, IECore.CompoundData( {