Skip to content

Commit 94bda88

Browse files
USDSceneTest : Test prototype hashes not reused by reopening file
1 parent 4267b66 commit 94bda88

File tree

2 files changed

+156
-0
lines changed

2 files changed

+156
-0
lines changed

contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,60 @@ def testInstancesShareHashes( self ) :
474474
self.assertEqual( instance0.hash( hashType, 0 ), instance1.hash( hashType, 0 ) )
475475
self.assertEqual( notInstance.hash( hashType, 0 ), instance0.hash( hashType, 0 ) )
476476

477+
def testInstancePrototypeHashesNotReused( self ) :
478+
479+
# The original intent of this test was to check that we assign consistent hashes to prototypes when
480+
# opening and closing the same file ( which triggers USD to randomly shuffle the prototype names ).
481+
482+
# The solution we've ended up with is instead of assigning consistent hashes, each instance of the
483+
# file gets it's own unique hashes, and is basically treated separately. This allows us to just
484+
# use the prototype names in the hash, since we force the hash to be unique anyway.
485+
486+
usedHashes = set()
487+
488+
for i in range( 100 ):
489+
scene = IECoreScene.SceneInterface.create(
490+
os.path.dirname( __file__ ) + "/data/severalInstances.usda",
491+
IECore.IndexedIO.OpenMode.Read
492+
)
493+
494+
instance0 = scene.child( "instance0" )
495+
instance0Child = instance0.child( "world" )
496+
instance10 = scene.child( "instance10" )
497+
instance10Child = instance10.child( "model" ).child( "assembly" )
498+
499+
h1 = instance0Child.hash( scene.HashType.TransformHash, 1 )
500+
h2 = instance10Child.hash( scene.HashType.TransformHash, 1 )
501+
502+
self.assertNotEqual( h1, h2 )
503+
504+
self.assertNotIn( h1, usedHashes )
505+
for j in range( 1, 10 ):
506+
instanceJ = scene.child( "instance%i" % j )
507+
self.assertEqual( h1, instanceJ.child( "world" ).hash( scene.HashType.TransformHash, 1 ) )
508+
del instanceJ
509+
510+
self.assertNotIn( h2, usedHashes )
511+
for j in range( 11, 20 ):
512+
instanceJ = scene.child( "instance%i" % j )
513+
self.assertEqual( h2, instanceJ.child( "model" ).child( "assembly" ).hash( scene.HashType.TransformHash, 1 ) )
514+
del instanceJ
515+
516+
usedHashes.add( h1 )
517+
usedHashes.add( h2 )
518+
519+
# We must carefully delete everything in order to reliably trigger USD randomly switching the
520+
# prototype names around ( I guess waiting for the garbage collector means we might not be
521+
# fully closing the file before we open it again? Weird, but seems reproducible ).
522+
# This is no longer really crucial to this test, since we just force every instance of the file
523+
# to get unique hashes rather than trying to keep prototypes hashing the same, but I'm trying to
524+
# document as much intent as possible here, in case we consider a different solution in the future.
525+
del instance0Child
526+
del instance0
527+
del instance10Child
528+
del instance10
529+
del scene
530+
477531
def testGeometricInterpretation( self ) :
478532

479533
primitive = IECoreScene.PointsPrimitive( IECore.V3fVectorData( [ imath.V3f( 0 ) ] ) )
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#usda 1.0
2+
3+
def Xform "instance0" (
4+
prepend references = @./sphere.usda@
5+
instanceable = true
6+
)
7+
{ }
8+
def Xform "instance1" (
9+
prepend references = @./sphere.usda@
10+
instanceable = true
11+
)
12+
{ }
13+
def Xform "instance2" (
14+
prepend references = @./sphere.usda@
15+
instanceable = true
16+
)
17+
{ }
18+
def Xform "instance3" (
19+
prepend references = @./sphere.usda@
20+
instanceable = true
21+
)
22+
{ }
23+
def Xform "instance4" (
24+
prepend references = @./sphere.usda@
25+
instanceable = true
26+
)
27+
{ }
28+
def Xform "instance5" (
29+
prepend references = @./sphere.usda@
30+
instanceable = true
31+
)
32+
{ }
33+
def Xform "instance6" (
34+
prepend references = @./sphere.usda@
35+
instanceable = true
36+
)
37+
{ }
38+
def Xform "instance7" (
39+
prepend references = @./sphere.usda@
40+
instanceable = true
41+
)
42+
{ }
43+
def Xform "instance8" (
44+
prepend references = @./sphere.usda@
45+
instanceable = true
46+
)
47+
{ }
48+
def Xform "instance9" (
49+
prepend references = @./sphere.usda@
50+
instanceable = true
51+
)
52+
{ }
53+
def Xform "instance10" (
54+
prepend references = @./kind.usda@
55+
instanceable = true
56+
)
57+
{ }
58+
def Xform "instance11" (
59+
prepend references = @./kind.usda@
60+
instanceable = true
61+
)
62+
{ }
63+
def Xform "instance12" (
64+
prepend references = @./kind.usda@
65+
instanceable = true
66+
)
67+
{ }
68+
def Xform "instance13" (
69+
prepend references = @./kind.usda@
70+
instanceable = true
71+
)
72+
{ }
73+
def Xform "instance14" (
74+
prepend references = @./kind.usda@
75+
instanceable = true
76+
)
77+
{ }
78+
def Xform "instance15" (
79+
prepend references = @./kind.usda@
80+
instanceable = true
81+
)
82+
{ }
83+
def Xform "instance16" (
84+
prepend references = @./kind.usda@
85+
instanceable = true
86+
)
87+
{ }
88+
def Xform "instance17" (
89+
prepend references = @./kind.usda@
90+
instanceable = true
91+
)
92+
{ }
93+
def Xform "instance18" (
94+
prepend references = @./kind.usda@
95+
instanceable = true
96+
)
97+
{ }
98+
def Xform "instance19" (
99+
prepend references = @./kind.usda@
100+
instanceable = true
101+
)
102+
{ }

0 commit comments

Comments
 (0)