@@ -162,6 +162,45 @@ void readNonStandardLightParameters( const pxr::UsdPrim &prim, IECore::CompoundD
162162#endif
163163}
164164
165+ bool nonStandardLightParametersMightBeTimeVarying ( const pxr::UsdPrim &prim )
166+ {
167+ #if PXR_VERSION >= 2111
168+ if ( auto sphereLight = pxr::UsdLuxSphereLight ( prim ) )
169+ {
170+ if ( sphereLight.GetTreatAsPointAttr ().ValueMightBeTimeVarying () )
171+ {
172+ return true ;
173+ }
174+ }
175+ else if ( auto cylinderLight = pxr::UsdLuxCylinderLight ( prim ) )
176+ {
177+ if ( cylinderLight.GetTreatAsLineAttr ().ValueMightBeTimeVarying () )
178+ {
179+ return true ;
180+ }
181+ }
182+
183+ if ( auto light = pxr::UsdLuxLightAPI ( prim ) )
184+ {
185+ pxr::UsdGeomPrimvarsAPI primVarsAPI ( prim );
186+ for ( const auto &primVar : primVarsAPI.GetPrimvarsWithAuthoredValues () )
187+ {
188+ pxr::TfToken name = primVar.GetPrimvarName ();
189+ if ( !boost::starts_with ( name.GetString (), " arnold:" ) )
190+ {
191+ continue ;
192+ }
193+
194+ if ( primVar.ValueMightBeTimeVarying () )
195+ {
196+ return true ;
197+ }
198+ }
199+ }
200+ #endif
201+ return false ;
202+ }
203+
165204const std::regex g_arrayIndexFromUSDRegex ( " :i([0-9]+)$" );
166205const std::string g_arrayIndexFromUSDFormat ( " [$1]" );
167206IECore::InternedString fromUSDParameterName ( const pxr::TfToken &usdName )
@@ -181,9 +220,9 @@ pxr::TfToken toUSDParameterName( IECore::InternedString cortexName )
181220 );
182221}
183222
184- IECoreScene::ShaderNetwork::Parameter readShaderNetworkWalk ( const pxr::SdfPath &anchorPath, const pxr::UsdShadeOutput &output, IECoreScene::ShaderNetwork &shaderNetwork );
223+ IECoreScene::ShaderNetwork::Parameter readShaderNetworkWalk ( const pxr::SdfPath &anchorPath, const pxr::UsdShadeOutput &output, pxr::UsdTimeCode timeCode, IECoreScene::ShaderNetwork &shaderNetwork );
185224
186- IECore::InternedString readShaderNetworkWalk ( const pxr::SdfPath &anchorPath, const pxr::UsdShadeConnectableAPI &usdShader, IECoreScene::ShaderNetwork &shaderNetwork )
225+ IECore::InternedString readShaderNetworkWalk ( const pxr::SdfPath &anchorPath, const pxr::UsdShadeConnectableAPI &usdShader, pxr::UsdTimeCode timeCode, IECoreScene::ShaderNetwork &shaderNetwork )
187226{
188227 IECore::InternedString handle ( usdShader.GetPath ().MakeRelativePath ( anchorPath ).GetString () );
189228
@@ -226,7 +265,7 @@ IECore::InternedString readShaderNetworkWalk( const pxr::SdfPath &anchorPath, co
226265 if ( usdSourceType == pxr::UsdShadeAttributeType::Output )
227266 {
228267 const IECoreScene::ShaderNetwork::Parameter sourceHandle = readShaderNetworkWalk (
229- anchorPath, usdSource.GetOutput ( usdSourceName ), shaderNetwork
268+ anchorPath, usdSource.GetOutput ( usdSourceName ), timeCode, shaderNetwork
230269 );
231270 connections.push_back ( {
232271 sourceHandle, { handle, fromUSDParameterName ( i.GetBaseName () ) }
@@ -241,7 +280,7 @@ IECore::InternedString readShaderNetworkWalk( const pxr::SdfPath &anchorPath, co
241280 }
242281 }
243282
244- if ( IECore::DataPtr d = IECoreUSD::DataAlgo::fromUSD ( pxr::UsdAttribute ( valueAttribute ) ) )
283+ if ( IECore::DataPtr d = IECoreUSD::DataAlgo::fromUSD ( pxr::UsdAttribute ( valueAttribute ), timeCode ) )
245284 {
246285 parameters[fromUSDParameterName ( i.GetBaseName () )] = d;
247286 }
@@ -281,9 +320,9 @@ IECore::InternedString readShaderNetworkWalk( const pxr::SdfPath &anchorPath, co
281320 return handle;
282321}
283322
284- IECoreScene::ShaderNetwork::Parameter readShaderNetworkWalk ( const pxr::SdfPath &anchorPath, const pxr::UsdShadeOutput &output, IECoreScene::ShaderNetwork &shaderNetwork )
323+ IECoreScene::ShaderNetwork::Parameter readShaderNetworkWalk ( const pxr::SdfPath &anchorPath, const pxr::UsdShadeOutput &output, pxr::UsdTimeCode timeCode, IECoreScene::ShaderNetwork &shaderNetwork )
285324{
286- IECore::InternedString shaderHandle = readShaderNetworkWalk ( anchorPath, pxr::UsdShadeConnectableAPI ( output.GetPrim () ), shaderNetwork );
325+ IECore::InternedString shaderHandle = readShaderNetworkWalk ( anchorPath, pxr::UsdShadeConnectableAPI ( output.GetPrim () ), timeCode, shaderNetwork );
287326 if ( output.GetBaseName () != " DEFAULT_OUTPUT" )
288327 {
289328 return IECoreScene::ShaderNetwork::Parameter ( shaderHandle, output.GetBaseName ().GetString () );
@@ -294,6 +333,45 @@ IECoreScene::ShaderNetwork::Parameter readShaderNetworkWalk( const pxr::SdfPath
294333 }
295334}
296335
336+ bool shaderNetworkMightBeTimeVaryingWalk ( const pxr::UsdShadeConnectableAPI &usdShader, std::unordered_set<pxr::UsdPrim, pxr::TfHash> &visited )
337+ {
338+ if ( !visited.insert ( usdShader.GetPrim () ).second )
339+ {
340+ return false ;
341+ }
342+
343+ std::vector<IECoreScene::ShaderNetwork::Connection> connections;
344+ for ( pxr::UsdShadeInput &i : usdShader.GetInputs () )
345+ {
346+ pxr::UsdShadeConnectableAPI usdSource;
347+ pxr::TfToken usdSourceName;
348+ pxr::UsdShadeAttributeType usdSourceType;
349+
350+ pxr::UsdAttribute valueAttribute = i;
351+ if ( i.GetConnectedSource ( &usdSource, &usdSourceName, &usdSourceType ) )
352+ {
353+ if ( usdSourceType == pxr::UsdShadeAttributeType::Output )
354+ {
355+ if ( shaderNetworkMightBeTimeVaryingWalk ( usdSource, visited ) )
356+ {
357+ return true ;
358+ }
359+ }
360+ else
361+ {
362+ valueAttribute = usdSource.GetInput ( usdSourceName );
363+ }
364+ }
365+
366+ if ( valueAttribute.ValueMightBeTimeVarying () )
367+ {
368+ return true ;
369+ }
370+ }
371+
372+ return nonStandardLightParametersMightBeTimeVarying ( usdShader.GetPrim () );
373+ }
374+
297375IECoreScene::ConstShaderNetworkPtr adaptShaderNetworkForWriting ( const IECoreScene::ShaderNetwork *shaderNetwork )
298376{
299377 IECoreScene::ShaderNetworkPtr result = shaderNetwork->copy ();
@@ -480,7 +558,7 @@ bool IECoreUSD::ShaderAlgo::canReadShaderNetwork( const pxr::UsdShadeOutput &out
480558 return true ;
481559}
482560
483- IECoreScene::ShaderNetworkPtr IECoreUSD::ShaderAlgo::readShaderNetwork ( const pxr::UsdShadeOutput &output )
561+ IECoreScene::ShaderNetworkPtr IECoreUSD::ShaderAlgo::readShaderNetwork ( const pxr::UsdShadeOutput &output, pxr::UsdTimeCode timeCode )
484562{
485563 pxr::UsdShadeConnectableAPI usdSource;
486564 pxr::TfToken usdSourceName;
@@ -494,7 +572,7 @@ IECoreScene::ShaderNetworkPtr IECoreUSD::ShaderAlgo::readShaderNetwork( const px
494572 }
495573
496574 IECoreScene::ShaderNetworkPtr result = new IECoreScene::ShaderNetwork ();
497- IECoreScene::ShaderNetwork::Parameter outputHandle = readShaderNetworkWalk ( usdSource.GetPrim ().GetParent ().GetPath (), usdSource.GetOutput ( usdSourceName ), *result );
575+ IECoreScene::ShaderNetwork::Parameter outputHandle = readShaderNetworkWalk ( usdSource.GetPrim ().GetParent ().GetPath (), usdSource.GetOutput ( usdSourceName ), timeCode, *result );
498576
499577 // If the output shader has type "ai:shader" then set its type to
500578 // "ai:surface" or "ai:light" as appropriate. This is just a heuristic,
@@ -529,6 +607,23 @@ IECoreScene::ShaderNetworkPtr IECoreUSD::ShaderAlgo::readShaderNetwork( const px
529607 return result;
530608}
531609
610+ bool IECoreUSD::ShaderAlgo::shaderNetworkMightBeTimeVarying ( const pxr::UsdShadeOutput &output )
611+ {
612+ pxr::UsdShadeConnectableAPI usdSource;
613+ pxr::TfToken usdSourceName;
614+ pxr::UsdShadeAttributeType usdSourceType;
615+ if (
616+ !output.GetConnectedSource ( &usdSource, &usdSourceName, &usdSourceType ) ||
617+ usdSourceType != pxr::UsdShadeAttributeType::Output
618+ )
619+ {
620+ return false ;
621+ }
622+
623+ std::unordered_set<pxr::UsdPrim, pxr::TfHash> visited;
624+ return shaderNetworkMightBeTimeVaryingWalk ( usdSource, visited );
625+ }
626+
532627#if PXR_VERSION >= 2111
533628
534629// This is very similar to `writeShaderNetwork` but with these key differences :
@@ -587,13 +682,19 @@ void IECoreUSD::ShaderAlgo::writeLight( const IECoreScene::ShaderNetwork *shader
587682 writeShaderConnections ( shaderNetwork, usdShaders );
588683}
589684
590- IECoreScene::ShaderNetworkPtr IECoreUSD::ShaderAlgo::readLight ( const pxr::UsdLuxLightAPI &light )
685+ IECoreScene::ShaderNetworkPtr IECoreUSD::ShaderAlgo::readLight ( const pxr::UsdLuxLightAPI &light, pxr::UsdTimeCode timeCode )
591686{
592687 IECoreScene::ShaderNetworkPtr result = new IECoreScene::ShaderNetwork ();
593- IECoreScene::ShaderNetwork::Parameter lightHandle = readShaderNetworkWalk ( light.GetPath ().GetParentPath (), pxr::UsdShadeConnectableAPI ( light ), *result );
688+ IECoreScene::ShaderNetwork::Parameter lightHandle = readShaderNetworkWalk ( light.GetPath ().GetParentPath (), pxr::UsdShadeConnectableAPI ( light ), timeCode, *result );
594689 result->setOutput ( lightHandle );
595690 IECoreScene::ShaderNetworkAlgo::removeComponentConnectionAdapters ( result.get () );
596691 return result;
597692}
598693
694+ bool IECoreUSD::ShaderAlgo::lightMightBeTimeVarying ( const pxr::UsdLuxLightAPI &light )
695+ {
696+ std::unordered_set<pxr::UsdPrim, pxr::TfHash> visited;
697+ return shaderNetworkMightBeTimeVaryingWalk ( pxr::UsdShadeConnectableAPI ( light ), visited );
698+ }
699+
599700#endif
0 commit comments