Skip to content

Commit 54c5f6c

Browse files
committed
Merge branch 'RB-10.4' into RB-10.5
2 parents 09c8d16 + 293c55e commit 54c5f6c

File tree

6 files changed

+75
-15
lines changed

6 files changed

+75
-15
lines changed

Changes

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,15 @@ Improvements
99
Fixes
1010
-----
1111

12-
- USDScene : Fixed handling of invalid values on the following attributes :
13-
- PointBased : `positions`, `normals`, `velocities`, `accelerations`.
14-
- Curves : `widths`.
15-
- PointInstancer : `ids`, `protoIndices`, `orientations`, `scales`, `velocities`, `accelerations`, `angularVelocities`.
16-
- Points : `ids`, `widths`.
17-
Invalid values are now ignored with a warning, instead of loading as invalid primitive variables.
12+
- USDScene :
13+
- Fixed handling of invalid values on the following attributes :
14+
- PointBased : `positions`, `normals`, `velocities`, `accelerations`.
15+
- Curves : `widths`.
16+
- PointInstancer : `ids`, `protoIndices`, `orientations`, `scales`, `velocities`, `accelerations`, `angularVelocities`.
17+
- Points : `ids`, `widths`.
18+
Invalid values are now ignored with a warning, instead of loading as invalid primitive variables.
19+
- Fixed treatment of unconnected material outputs during reading. If they were "authored" but not connected to a source, they were incorrectly being treated as valid attributes, and loading as empty ShaderNetworks which caused problems elsewhere.
20+
1821
- ToMayaMeshConverter : No longer locks normals set on the Mesh from the scc.
1922

2023
Breaking Changes
@@ -83,6 +86,14 @@ Breaking Changes
8386
- Changed function signature.
8487
- Bug fixes mean subtle changes to the resulting points.
8588

89+
10.4.10.3 (relative to 10.4.10.2)
90+
=========
91+
92+
Fixes
93+
-----
94+
95+
- USDScene : Fixed treatment of unconnected material outputs during reading. If they were "authored" but not connected to a source, they were incorrectly being treated as valid attributes, and loading as empty ShaderNetworks which caused problems elsewhere.
96+
8697
10.4.10.2 (relative to 10.4.10.1)
8798
=========
8899

contrib/IECoreUSD/include/IECoreUSD/ShaderAlgo.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,11 @@ namespace ShaderAlgo
5757
IECOREUSD_API pxr::UsdShadeOutput writeShaderNetwork( const IECoreScene::ShaderNetwork *shaderNetwork, pxr::UsdPrim shaderContainer );
5858

5959
/// Reads a ShaderNetwork from a material output, typically obtained from `UsdShadeMaterial::GetOutput()`.
60+
/// Returns `nullptr` if `canReadShaderNetwork() == false`, usually because the output has no connected source.
6061
IECOREUSD_API IECoreScene::ShaderNetworkPtr readShaderNetwork( const pxr::UsdShadeOutput &output );
62+
/// Returns true if `readShaderNetwork()` will return `nullptr`, usually because the output has no
63+
/// connected source.
64+
bool canReadShaderNetwork( const pxr::UsdShadeOutput &output );
6165

6266
#if PXR_VERSION >= 2111
6367
/// Writes a UsdLuxLight from a shader network.

contrib/IECoreUSD/src/IECoreUSD/ShaderAlgo.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,22 @@ pxr::UsdShadeOutput IECoreUSD::ShaderAlgo::writeShaderNetwork( const IECoreScene
359359
return networkOutUsd;
360360
}
361361

362+
bool IECoreUSD::ShaderAlgo::canReadShaderNetwork( const pxr::UsdShadeOutput &output )
363+
{
364+
pxr::UsdShadeConnectableAPI usdSource;
365+
pxr::TfToken usdSourceName;
366+
pxr::UsdShadeAttributeType usdSourceType;
367+
if(
368+
!output.GetConnectedSource( &usdSource, &usdSourceName, &usdSourceType ) ||
369+
usdSourceType != pxr::UsdShadeAttributeType::Output
370+
)
371+
{
372+
return false;
373+
}
374+
375+
return true;
376+
}
377+
362378
IECoreScene::ShaderNetworkPtr IECoreUSD::ShaderAlgo::readShaderNetwork( const pxr::UsdShadeOutput &output )
363379
{
364380
pxr::UsdShadeConnectableAPI usdSource;
@@ -369,7 +385,7 @@ IECoreScene::ShaderNetworkPtr IECoreUSD::ShaderAlgo::readShaderNetwork( const px
369385
usdSourceType != pxr::UsdShadeAttributeType::Output
370386
)
371387
{
372-
return new IECoreScene::ShaderNetwork();
388+
return nullptr;
373389
}
374390

375391
IECoreScene::ShaderNetworkPtr result = new IECoreScene::ShaderNetwork();

contrib/IECoreUSD/src/IECoreUSD/USDScene.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ class ShaderNetworkCache : public LRUCache<pxr::SdfPath, IECoreScene::ConstShade
480480
static IECoreScene::ConstShaderNetworkPtr getter( const ShaderNetworkCacheGetterKey &key, size_t &cost )
481481
{
482482
IECoreScene::ConstShaderNetworkPtr result = ShaderAlgo::readShaderNetwork( key );
483-
cost = result->Object::memoryUsage();
483+
cost = result ? result ->Object::memoryUsage() : 0;
484484
return result;
485485
}
486486

@@ -961,7 +961,7 @@ bool USDScene::hasAttribute( const SceneInterface::Name &name ) const
961961
{
962962
if( pxr::UsdShadeOutput o = mat.GetOutput( output ) )
963963
{
964-
return o.GetAttr().IsAuthored();
964+
return ShaderAlgo::canReadShaderNetwork( o );
965965
}
966966
}
967967
return false;
@@ -1025,6 +1025,10 @@ void USDScene::attributeNames( SceneInterface::NameList &attrs ) const
10251025
{
10261026
for( pxr::UsdShadeOutput &o : mat.GetOutputs( /* onlyAuthored = */ true ) )
10271027
{
1028+
if( !ShaderAlgo::canReadShaderNetwork( o ) )
1029+
{
1030+
continue;
1031+
}
10281032
InternedString attrName = AttributeAlgo::nameFromUSD( { o.GetBaseName() , false } );
10291033
if( !purpose.IsEmpty() )
10301034
{
@@ -1118,8 +1122,7 @@ ConstObjectPtr USDScene::readAttribute( const SceneInterface::Name &name, double
11181122
const auto &[output, purpose] = materialOutputAndPurpose( name.string() );
11191123
if( pxr::UsdShadeMaterial mat = m_root->computeBoundMaterial( m_location->prim, purpose ) )
11201124
{
1121-
pxr::UsdShadeOutput o = mat.GetOutput( output );
1122-
if( o && o.GetAttr().IsAuthored() )
1125+
if( pxr::UsdShadeOutput o = mat.GetOutput( output ) )
11231126
{
11241127
return m_root->readShaderNetwork( o );
11251128
}

contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2686,7 +2686,8 @@ def testShaders( self ) :
26862686
oneShaderNetwork.addShader( "foo", surface )
26872687
oneShaderNetwork.setOutput( IECoreScene.ShaderNetwork.Parameter( "foo", "" ) )
26882688

2689-
# A network with no output can be written out, but it will read back in as empty
2689+
# A network with no output can be written out, but not read back in, because
2690+
# it will not have been connected to a material output.
26902691
noOutputNetwork = IECoreScene.ShaderNetwork()
26912692
noOutputNetwork.addShader( "foo", surface )
26922693

@@ -2873,14 +2874,14 @@ def testShaders( self ) :
28732874

28742875
root = IECoreScene.SceneInterface.create( fileName, IECore.IndexedIO.OpenMode.Read )
28752876

2876-
self.assertEqual( set( root.child( "shaderLocation" ).attributeNames() ), set( ['ai:disp_map', 'ai:surface', 'complex:surface', 'testBad:surface', 'volume', 'componentConnection:surface', 'manualComponent:surface' ] ) )
2877+
self.assertEqual( set( root.child( "shaderLocation" ).attributeNames() ), set( ['ai:disp_map', 'ai:surface', 'complex:surface', 'volume', 'componentConnection:surface', 'manualComponent:surface' ] ) )
28772878

28782879
self.assertEqual( root.child( "shaderLocation" ).readAttribute( "ai:surface", 0 ).outputShader().parameters, oneShaderNetwork.outputShader().parameters )
28792880
self.assertEqual( root.child( "shaderLocation" ).readAttribute( "ai:surface", 0 ).outputShader(), oneShaderNetwork.outputShader() )
28802881
self.assertEqual( root.child( "shaderLocation" ).readAttribute( "ai:surface", 0 ), oneShaderNetwork )
2881-
self.assertTrue( root.child( "shaderLocation" ).hasAttribute( "testBad:surface" ) )
2882+
self.assertFalse( root.child( "shaderLocation" ).hasAttribute( "testBad:surface" ) )
28822883

2883-
self.assertEqual( root.child( "shaderLocation" ).readAttribute( "testBad:surface", 0 ), IECoreScene.ShaderNetwork() )
2884+
self.assertEqual( root.child( "shaderLocation" ).readAttribute( "testBad:surface", 0 ), None )
28842885
self.assertEqual( root.child( "shaderLocation" ).readAttribute( "ai:disp_map", 0 ), pickOutputNetwork )
28852886
self.assertEqual( root.child( "shaderLocation" ).hasAttribute( "ai:volume" ), False )
28862887
self.assertEqual( root.child( "shaderLocation" ).readAttribute( "volume", 0 ), oneShaderNetwork )
@@ -3898,5 +3899,17 @@ def testWriteVDBObject( self ) :
38983899
self.assertEqual( field.GetFilePathAttr().Get( 0 ), vdbFileName )
38993900
self.assertEqual( field.GetFieldClassAttr().Get( 0 ), "GRID_FOG_VOLUME" )
39003901

3902+
def testUnconnectedMaterialOutput( self ) :
3903+
3904+
root = IECoreScene.SceneInterface.create(
3905+
os.path.join( os.path.dirname( __file__ ), "data", "unconnectedMaterialOutput.usda" ),
3906+
IECore.IndexedIO.OpenMode.Read
3907+
)
3908+
3909+
sphere = root.child( "sphere" )
3910+
self.assertFalse( sphere.hasAttribute( "cycles:surface" ) )
3911+
self.assertNotIn( "cycles:surface", sphere.attributeNames() )
3912+
self.assertIsNone( sphere.readAttribute( "cycles:surface", 0 ) )
3913+
39013914
if __name__ == "__main__":
39023915
unittest.main()
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#usda 1.0
2+
3+
def Sphere "sphere" (
4+
prepend apiSchemas = ["MaterialBindingAPI"]
5+
)
6+
{
7+
rel material:binding = </myMaterial>
8+
}
9+
10+
def Material "myMaterial"
11+
{
12+
token outputs:cycles:surface
13+
}

0 commit comments

Comments
 (0)