Skip to content

Commit 4f7d1df

Browse files
committed
USD PrimitiveAlgo : Don't load invalid primitive variables
This required some fixes to the existing tests, since they were accidentally using invalid variables. Also required a change to the PointsPrimitive reader to construct the primitive with the right point count, so that the primitive variable checks are using the right sizes.
1 parent 29eddb1 commit 4f7d1df

File tree

7 files changed

+83
-18
lines changed

7 files changed

+83
-18
lines changed

Changes

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33

44
Fixes
55
-----
6-
- ImageReader : Fixed compilation with versions of OIIO < 2.4
76

7+
- ImageReader : Fixed compilation with versions of OIIO < 2.4.
8+
- USDScene : Invalid primitive variables are now skipped during loading, with a warning being emitted instead.
89

910
10.4.5.0 (relative to 10.4.4.0)
1011
========

contrib/IECoreUSD/src/IECoreUSD/PointsAlgo.cpp

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,9 @@ namespace
5757

5858
IECore::ObjectPtr readPoints( pxr::UsdGeomPoints &points, pxr::UsdTimeCode time, const Canceller *canceller )
5959
{
60-
IECoreScene::PointsPrimitivePtr newPoints = new IECoreScene::PointsPrimitive();
60+
IECoreScene::PointsPrimitivePtr newPoints = new IECoreScene::PointsPrimitive( points.GetPointCount( time ) );
6161
PrimitiveAlgo::readPrimitiveVariables( points, time, newPoints.get(), canceller );
6262

63-
Canceller::check( canceller );
64-
if( auto *p = newPoints->variableData<V3fVectorData>( "P" ) )
65-
{
66-
newPoints->setNumPoints( p->readable().size() );
67-
}
68-
6963
Canceller::check( canceller );
7064
if( auto i = boost::static_pointer_cast<Int64VectorData>( DataAlgo::fromUSD( points.GetIdsAttr(), time ) ) )
7165
{

contrib/IECoreUSD/src/IECoreUSD/PrimitiveAlgo.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,14 @@ void readPrimitiveVariable( const pxr::UsdGeomPrimvar &primVar, pxr::UsdTimeCode
242242
indices = DataAlgo::fromUSD( srcIndices );
243243
}
244244

245-
primitive->variables[name] = IECoreScene::PrimitiveVariable( interpolation, data, indices );
245+
const IECoreScene::PrimitiveVariable primitiveVariable( interpolation, data, indices );
246+
if( !primitive->isPrimitiveVariableValid( primitiveVariable ) )
247+
{
248+
IECore::msg( IECore::MessageHandler::Level::Warning, "IECoreUSD::PrimitiveAlgo", boost::format( "Skipping invalid UsdGeomPrimvar \"%1%\"" ) % primVar.GetAttr().GetPath().GetAsString() );
249+
return;
250+
}
251+
252+
primitive->variables[name] = primitiveVariable;
246253
}
247254

248255
pxr::UsdSkelCache *skelCache()

contrib/IECoreUSD/test/IECoreUSD/SceneCacheFileFormatTest.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -522,10 +522,12 @@ def testCustomPrimvars( self ):
522522
box = m.createChild( "box" )
523523
mesh = IECoreScene.MeshPrimitive.createBox( imath.Box3f( imath.V3f( 0 ), imath.V3f( 1 ) ) )
524524
vertexSize = mesh.variableSize( IECoreScene.PrimitiveVariable.Interpolation.Vertex )
525+
uniformSize = mesh.variableSize( IECoreScene.PrimitiveVariable.Interpolation.Uniform )
525526

526-
v = IECore.V3fVectorData( [ imath.Color3f( 12, 12, 12 ) ], IECore.GeometricData.Interpretation.Point )
527+
v = IECore.V3fVectorData( [ imath.Color3f( 12, 12, 12 ) ] * vertexSize, IECore.GeometricData.Interpretation.Point )
527528
mesh["customPoint"] = IECoreScene.PrimitiveVariable( IECoreScene.PrimitiveVariable.Interpolation.Vertex, v )
528-
mesh["customIndexedInt"] = IECoreScene.PrimitiveVariable( IECoreScene.PrimitiveVariable.Interpolation.Uniform, IECore.IntVectorData( [12] ), IECore.IntVectorData( [ 0 ] * vertexSize ) )
529+
mesh["customIndexedInt"] = IECoreScene.PrimitiveVariable( IECoreScene.PrimitiveVariable.Interpolation.Uniform, IECore.IntVectorData( [12] ), IECore.IntVectorData( [ 0 ] * uniformSize ) )
530+
self.assertTrue( mesh.arePrimitiveVariablesValid() )
529531

530532
# Test a shallow copy of a primvar which causes IECore.Object to write a reference into the IndexedIO file
531533
mesh["Pref"] = mesh["P"]
@@ -549,12 +551,12 @@ def testCustomPrimvars( self ):
549551
self.assertEqual( customPoint.GetMetadata( "interpolation" ), "vertex" )
550552

551553
# value
552-
self.assertEqual( customPoint.Get( 24.0 ), pxr.Vt.Vec3fArray( 1, [ pxr.Gf.Vec3f( 12 ) ] ) )
554+
self.assertEqual( customPoint.Get( 24.0 ), pxr.Vt.Vec3fArray( vertexSize, pxr.Gf.Vec3f( 12 ) ) )
553555

554556
# indices
555557
indices = prim.GetAttribute( "primvars:customIndexedInt:indices" )
556558
self.assertTrue( indices )
557-
self.assertEqual( indices.Get( 24.0 ), pxr.Vt.IntArray( vertexSize, [ 0 ] * vertexSize ) )
559+
self.assertEqual( indices.Get( 24.0 ), pxr.Vt.IntArray( [ 0 ] * uniformSize ) )
558560

559561
# uniform interpolation
560562
customIndexedInt = prim.GetAttribute( "primvars:customIndexedInt" )
@@ -587,10 +589,10 @@ def testCustomPrimvars( self ):
587589
self.assertEqual( customPoint.interpolation, IECoreScene.PrimitiveVariable.Interpolation.Vertex )
588590

589591
# value
590-
self.assertEqual( customPoint.data, IECore.V3fVectorData( [ imath.V3f( 12.0 ) ], IECore.GeometricData.Interpretation.Point ) )
592+
self.assertEqual( customPoint.data, IECore.V3fVectorData( [ imath.V3f( 12.0 ) ] * vertexSize, IECore.GeometricData.Interpretation.Point ) )
591593

592594
# indices
593-
self.assertEqual( mesh["customIndexedInt"].indices, IECore.IntVectorData( [0] * vertexSize ) )
595+
self.assertEqual( mesh["customIndexedInt"].indices, IECore.IntVectorData( [ 0 ] * uniformSize ) )
594596

595597
# copy
596598
self.assertEqual( mesh["Pref"], mesh["P"] )

contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -803,6 +803,7 @@ def testCanWriteVariousPrimVarTypes ( self ):
803803
pointsPrimitive["c3f"] = IECoreScene.PrimitiveVariable( IECoreScene.PrimitiveVariable.Interpolation.Vertex, c3f)
804804
pointsPrimitive["token"] = IECoreScene.PrimitiveVariable( IECoreScene.PrimitiveVariable.Interpolation.Vertex, intStr)
805805
pointsPrimitive["quat"] = IECoreScene.PrimitiveVariable( IECoreScene.PrimitiveVariable.Interpolation.Vertex, quat)
806+
self.assertTrue( pointsPrimitive.arePrimitiveVariablesValid() )
806807

807808
child.writeObject( pointsPrimitive, 0.0 )
808809

@@ -2450,7 +2451,14 @@ def assertAttributesValues( sphere ):
24502451
self.assertEqual( bObj.keys(), ["bar", "barDeprecated", "withIndices"] )
24512452
self.assertEqual( bObj["bar"].data, IECore.StringData( "black" ) )
24522453
self.assertEqual( bObj["barDeprecated"].data, IECore.StringData( "black" ) )
2453-
self.assertEqual( bObj["withIndices"], IECoreScene.PrimitiveVariable( IECoreScene.PrimitiveVariable.Interpolation.Vertex, IECore.FloatVectorData([ 1, 2, 3 ]), IECore.IntVectorData( [1] ) ) )
2454+
self.assertEqual(
2455+
bObj["withIndices"],
2456+
IECoreScene.PrimitiveVariable(
2457+
IECoreScene.PrimitiveVariable.Interpolation.Vertex,
2458+
IECore.FloatVectorData( [ 1, 2 ] ),
2459+
IECore.IntVectorData( [ 0, 1, 0, 1 ] )
2460+
)
2461+
)
24542462

24552463
# check primvars from USD API
24562464
stage = pxr.Usd.Stage.Open( os.path.dirname( __file__ ) + "/data/customAttribute.usda" )
@@ -3302,5 +3310,28 @@ def assertExpectedArrayInputs( network ) :
33023310
scene = IECoreScene.SceneInterface.create( fileName, IECore.IndexedIO.OpenMode.Read )
33033311
assertExpectedArrayInputs( scene.child( "sphere" ).readAttribute( "ai:surface", 0 ) )
33043312

3313+
def testInvalidPrimitiveVariables( self ) :
3314+
3315+
goodRoot = IECoreScene.SceneInterface.create( os.path.dirname( __file__ ) + "/data/cube.usda", IECore.IndexedIO.OpenMode.Read )
3316+
badRoot = IECoreScene.SceneInterface.create( os.path.dirname( __file__ ) + "/data/invalidCube.usda", IECore.IndexedIO.OpenMode.Read )
3317+
3318+
goodCube = goodRoot.child( "pCube1" ).readObject( 0 )
3319+
self.assertIn( "uv", goodCube )
3320+
self.assertTrue( goodCube.arePrimitiveVariablesValid() )
3321+
3322+
with IECore.CapturingMessageHandler() as mh :
3323+
badCube = badRoot.child( "pCube1" ).readObject( 0 )
3324+
3325+
self.assertEqual( len( mh.messages ), 1 )
3326+
self.assertEqual( mh.messages[0].level, IECore.Msg.Level.Warning )
3327+
self.assertEqual( mh.messages[0].message, "Skipping invalid UsdGeomPrimvar \"/pCube1.primvars:st\"" )
3328+
3329+
self.assertNotIn( "uv", badCube )
3330+
self.assertTrue( badCube.arePrimitiveVariablesValid() )
3331+
3332+
self.assertNotEqual( goodCube, badCube )
3333+
del goodCube["uv"]
3334+
self.assertEqual( goodCube, badCube )
3335+
33053336
if __name__ == "__main__":
33063337
unittest.main()

contrib/IECoreUSD/test/IECoreUSD/data/customAttribute.usda

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ def Xform "a"
3838
)
3939
string primvars:user:baz = "white"
4040
string primvars:notUserPrefixAttribute = "orange"
41-
float[] primvars:withIndices = [ 1, 2, 3 ] (
41+
float[] primvars:withIndices = [ 1, 2 ] (
4242
interpolation = "vertex"
4343
)
44-
int[] primvars:withIndices:indices = [1]
44+
int[] primvars:withIndices:indices = [0, 1, 0, 1]
4545

4646
def Sphere "c"
4747
{
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#usda 1.0
2+
(
3+
defaultPrim = "pCube1"
4+
endTimeCode = 1
5+
startTimeCode = 1
6+
upAxis = "Y"
7+
)
8+
9+
def Mesh "pCube1" (
10+
kind = "component"
11+
)
12+
{
13+
uniform bool doubleSided = 1
14+
float3[] extent = [(-0.5, -0.5, -0.5), (0.5, 0.5, 0.5)]
15+
int[] faceVertexCounts = [4, 4, 4, 4, 4, 4]
16+
int[] faceVertexIndices = [0, 1, 3, 2, 2, 3, 5, 4, 4, 5, 7, 6, 6, 7, 1, 0, 1, 7, 5, 3, 6, 0, 2, 4]
17+
point3f[] points = [(-0.5, -0.5, 0.5), (0.5, -0.5, 0.5), (-0.5, 0.5, 0.5), (0.5, 0.5, 0.5), (-0.5, 0.5, -0.5), (0.5, 0.5, -0.5), (-0.5, -0.5, -0.5), (0.5, -0.5, -0.5)]
18+
color3f[] primvars:displayColor = [(0.21763764, 0.21763764, 0.21763764)] (
19+
customData = {
20+
dictionary Maya = {
21+
bool generated = 1
22+
}
23+
}
24+
)
25+
float2[] primvars:st = [] (
26+
interpolation = "faceVarying"
27+
)
28+
int[] primvars:st:indices = [0, 1, 2, 3, 3, 2, 4, 5, 5, 4, 6, 7, 7, 6, 8, 9, 1, 10, 11, 2, 12, 0, 3, 13]
29+
}
30+

0 commit comments

Comments
 (0)