diff --git a/contrib/IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp b/contrib/IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp index 1b727cff93..112b9b7b57 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" @@ -53,21 +58,44 @@ 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 ) +{ + // 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 ); @@ -81,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(); @@ -137,6 +164,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..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( { @@ -3031,6 +3034,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 } )