Skip to content

Commit 3bb0325

Browse files
authored
Merge pull request #1256 from johnhaddon/usdLights
Basic UsdLux read support
2 parents 0c7939c + 5d233ba commit 3bb0325

File tree

9 files changed

+203
-105
lines changed

9 files changed

+203
-105
lines changed

SConstruct

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2999,6 +2999,7 @@ else :
29992999
usdLibs = [
30003000
"usd",
30013001
"usdGeom",
3002+
"usdLux",
30023003
"usdSkel",
30033004
"usdShade",
30043005
"sdf",

contrib/IECoreUSD/include/IECoreUSD/ShaderAlgo.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@
4242
IECORE_PUSH_DEFAULT_VISIBILITY
4343
#include "pxr/usd/usdShade/material.h"
4444
#include "pxr/usd/usdShade/output.h"
45+
#if PXR_VERSION >= 2111
46+
#include "pxr/usd/usdLux/lightAPI.h"
47+
#endif
4548
IECORE_POP_DEFAULT_VISIBILITY
4649

4750
namespace IECoreUSD
@@ -53,13 +56,13 @@ namespace ShaderAlgo
5356
/// Write ShaderNetwork to USD, placing the shaders under the Prim `shaderContainer`
5457
IECOREUSD_API pxr::UsdShadeOutput writeShaderNetwork( const IECoreScene::ShaderNetwork *shaderNetwork, pxr::UsdPrim shaderContainer );
5558

56-
/// Read ShaderNetwork from a USD node ( and its connected inputs )
57-
/// `anchorPath` is the ancestor path that shaders will be named relative to
58-
/// `outputHandle` specifies which output of the USD node is being used ( the ShaderNetwork must have
59-
/// a corresponding output set )
60-
IECoreScene::ShaderNetworkPtr readShaderNetwork( const pxr::SdfPath &anchorPath, const pxr::UsdShadeShader &outputShader, const pxr::TfToken &outputHandle );
61-
59+
/// Reads a ShaderNetwork from a material output, typically obtained from `UsdShadeMaterial::GetOutput()`.
60+
IECoreScene::ShaderNetworkPtr readShaderNetwork( const pxr::UsdShadeOutput &output );
6261

62+
#if PXR_VERSION >= 2111
63+
/// Reads a ShaderNetwork from a light.
64+
IECoreScene::ShaderNetworkPtr readShaderNetwork( const pxr::UsdLuxLightAPI &light );
65+
#endif
6366

6467
} // namespace ShaderAlgo
6568

contrib/IECoreUSD/src/IECoreUSD/PointInstancerAlgo.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,11 @@ IECore::ObjectPtr readPointInstancer( pxr::UsdGeomPointInstancer &pointInstancer
9595
newPoints->variables["velocity"] = IECoreScene::PrimitiveVariable( IECoreScene::PrimitiveVariable::Vertex, velocityData );
9696
}
9797

98-
#if USD_VERSION >= 1911
9998
if( auto accelerationData = DataAlgo::fromUSD( pointInstancer.GetAccelerationsAttr(), time ) )
10099
{
101100
Canceller::check( canceller );
102101
newPoints->variables["acceleration"] = IECoreScene::PrimitiveVariable( IECoreScene::PrimitiveVariable::Vertex, accelerationData );
103102
}
104-
#endif
105103

106104
if( auto angularVelocityData = DataAlgo::fromUSD( pointInstancer.GetAngularVelocitiesAttr(), time ) )
107105
{
@@ -137,9 +135,7 @@ bool pointInstancerMightBeTimeVarying( pxr::UsdGeomPointInstancer &instancer )
137135
instancer.GetOrientationsAttr().ValueMightBeTimeVarying() ||
138136
instancer.GetScalesAttr().ValueMightBeTimeVarying() ||
139137
instancer.GetVelocitiesAttr().ValueMightBeTimeVarying() ||
140-
#if USD_VERSION >= 1911
141138
instancer.GetAccelerationsAttr().ValueMightBeTimeVarying() ||
142-
#endif
143139
instancer.GetAngularVelocitiesAttr().ValueMightBeTimeVarying()
144140
;
145141
}

contrib/IECoreUSD/src/IECoreUSD/PrimitiveAlgo.cpp

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,6 @@ IECORE_PUSH_DEFAULT_VISIBILITY
5454
#include "pxr/usd/usdSkel/root.h"
5555
IECORE_POP_DEFAULT_VISIBILITY
5656

57-
58-
/// \todo Use the standard PXR_VERSION instead. We can't do that until
59-
/// everyone is using USD 19.11 though, because prior to that PXR_VERSION
60-
/// was malformed (octal, and not comparable in any way).
61-
#define USD_VERSION ( PXR_MAJOR_VERSION * 10000 + PXR_MINOR_VERSION * 100 + PXR_PATCH_VERSION )
62-
6357
using namespace std;
6458
using namespace pxr;
6559
using namespace IECore;
@@ -136,12 +130,10 @@ void IECoreUSD::PrimitiveAlgo::writePrimitiveVariable( const std::string &name,
136130
{
137131
pointBased.CreateVelocitiesAttr().Set( PrimitiveAlgo::toUSDExpanded( value ), time );
138132
}
139-
#if USD_VERSION >= 1911
140133
else if( name == "acceleration" )
141134
{
142135
pointBased.CreateAccelerationsAttr().Set( PrimitiveAlgo::toUSDExpanded( value ), time );
143136
}
144-
#endif
145137
else
146138
{
147139
writePrimitiveVariable( name, value, static_cast<pxr::UsdGeomGprim &>( pointBased ), time );
@@ -329,7 +321,7 @@ bool readPrimitiveVariables( const pxr::UsdSkelRoot &skelRoot, const pxr::UsdGeo
329321
}
330322

331323
Canceller::check( canceller );
332-
#if USD_VERSION < 2011
324+
#if PXR_VERSION < 2011
333325
::skelCache()->Populate( skelRoot );
334326
#else
335327
::skelCache()->Populate( skelRoot, pxr::UsdTraverseInstanceProxies() );
@@ -498,12 +490,10 @@ void IECoreUSD::PrimitiveAlgo::readPrimitiveVariables( const pxr::UsdGeomPointBa
498490
primitive->variables["velocity"] = IECoreScene::PrimitiveVariable( IECoreScene::PrimitiveVariable::Vertex, v );
499491
}
500492

501-
#if USD_VERSION >= 1911
502493
if( auto a = boost::static_pointer_cast<V3fVectorData>( DataAlgo::fromUSD( pointBased.GetAccelerationsAttr(), time ) ) )
503494
{
504495
primitive->variables["acceleration"] = IECoreScene::PrimitiveVariable( IECoreScene::PrimitiveVariable::Vertex, a );
505496
}
506-
#endif
507497
}
508498

509499
bool IECoreUSD::PrimitiveAlgo::primitiveVariablesMightBeTimeVarying( const pxr::UsdGeomPrimvarsAPI &primvarsAPI )
@@ -524,9 +514,7 @@ bool IECoreUSD::PrimitiveAlgo::primitiveVariablesMightBeTimeVarying( const pxr::
524514
pointBased.GetPointsAttr().ValueMightBeTimeVarying() ||
525515
pointBased.GetNormalsAttr().ValueMightBeTimeVarying() ||
526516
pointBased.GetVelocitiesAttr().ValueMightBeTimeVarying() ||
527-
#if USD_VERSION >= 1911
528517
pointBased.GetAccelerationsAttr().ValueMightBeTimeVarying() ||
529-
#endif
530518
primitiveVariablesMightBeTimeVarying( pxr::UsdGeomPrimvarsAPI( pointBased.GetPrim() ) ) ||
531519
skelAnimMightBeTimeVarying( pointBased.GetPrim() )
532520
;

contrib/IECoreUSD/src/IECoreUSD/SceneCacheFileFormat.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -237,11 +237,7 @@ void UsdSceneCacheFileFormat::writeLocation(
237237
inChild->path( currentPath );
238238
SdfPath primPath = USDScene::toUSD(currentPath);
239239

240-
#if PXR_VERSION < 2007
241-
if( primPath.AbsoluteRootPath() != SdfPath( "/" ) )
242-
#else
243240
if( !primPath.IsAbsoluteRootPath() )
244-
#endif
245241
{
246242
if( const auto linkedOutScene = runTimeCast<LinkedScene>( outChild.get() ) )
247243
{

contrib/IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp

Lines changed: 76 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,26 @@ namespace
5353

5454
pxr::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 &parameters = 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

156174
pxr::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

Comments
 (0)