@@ -167,6 +167,45 @@ void readNonStandardLightParameters( const pxr::UsdPrim &prim, IECore::CompoundD
167167#endif
168168}
169169
170+ bool nonStandardLightParametersMightBeTimeVarying ( const pxr::UsdPrim &prim )
171+ {
172+ #if PXR_VERSION >= 2111
173+ if ( auto sphereLight = pxr::UsdLuxSphereLight ( prim ) )
174+ {
175+ if ( sphereLight.GetTreatAsPointAttr ().ValueMightBeTimeVarying () )
176+ {
177+ return true ;
178+ }
179+ }
180+ else if ( auto cylinderLight = pxr::UsdLuxCylinderLight ( prim ) )
181+ {
182+ if ( cylinderLight.GetTreatAsLineAttr ().ValueMightBeTimeVarying () )
183+ {
184+ return true ;
185+ }
186+ }
187+
188+ if ( auto light = pxr::UsdLuxLightAPI ( prim ) )
189+ {
190+ pxr::UsdGeomPrimvarsAPI primVarsAPI ( prim );
191+ for ( const auto &primVar : primVarsAPI.GetPrimvarsWithAuthoredValues () )
192+ {
193+ pxr::TfToken name = primVar.GetPrimvarName ();
194+ if ( !boost::starts_with ( name.GetString (), " arnold:" ) )
195+ {
196+ continue ;
197+ }
198+
199+ if ( primVar.ValueMightBeTimeVarying () )
200+ {
201+ return true ;
202+ }
203+ }
204+ }
205+ #endif
206+ return false ;
207+ }
208+
170209const std::regex g_arrayIndexFromUSDRegex ( " :i([0-9]+)$" );
171210const std::string g_arrayIndexFromUSDFormat ( " [$1]" );
172211IECore::InternedString fromUSDParameterName ( const pxr::TfToken &usdName )
@@ -186,9 +225,9 @@ pxr::TfToken toUSDParameterName( IECore::InternedString cortexName )
186225 );
187226}
188227
189- IECoreScene::ShaderNetwork::Parameter readShaderNetworkWalk ( const pxr::SdfPath &anchorPath, const pxr::UsdShadeOutput &output, IECoreScene::ShaderNetwork &shaderNetwork );
228+ IECoreScene::ShaderNetwork::Parameter readShaderNetworkWalk ( const pxr::SdfPath &anchorPath, const pxr::UsdShadeOutput &output, pxr::UsdTimeCode timeCode, IECoreScene::ShaderNetwork &shaderNetwork );
190229
191- IECore::InternedString readShaderNetworkWalk ( const pxr::SdfPath &anchorPath, const pxr::UsdShadeConnectableAPI &usdShader, IECoreScene::ShaderNetwork &shaderNetwork )
230+ IECore::InternedString readShaderNetworkWalk ( const pxr::SdfPath &anchorPath, const pxr::UsdShadeConnectableAPI &usdShader, pxr::UsdTimeCode timeCode, IECoreScene::ShaderNetwork &shaderNetwork )
192231{
193232 IECore::InternedString handle ( usdShader.GetPath ().MakeRelativePath ( anchorPath ).GetString () );
194233
@@ -231,7 +270,7 @@ IECore::InternedString readShaderNetworkWalk( const pxr::SdfPath &anchorPath, co
231270 if ( usdSourceType == pxr::UsdShadeAttributeType::Output )
232271 {
233272 const IECoreScene::ShaderNetwork::Parameter sourceHandle = readShaderNetworkWalk (
234- anchorPath, usdSource.GetOutput ( usdSourceName ), shaderNetwork
273+ anchorPath, usdSource.GetOutput ( usdSourceName ), timeCode, shaderNetwork
235274 );
236275 connections.push_back ( {
237276 sourceHandle, { handle, fromUSDParameterName ( i.GetBaseName () ) }
@@ -246,7 +285,7 @@ IECore::InternedString readShaderNetworkWalk( const pxr::SdfPath &anchorPath, co
246285 }
247286 }
248287
249- if ( IECore::DataPtr d = IECoreUSD::DataAlgo::fromUSD ( pxr::UsdAttribute ( valueAttribute ) ) )
288+ if ( IECore::DataPtr d = IECoreUSD::DataAlgo::fromUSD ( pxr::UsdAttribute ( valueAttribute ), timeCode ) )
250289 {
251290 parameters[fromUSDParameterName ( i.GetBaseName () )] = d;
252291 }
@@ -286,9 +325,9 @@ IECore::InternedString readShaderNetworkWalk( const pxr::SdfPath &anchorPath, co
286325 return handle;
287326}
288327
289- IECoreScene::ShaderNetwork::Parameter readShaderNetworkWalk ( const pxr::SdfPath &anchorPath, const pxr::UsdShadeOutput &output, IECoreScene::ShaderNetwork &shaderNetwork )
328+ IECoreScene::ShaderNetwork::Parameter readShaderNetworkWalk ( const pxr::SdfPath &anchorPath, const pxr::UsdShadeOutput &output, pxr::UsdTimeCode timeCode, IECoreScene::ShaderNetwork &shaderNetwork )
290329{
291- IECore::InternedString shaderHandle = readShaderNetworkWalk ( anchorPath, pxr::UsdShadeConnectableAPI ( output.GetPrim () ), shaderNetwork );
330+ IECore::InternedString shaderHandle = readShaderNetworkWalk ( anchorPath, pxr::UsdShadeConnectableAPI ( output.GetPrim () ), timeCode, shaderNetwork );
292331 if ( output.GetBaseName () != " DEFAULT_OUTPUT" )
293332 {
294333 return IECoreScene::ShaderNetwork::Parameter ( shaderHandle, output.GetBaseName ().GetString () );
@@ -299,6 +338,45 @@ IECoreScene::ShaderNetwork::Parameter readShaderNetworkWalk( const pxr::SdfPath
299338 }
300339}
301340
341+ bool shaderNetworkMightBeTimeVaryingWalk ( const pxr::UsdShadeConnectableAPI &usdShader, std::unordered_set<pxr::UsdPrim, pxr::TfHash> &visited )
342+ {
343+ if ( !visited.insert ( usdShader.GetPrim () ).second )
344+ {
345+ return false ;
346+ }
347+
348+ std::vector<IECoreScene::ShaderNetwork::Connection> connections;
349+ for ( pxr::UsdShadeInput &i : usdShader.GetInputs () )
350+ {
351+ pxr::UsdShadeConnectableAPI usdSource;
352+ pxr::TfToken usdSourceName;
353+ pxr::UsdShadeAttributeType usdSourceType;
354+
355+ pxr::UsdAttribute valueAttribute = i;
356+ if ( i.GetConnectedSource ( &usdSource, &usdSourceName, &usdSourceType ) )
357+ {
358+ if ( usdSourceType == pxr::UsdShadeAttributeType::Output )
359+ {
360+ if ( shaderNetworkMightBeTimeVaryingWalk ( usdSource, visited ) )
361+ {
362+ return true ;
363+ }
364+ }
365+ else
366+ {
367+ valueAttribute = usdSource.GetInput ( usdSourceName );
368+ }
369+ }
370+
371+ if ( valueAttribute.ValueMightBeTimeVarying () )
372+ {
373+ return true ;
374+ }
375+ }
376+
377+ return nonStandardLightParametersMightBeTimeVarying ( usdShader.GetPrim () );
378+ }
379+
302380IECoreScene::ConstShaderNetworkPtr adaptShaderNetworkForWriting ( const IECoreScene::ShaderNetwork *shaderNetwork )
303381{
304382 IECoreScene::ShaderNetworkPtr result = shaderNetwork->copy ();
@@ -485,7 +563,7 @@ bool IECoreUSD::ShaderAlgo::canReadShaderNetwork( const pxr::UsdShadeOutput &out
485563 return true ;
486564}
487565
488- IECoreScene::ShaderNetworkPtr IECoreUSD::ShaderAlgo::readShaderNetwork ( const pxr::UsdShadeOutput &output )
566+ IECoreScene::ShaderNetworkPtr IECoreUSD::ShaderAlgo::readShaderNetwork ( const pxr::UsdShadeOutput &output, pxr::UsdTimeCode timeCode )
489567{
490568 pxr::UsdShadeConnectableAPI usdSource;
491569 pxr::TfToken usdSourceName;
@@ -499,7 +577,7 @@ IECoreScene::ShaderNetworkPtr IECoreUSD::ShaderAlgo::readShaderNetwork( const px
499577 }
500578
501579 IECoreScene::ShaderNetworkPtr result = new IECoreScene::ShaderNetwork ();
502- IECoreScene::ShaderNetwork::Parameter outputHandle = readShaderNetworkWalk ( usdSource.GetPrim ().GetParent ().GetPath (), usdSource.GetOutput ( usdSourceName ), *result );
580+ IECoreScene::ShaderNetwork::Parameter outputHandle = readShaderNetworkWalk ( usdSource.GetPrim ().GetParent ().GetPath (), usdSource.GetOutput ( usdSourceName ), timeCode, *result );
503581
504582 // If the output shader has type "ai:shader" then set its type to
505583 // "ai:surface" or "ai:light" as appropriate. This is just a heuristic,
@@ -534,6 +612,23 @@ IECoreScene::ShaderNetworkPtr IECoreUSD::ShaderAlgo::readShaderNetwork( const px
534612 return result;
535613}
536614
615+ bool IECoreUSD::ShaderAlgo::shaderNetworkMightBeTimeVarying ( const pxr::UsdShadeOutput &output )
616+ {
617+ pxr::UsdShadeConnectableAPI usdSource;
618+ pxr::TfToken usdSourceName;
619+ pxr::UsdShadeAttributeType usdSourceType;
620+ if (
621+ !output.GetConnectedSource ( &usdSource, &usdSourceName, &usdSourceType ) ||
622+ usdSourceType != pxr::UsdShadeAttributeType::Output
623+ )
624+ {
625+ return false ;
626+ }
627+
628+ std::unordered_set<pxr::UsdPrim, pxr::TfHash> visited;
629+ return shaderNetworkMightBeTimeVaryingWalk ( usdSource, visited );
630+ }
631+
537632#if PXR_VERSION >= 2111
538633
539634// This is very similar to `writeShaderNetwork` but with these key differences :
@@ -592,13 +687,19 @@ void IECoreUSD::ShaderAlgo::writeLight( const IECoreScene::ShaderNetwork *shader
592687 writeShaderConnections ( shaderNetwork, usdShaders );
593688}
594689
595- IECoreScene::ShaderNetworkPtr IECoreUSD::ShaderAlgo::readLight ( const pxr::UsdLuxLightAPI &light )
690+ IECoreScene::ShaderNetworkPtr IECoreUSD::ShaderAlgo::readLight ( const pxr::UsdLuxLightAPI &light, pxr::UsdTimeCode timeCode )
596691{
597692 IECoreScene::ShaderNetworkPtr result = new IECoreScene::ShaderNetwork ();
598- IECoreScene::ShaderNetwork::Parameter lightHandle = readShaderNetworkWalk ( light.GetPath ().GetParentPath (), pxr::UsdShadeConnectableAPI ( light ), *result );
693+ IECoreScene::ShaderNetwork::Parameter lightHandle = readShaderNetworkWalk ( light.GetPath ().GetParentPath (), pxr::UsdShadeConnectableAPI ( light ), timeCode, *result );
599694 result->setOutput ( lightHandle );
600695 IECoreScene::ShaderNetworkAlgo::removeComponentConnectionAdapters ( result.get () );
601696 return result;
602697}
603698
699+ bool IECoreUSD::ShaderAlgo::lightMightBeTimeVarying ( const pxr::UsdLuxLightAPI &light )
700+ {
701+ std::unordered_set<pxr::UsdPrim, pxr::TfHash> visited;
702+ return shaderNetworkMightBeTimeVaryingWalk ( pxr::UsdShadeConnectableAPI ( light ), visited );
703+ }
704+
604705#endif
0 commit comments