@@ -53,7 +53,26 @@ namespace
5353
5454pxr::TfToken g_adapterLabelToken ( IECoreScene::ShaderNetworkAlgo::componentConnectionAdapterLabel().string() );
5555
56- IECore::InternedString readShaderNetworkWalk ( const pxr::SdfPath &anchorPath, const pxr::UsdShadeShader &usdShader, IECoreScene::ShaderNetwork &shaderNetwork )
56+ pxr::TfToken shaderId ( const pxr::UsdShadeConnectableAPI &connectable )
57+ {
58+ pxr::TfToken result;
59+ if ( auto shader = pxr::UsdShadeShader ( connectable ) )
60+ {
61+ shader.GetShaderId ( &result );
62+ }
63+ #if PXR_VERSION >= 2111
64+ else if ( auto light = pxr::UsdLuxLightAPI ( connectable ) )
65+ {
66+ light.GetShaderIdAttr ().Get ( &result );
67+ }
68+ #endif
69+
70+ return result;
71+ }
72+
73+ IECoreScene::ShaderNetwork::Parameter readShaderNetworkWalk ( const pxr::SdfPath &anchorPath, const pxr::UsdShadeOutput &output, IECoreScene::ShaderNetwork &shaderNetwork );
74+
75+ IECore::InternedString readShaderNetworkWalk ( const pxr::SdfPath &anchorPath, const pxr::UsdShadeConnectableAPI &usdShader, IECoreScene::ShaderNetwork &shaderNetwork )
5776{
5877 IECore::InternedString handle ( usdShader.GetPath ().MakeRelativePath ( anchorPath ).GetString () );
5978
@@ -62,10 +81,10 @@ IECore::InternedString readShaderNetworkWalk( const pxr::SdfPath &anchorPath, co
6281 return handle;
6382 }
6483
65- pxr::TfToken id;
84+ const pxr::TfToken id = shaderId ( usdShader ) ;
6685 std::string shaderName = " defaultsurface" ;
6786 std::string shaderType = " surface" ;
68- if ( usdShader. GetShaderId ( &id ) )
87+ if ( id. size ( ) )
6988 {
7089 std::string name = id.GetString ();
7190 size_t colonPos = name.find ( " :" );
@@ -84,8 +103,7 @@ IECore::InternedString readShaderNetworkWalk( const pxr::SdfPath &anchorPath, co
84103
85104 IECore::CompoundDataPtr parametersData = new IECore::CompoundData ();
86105 IECore::CompoundDataMap ¶meters = parametersData->writable ();
87- std::vector< std::tuple< IECore::InternedString, pxr::UsdShadeConnectableAPI, IECore::InternedString > > connections;
88- std::vector< pxr::UsdShadeInput > inputs = usdShader.GetInputs ();
106+ std::vector<IECoreScene::ShaderNetwork::Connection> connections;
89107 for ( pxr::UsdShadeInput &i : usdShader.GetInputs () )
90108 {
91109 pxr::UsdShadeConnectableAPI usdSource;
@@ -95,9 +113,14 @@ IECore::InternedString readShaderNetworkWalk( const pxr::SdfPath &anchorPath, co
95113 pxr::UsdAttribute valueAttribute = i;
96114 if ( i.GetConnectedSource ( &usdSource, &usdSourceName, &usdSourceType ) )
97115 {
98- if ( !usdSource. IsContainer () )
116+ if ( usdSourceType == pxr::UsdShadeAttributeType::Output )
99117 {
100- connections.push_back ( { i.GetBaseName ().GetString (), usdSource, usdSourceName.GetString () } );
118+ const IECoreScene::ShaderNetwork::Parameter sourceHandle = readShaderNetworkWalk (
119+ anchorPath, usdSource.GetOutput ( usdSourceName ), shaderNetwork
120+ );
121+ connections.push_back ( {
122+ sourceHandle, { handle, IECore::InternedString ( i.GetBaseName ().GetString () ) }
123+ } );
101124 }
102125 else
103126 {
@@ -124,33 +147,28 @@ IECore::InternedString readShaderNetworkWalk( const pxr::SdfPath &anchorPath, co
124147 }
125148 shaderNetwork.addShader ( handle, std::move ( newShader ) );
126149
150+ // Can only add connections after we've added the shader.
127151 for ( const auto &c : connections )
128152 {
129- IECore::InternedString attributeName;
130- pxr::UsdShadeConnectableAPI usdSource;
131- IECore::InternedString sourceAttributeName;
132- std::tie ( attributeName, usdSource, sourceAttributeName ) = c;
133- IECore::InternedString sourceHandle = readShaderNetworkWalk ( anchorPath, pxr::UsdShadeShader ( usdSource.GetPrim () ), shaderNetwork );
134-
135- if ( sourceAttributeName == " DEFAULT_OUTPUT" )
136- {
137- shaderNetwork.addConnection ( IECoreScene::ShaderNetwork::Connection (
138- { sourceHandle, " " },
139- { handle, attributeName }
140- ) );
141- }
142- else
143- {
144- shaderNetwork.addConnection ( IECoreScene::ShaderNetwork::Connection (
145- { sourceHandle, sourceAttributeName },
146- { handle, attributeName }
147- ) );
148- }
153+ shaderNetwork.addConnection ( c );
149154 }
150155
151156 return handle;
152157}
153158
159+ IECoreScene::ShaderNetwork::Parameter readShaderNetworkWalk ( const pxr::SdfPath &anchorPath, const pxr::UsdShadeOutput &output, IECoreScene::ShaderNetwork &shaderNetwork )
160+ {
161+ IECore::InternedString shaderHandle = readShaderNetworkWalk ( anchorPath, pxr::UsdShadeConnectableAPI ( output.GetPrim () ), shaderNetwork );
162+ if ( output.GetBaseName () != " DEFAULT_OUTPUT" )
163+ {
164+ return IECoreScene::ShaderNetwork::Parameter ( shaderHandle, output.GetBaseName ().GetString () );
165+ }
166+ else
167+ {
168+ return IECoreScene::ShaderNetwork::Parameter ( shaderHandle );
169+ }
170+ }
171+
154172} // namespace
155173
156174pxr::UsdShadeOutput IECoreUSD::ShaderAlgo::writeShaderNetwork ( const IECoreScene::ShaderNetwork *shaderNetwork, pxr::UsdPrim shaderContainer )
@@ -249,10 +267,21 @@ pxr::UsdShadeOutput IECoreUSD::ShaderAlgo::writeShaderNetwork( const IECoreScene
249267 return networkOutUsd;
250268}
251269
252- IECoreScene::ShaderNetworkPtr IECoreUSD::ShaderAlgo::readShaderNetwork ( const pxr::SdfPath &anchorPath, const pxr::UsdShadeShader &outputShader, const pxr::TfToken &outputParameter )
270+ IECoreScene::ShaderNetworkPtr IECoreUSD::ShaderAlgo::readShaderNetwork ( const pxr::UsdShadeOutput &output )
253271{
272+ pxr::UsdShadeConnectableAPI usdSource;
273+ pxr::TfToken usdSourceName;
274+ pxr::UsdShadeAttributeType usdSourceType;
275+ if (
276+ !output.GetConnectedSource ( &usdSource, &usdSourceName, &usdSourceType ) ||
277+ usdSourceType != pxr::UsdShadeAttributeType::Output
278+ )
279+ {
280+ return new IECoreScene::ShaderNetwork ();
281+ }
282+
254283 IECoreScene::ShaderNetworkPtr result = new IECoreScene::ShaderNetwork ();
255- IECore::InternedString outputHandle = readShaderNetworkWalk ( anchorPath, outputShader , *result );
284+ IECoreScene::ShaderNetwork::Parameter outputHandle = readShaderNetworkWalk ( usdSource. GetPrim (). GetParent (). GetPath (), usdSource. GetOutput ( usdSourceName ) , *result );
256285
257286 // For the output shader, set the type to "ai:surface" if it is "ai:shader".
258287 // This is complete nonsense - there is nothing to suggest that this shader is
@@ -265,24 +294,30 @@ IECoreScene::ShaderNetworkPtr IECoreUSD::ShaderAlgo::readShaderNetwork( const px
265294 // don't use the suffix of the shader type for anything, and we should just set
266295 // everything to prefix:shader ( aside from lights, which are a bit of a
267296 // different question )
268- if ( result->getShader ( outputHandle )->getType () == " ai:shader" )
297+ const IECoreScene::Shader *outputShader = result->getShader ( outputHandle.shader );
298+ if ( outputShader->getType () == " ai:shader" )
269299 {
270- IECoreScene::ShaderPtr o = result-> getShader ( outputHandle ) ->copy ();
300+ IECoreScene::ShaderPtr o = outputShader ->copy ();
271301 o->setType ( " ai:surface" );
272- result->setShader ( outputHandle, std::move ( o ) );
302+ result->setShader ( outputHandle. shader , std::move ( o ) );
273303 }
274304
275- // handles[0] is the handle of the first shader added, which is always the output shader
276- if ( outputParameter.GetString () != " DEFAULT_OUTPUT" )
277- {
278- result->setOutput ( IECoreScene::ShaderNetwork::Parameter ( outputHandle, outputParameter.GetString () ) );
279- }
280- else
281- {
282- result->setOutput ( IECoreScene::ShaderNetwork::Parameter ( outputHandle ) );
283- }
305+ result->setOutput ( outputHandle );
284306
285307 IECoreScene::ShaderNetworkAlgo::removeComponentConnectionAdapters ( result.get () );
286308
287309 return result;
288310}
311+
312+ #if PXR_VERSION >= 2111
313+
314+ IECoreScene::ShaderNetworkPtr IECoreUSD::ShaderAlgo::readShaderNetwork ( const pxr::UsdLuxLightAPI &light )
315+ {
316+ IECoreScene::ShaderNetworkPtr result = new IECoreScene::ShaderNetwork ();
317+ IECoreScene::ShaderNetwork::Parameter lightHandle = readShaderNetworkWalk ( light.GetPath ().GetParentPath (), pxr::UsdShadeConnectableAPI ( light ), *result );
318+ result->setOutput ( lightHandle );
319+ IECoreScene::ShaderNetworkAlgo::removeComponentConnectionAdapters ( result.get () );
320+ return result;
321+ }
322+
323+ #endif
0 commit comments