1#!/pxrpythonsubst
2#
3# Copyright 2017 Pixar
4#
5# Licensed under the Apache License, Version 2.0 (the "Apache License")
6# with the following modification; you may not use this file except in
7# compliance with the Apache License and the following modification to it:
8# Section 6. Trademarks. is deleted and replaced with:
9#
10# 6. Trademarks. This License does not grant permission to use the trade
11#    names, trademarks, service marks, or product names of the Licensor
12#    and its affiliates, except as required to comply with Section 4(c) of
13#    the License and to reproduce the content of the NOTICE file.
14#
15# You may obtain a copy of the Apache License at
16#
17#     http://www.apache.org/licenses/LICENSE-2.0
18#
19# Unless required by applicable law or agreed to in writing, software
20# distributed under the Apache License with the above modification is
21# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
22# KIND, either express or implied. See the Apache License for the specific
23# language governing permissions and limitations under the Apache License.
24
25from pxr import Sdf, Tf, Usd
26import unittest
27
28class TestUsdInstanceProxy(unittest.TestCase):
29    def _ValidateInstanceProxy(self, expectedPath, prim,
30                               expectedPathInPrototype=False):
31        expectedPath = Sdf.Path(expectedPath)
32
33        # Verify that the instance proxy has the expected path.
34        self.assertEqual(prim.GetPath(), expectedPath)
35
36        # Instance proxies should be identified as such.
37        self.assertTrue(prim)
38        self.assertTrue(prim.IsInstanceProxy())
39
40        # An instance proxy is not in a prototype unless it came from
41        # explicitly traversing within a prototype. For instance, calling
42        # GetPrimAtPath('/__Prototype_1/Instance/Child') will return
43        # an instance proxy at that path, which is inside a prototype.
44        if expectedPathInPrototype:
45            self.assertTrue(prim.IsInPrototype())
46        else:
47            self.assertFalse(prim.IsInPrototype())
48
49    def test_GetPrimAtPath(self):
50        s = Usd.Stage.Open('nested/root.usda')
51
52        # Test that getting a prim for a non-nested instance
53        # does not return an instance proxy.
54        prim = s.GetPrimAtPath('/World/sets/Set_1')
55        self.assertTrue(prim)
56        self.assertFalse(prim.IsInstanceProxy())
57        self.assertTrue(prim.IsInstance())
58
59        # Test getting prims at paths beneath instances and
60        # nested instances
61        for path in ['/World/sets/Set_1/Prop_1',
62                     '/World/sets/Set_1/Prop_1/geom',
63                     '/World/sets/Set_1/Prop_2',
64                     '/World/sets/Set_1/Prop_2/geom',
65                     '/World/sets/Set_2/Prop_1',
66                     '/World/sets/Set_2/Prop_1/geom',
67                     '/World/sets/Set_2/Prop_2',
68                     '/World/sets/Set_2/Prop_2/geom']:
69            self._ValidateInstanceProxy(path, s.GetPrimAtPath(path))
70
71        # Test getting prims at paths beneath instances nested
72        # in prototypes.
73        prototype = s.GetPrimAtPath('/World/sets/Set_1').GetPrototype()
74        for path in [prototype.GetPath().AppendPath('Prop_1/geom'),
75                     prototype.GetPath().AppendPath('Prop_2/geom')]:
76            self._ValidateInstanceProxy(path, s.GetPrimAtPath(path),
77                                        expectedPathInPrototype=True)
78
79    def test_GetParent(self):
80        s = Usd.Stage.Open('nested/root.usda')
81
82        # Test getting parents of instance proxies
83        for path in ['/World/sets/Set_1/Prop_1/geom',
84                     '/World/sets/Set_1/Prop_2/geom',
85                     '/World/sets/Set_2/Prop_1/geom',
86                     '/World/sets/Set_2/Prop_2/geom']:
87            prim = s.GetPrimAtPath(path)
88            self._ValidateInstanceProxy(path, prim)
89
90            prim = prim.GetParent()
91            expectedPath = Sdf.Path(path).GetParentPath()
92            self._ValidateInstanceProxy(expectedPath, prim)
93            self.assertEqual(prim, s.GetPrimAtPath(expectedPath))
94
95            prim = prim.GetParent()
96            expectedPath = Sdf.Path(expectedPath).GetParentPath()
97            self.assertEqual(prim.GetPath(), expectedPath)
98            self.assertFalse(prim.IsInstanceProxy())
99
100        # Test getting parents of instance proxies inside prototypes
101        prototype = s.GetPrimAtPath('/World/sets/Set_1').GetPrototype()
102        for path in [prototype.GetPath().AppendPath('Prop_1/geom'),
103                     prototype.GetPath().AppendPath('Prop_2/geom')]:
104            prim = s.GetPrimAtPath(path)
105            self._ValidateInstanceProxy(path, prim,
106                                        expectedPathInPrototype=True)
107
108            prim = prim.GetParent()
109            path = path.GetParentPath()
110            self.assertEqual(prim.GetPath(), path)
111            self.assertEqual(prim, s.GetPrimAtPath(path))
112            self.assertTrue(prim.IsInstance())
113            self.assertFalse(prim.IsInstanceProxy())
114
115            prim = prim.GetParent()
116            path = path.GetParentPath()
117            self.assertEqual(prim.GetPath(), path)
118            self.assertEqual(prim, s.GetPrimAtPath(path))
119            self.assertTrue(prim.IsPrototype())
120            self.assertFalse(prim.IsInstanceProxy())
121
122    def test_GetChildren(self):
123        s = Usd.Stage.Open('nested/root.usda')
124
125        def _ValidateChildren(parentPath, expectedChildrenPaths):
126            expectedPrims = [s.GetPrimAtPath(p) for p in expectedChildrenPaths]
127
128            parentPrim = s.GetPrimAtPath(parentPath)
129
130            # Children queries on instance proxies will always return
131            # instance proxies.
132            if parentPrim.IsInstanceProxy():
133                children = parentPrim.GetChildren()
134            else:
135                children = parentPrim \
136                    .GetFilteredChildren(Usd.TraverseInstanceProxies())
137            self.assertEqual(expectedPrims, children)
138
139            for (expectedPath, child) in zip(expectedChildrenPaths, children):
140                self._ValidateInstanceProxy(expectedPath, child)
141
142        _ValidateChildren(
143            parentPath = '/World/sets/Set_1',
144            expectedChildrenPaths = [
145                '/World/sets/Set_1/Prop_1',
146                '/World/sets/Set_1/Prop_2'])
147
148        _ValidateChildren(
149            parentPath = '/World/sets/Set_2',
150            expectedChildrenPaths = [
151                '/World/sets/Set_2/Prop_1',
152                '/World/sets/Set_2/Prop_2'])
153
154        _ValidateChildren(
155            parentPath = '/World/sets/Set_1/Prop_1',
156            expectedChildrenPaths = [
157                '/World/sets/Set_1/Prop_1/geom',
158                '/World/sets/Set_1/Prop_1/anim'])
159
160        _ValidateChildren(
161            parentPath = '/World/sets/Set_1/Prop_2',
162            expectedChildrenPaths = [
163                '/World/sets/Set_1/Prop_2/geom',
164                '/World/sets/Set_1/Prop_2/anim'])
165
166        _ValidateChildren(
167            parentPath = '/World/sets/Set_2/Prop_1',
168            expectedChildrenPaths = [
169                '/World/sets/Set_2/Prop_1/geom',
170                '/World/sets/Set_2/Prop_1/anim'])
171
172        _ValidateChildren(
173            parentPath = '/World/sets/Set_2/Prop_2',
174            expectedChildrenPaths = [
175                '/World/sets/Set_2/Prop_2/geom',
176                '/World/sets/Set_2/Prop_2/anim'])
177
178    def test_GetPrimInPrototype(self):
179        s = Usd.Stage.Open('nested/root.usda')
180
181        setPrototype = s.GetPrimAtPath('/World/sets/Set_1').GetPrototype()
182        propPrototype = setPrototype.GetChild('Prop_1').GetPrototype()
183
184        self.assertEqual(
185            s.GetPrimAtPath('/World/sets/Set_1/Prop_1').GetPrimInPrototype(),
186            setPrototype.GetChild('Prop_1'))
187        self.assertEqual(
188            s.GetPrimAtPath('/World/sets/Set_1/Prop_1/geom').GetPrimInPrototype(),
189            propPrototype.GetChild('geom'))
190
191        self.assertEqual(
192            s.GetPrimAtPath('/World/sets/Set_1/Prop_2').GetPrimInPrototype(),
193            setPrototype.GetChild('Prop_2'))
194        self.assertEqual(
195            s.GetPrimAtPath('/World/sets/Set_1/Prop_2/geom').GetPrimInPrototype(),
196            propPrototype.GetChild('geom'))
197
198        self.assertEqual(
199            s.GetPrimAtPath('/World/sets/Set_2/Prop_1').GetPrimInPrototype(),
200            setPrototype.GetChild('Prop_1'))
201        self.assertEqual(
202            s.GetPrimAtPath('/World/sets/Set_2/Prop_1/geom').GetPrimInPrototype(),
203            propPrototype.GetChild('geom'))
204
205        self.assertEqual(
206            s.GetPrimAtPath('/World/sets/Set_2/Prop_2').GetPrimInPrototype(),
207            setPrototype.GetChild('Prop_2'))
208        self.assertEqual(
209            s.GetPrimAtPath('/World/sets/Set_2/Prop_2/geom').GetPrimInPrototype(),
210            propPrototype.GetChild('geom'))
211
212    def test_LoadSet(self):
213        s = Usd.Stage.Open('nested_payloads/root.usda',
214                      Usd.Stage.LoadNone)
215
216        prototype = s.GetPrimAtPath('/World/sets/Set_1').GetPrototype()
217
218        # Note that FindLoadable never returns paths to prims in prototypes.
219        self.assertEqual(
220            s.FindLoadable(),
221            ['/World/sets/Set_1/props/Prop_1',
222             '/World/sets/Set_1/props/Prop_2',
223             '/World/sets/Set_2/props/Prop_1',
224             '/World/sets/Set_2/props/Prop_2'])
225
226        self.assertEqual(
227            s.FindLoadable('/World/sets/Set_1/props'),
228            ['/World/sets/Set_1/props/Prop_1',
229             '/World/sets/Set_1/props/Prop_2'])
230
231        self.assertEqual(
232            s.FindLoadable('/World/sets/Set_2/props'),
233            ['/World/sets/Set_2/props/Prop_1',
234             '/World/sets/Set_2/props/Prop_2'])
235
236        # Load and unload models through instance proxies.
237        self.assertFalse(
238            s.GetPrimAtPath('/World/sets/Set_1/props/Prop_1').IsLoaded())
239        self.assertFalse(
240            s.GetPrimAtPath('/World/sets/Set_1/props/Prop_2').IsLoaded())
241        self.assertFalse(
242            s.GetPrimAtPath('/World/sets/Set_2/props/Prop_1').IsLoaded())
243        self.assertFalse(
244            s.GetPrimAtPath('/World/sets/Set_2/props/Prop_2').IsLoaded())
245
246        s.GetPrimAtPath('/World/sets/Set_1/props/Prop_1').Load()
247        self.assertTrue(
248            s.GetPrimAtPath('/World/sets/Set_1/props/Prop_1').IsLoaded())
249        self.assertFalse(
250            s.GetPrimAtPath('/World/sets/Set_1/props/Prop_2').IsLoaded())
251        self.assertFalse(
252            s.GetPrimAtPath('/World/sets/Set_2/props/Prop_1').IsLoaded())
253        self.assertFalse(
254            s.GetPrimAtPath('/World/sets/Set_2/props/Prop_2').IsLoaded())
255
256        s.GetPrimAtPath('/World/sets/Set_2/props/Prop_2').Load()
257        self.assertTrue(
258            s.GetPrimAtPath('/World/sets/Set_1/props/Prop_1').IsLoaded())
259        self.assertFalse(
260            s.GetPrimAtPath('/World/sets/Set_1/props/Prop_2').IsLoaded())
261        self.assertFalse(
262            s.GetPrimAtPath('/World/sets/Set_2/props/Prop_1').IsLoaded())
263        self.assertTrue(
264            s.GetPrimAtPath('/World/sets/Set_2/props/Prop_2').IsLoaded())
265
266        s.LoadAndUnload([], ['/World/sets/Set_1/props'])
267        self.assertFalse(
268            s.GetPrimAtPath('/World/sets/Set_1/props/Prop_1').IsLoaded())
269        self.assertFalse(
270            s.GetPrimAtPath('/World/sets/Set_1/props/Prop_2').IsLoaded())
271        self.assertFalse(
272            s.GetPrimAtPath('/World/sets/Set_2/props/Prop_1').IsLoaded())
273        self.assertTrue(
274            s.GetPrimAtPath('/World/sets/Set_2/props/Prop_2').IsLoaded())
275
276    def test_PrimRange(self):
277        s = Usd.Stage.Open('nested/root.usda')
278
279        # Test iterating over all prims on the stage
280        expectedPrims = [s.GetPrimAtPath(p) for p in
281            ['/World',
282             '/World/sets',
283             '/World/sets/Set_1',
284             '/World/sets/Set_1/Prop_1',
285             '/World/sets/Set_1/Prop_1/geom',
286             '/World/sets/Set_1/Prop_1/anim',
287             '/World/sets/Set_1/Prop_2',
288             '/World/sets/Set_1/Prop_2/geom',
289             '/World/sets/Set_1/Prop_2/anim',
290             '/World/sets/Set_2',
291             '/World/sets/Set_2/Prop_1',
292             '/World/sets/Set_2/Prop_1/geom',
293             '/World/sets/Set_2/Prop_1/anim',
294             '/World/sets/Set_2/Prop_2',
295             '/World/sets/Set_2/Prop_2/geom',
296             '/World/sets/Set_2/Prop_2/anim']
297        ]
298
299        gotPrims = list(Usd.PrimRange.Stage(s, Usd.TraverseInstanceProxies()))
300        self.assertEqual(expectedPrims, gotPrims)
301
302        # Test getting instance proxy descendants from each instance.
303        def _ValidateInstanceDescendants(parentPath, expectedDescendantPaths):
304            parent = s.GetPrimAtPath(parentPath)
305            descendants = \
306                list(Usd.PrimRange(parent, Usd.TraverseInstanceProxies()))
307            expectedDescendants = \
308                [s.GetPrimAtPath(p) for p in expectedDescendantPaths]
309            self.assertEqual(expectedDescendants, descendants)
310
311        _ValidateInstanceDescendants(
312            parentPath = '/World/sets/Set_1',
313            expectedDescendantPaths = [
314                '/World/sets/Set_1',
315                '/World/sets/Set_1/Prop_1',
316                '/World/sets/Set_1/Prop_1/geom',
317                '/World/sets/Set_1/Prop_1/anim',
318                '/World/sets/Set_1/Prop_2',
319                '/World/sets/Set_1/Prop_2/geom',
320                '/World/sets/Set_1/Prop_2/anim'])
321
322        _ValidateInstanceDescendants(
323            parentPath = '/World/sets/Set_1/Prop_1',
324            expectedDescendantPaths = [
325                '/World/sets/Set_1/Prop_1',
326                '/World/sets/Set_1/Prop_1/geom',
327                '/World/sets/Set_1/Prop_1/anim'])
328
329        _ValidateInstanceDescendants(
330            parentPath = '/World/sets/Set_1/Prop_2',
331            expectedDescendantPaths = [
332                '/World/sets/Set_1/Prop_2',
333                '/World/sets/Set_1/Prop_2/geom',
334                '/World/sets/Set_1/Prop_2/anim'])
335
336        _ValidateInstanceDescendants(
337            parentPath = '/World/sets/Set_2',
338            expectedDescendantPaths = [
339                '/World/sets/Set_2',
340                '/World/sets/Set_2/Prop_1',
341                '/World/sets/Set_2/Prop_1/geom',
342                '/World/sets/Set_2/Prop_1/anim',
343                '/World/sets/Set_2/Prop_2',
344                '/World/sets/Set_2/Prop_2/geom',
345                '/World/sets/Set_2/Prop_2/anim'])
346
347        _ValidateInstanceDescendants(
348            parentPath = '/World/sets/Set_2/Prop_1',
349            expectedDescendantPaths = [
350                '/World/sets/Set_2/Prop_1',
351                '/World/sets/Set_2/Prop_1/geom',
352                '/World/sets/Set_2/Prop_1/anim'])
353
354        _ValidateInstanceDescendants(
355            parentPath = '/World/sets/Set_2/Prop_2',
356            expectedDescendantPaths = [
357                '/World/sets/Set_2/Prop_2',
358                '/World/sets/Set_2/Prop_2/geom',
359                '/World/sets/Set_2/Prop_2/anim'])
360
361        # Test iterating starting from a prototype prim
362        prototype = s.GetPrimAtPath('/World/sets/Set_1').GetPrototype()
363        _ValidateInstanceDescendants(
364            parentPath = prototype.GetPath(),
365            expectedDescendantPaths = [
366                prototype.GetPath(),
367                prototype.GetPath().AppendPath('Prop_1'),
368                prototype.GetPath().AppendPath('Prop_1/geom'),
369                prototype.GetPath().AppendPath('Prop_1/anim'),
370                prototype.GetPath().AppendPath('Prop_2'),
371                prototype.GetPath().AppendPath('Prop_2/geom'),
372                prototype.GetPath().AppendPath('Prop_2/anim')])
373
374        prototype = s.GetPrimAtPath('/World/sets/Set_1/Prop_1').GetPrototype()
375        _ValidateInstanceDescendants(
376            parentPath = prototype.GetPath(),
377            expectedDescendantPaths = [
378                prototype.GetPath(),
379                prototype.GetPath().AppendPath('geom'),
380                prototype.GetPath().AppendPath('anim')])
381
382    def test_GetAttributeValue(self):
383        s = Usd.Stage.Open('nested/root.usda')
384
385        def _ValidateAttributeValue(attrPath, expectedValue):
386            attrPath = Sdf.Path(attrPath)
387            prim = s.GetPrimAtPath(attrPath.GetPrimPath())
388            self._ValidateInstanceProxy(attrPath.GetPrimPath(), prim)
389
390            attr = prim.GetAttribute(attrPath.name)
391            self.assertTrue(attr)
392            self.assertEqual(attr.GetPath(), attrPath)
393            self.assertEqual(attr.Get(), expectedValue)
394
395        _ValidateAttributeValue(
396            attrPath = '/World/sets/Set_1/Prop_1/geom.x', expectedValue = 1.0)
397
398        _ValidateAttributeValue(
399            attrPath = '/World/sets/Set_1/Prop_2/geom.x', expectedValue = 1.0)
400
401        _ValidateAttributeValue(
402            attrPath = '/World/sets/Set_2/Prop_1/geom.x', expectedValue = 1.0)
403
404        _ValidateAttributeValue(
405            attrPath = '/World/sets/Set_2/Prop_2/geom.x', expectedValue = 1.0)
406
407    def test_GetRelationshipTargets(self):
408        s = Usd.Stage.Open('rels/root.usda')
409
410        def _ValidateRelationshipTargets(relPath, expectedTargets):
411            relPath = Sdf.Path(relPath)
412            prim = s.GetPrimAtPath(relPath.GetPrimPath())
413            self._ValidateInstanceProxy(relPath.GetPrimPath(), prim)
414
415            rel = prim.GetRelationship(relPath.name)
416            self.assertTrue(rel)
417            self.assertEqual(rel.GetPath(), relPath)
418            self.assertEqual(
419                rel.GetTargets(), [Sdf.Path(p) for p in expectedTargets])
420
421        _ValidateRelationshipTargets(
422            relPath = '/Root/Instance_1/A.rel',
423            expectedTargets = [
424                '/Root/Instance_1',
425                '/Root/Instance_1.attr',
426                '/Root/Instance_1/A',
427                '/Root/Instance_1/A.attr',
428                '/Root/Instance_1/NestedInstance_1',
429                '/Root/Instance_1/NestedInstance_1.attr',
430                '/Root/Instance_1/NestedInstance_1/B',
431                '/Root/Instance_1/NestedInstance_1/B.attr',
432                '/Root/Instance_1/NestedInstance_2',
433                '/Root/Instance_1/NestedInstance_2.attr',
434                '/Root/Instance_1/NestedInstance_2/B',
435                '/Root/Instance_1/NestedInstance_2/B.attr'])
436
437        _ValidateRelationshipTargets(
438            relPath = '/Root/Instance_2/A.rel',
439            expectedTargets = [
440                '/Root/Instance_2',
441                '/Root/Instance_2.attr',
442                '/Root/Instance_2/A',
443                '/Root/Instance_2/A.attr',
444                '/Root/Instance_2/NestedInstance_1',
445                '/Root/Instance_2/NestedInstance_1.attr',
446                '/Root/Instance_2/NestedInstance_1/B',
447                '/Root/Instance_2/NestedInstance_1/B.attr',
448                '/Root/Instance_2/NestedInstance_2',
449                '/Root/Instance_2/NestedInstance_2.attr',
450                '/Root/Instance_2/NestedInstance_2/B',
451                '/Root/Instance_2/NestedInstance_2/B.attr'])
452
453        _ValidateRelationshipTargets(
454            relPath = '/Root/Instance_1/NestedInstance_1/B.rel',
455            expectedTargets = [
456                '/Root/Instance_1/NestedInstance_1/B',
457                '/Root/Instance_1/NestedInstance_1/B.attr'])
458
459        _ValidateRelationshipTargets(
460            relPath = '/Root/Instance_1/NestedInstance_2/B.rel',
461            expectedTargets = [
462                '/Root/Instance_1/NestedInstance_2/B',
463                '/Root/Instance_1/NestedInstance_2/B.attr'])
464
465        _ValidateRelationshipTargets(
466            relPath = '/Root/Instance_2/NestedInstance_1/B.rel',
467            expectedTargets = [
468                '/Root/Instance_2/NestedInstance_1/B',
469                '/Root/Instance_2/NestedInstance_1/B.attr'])
470
471        _ValidateRelationshipTargets(
472            relPath = '/Root/Instance_2/NestedInstance_2/B.rel',
473            expectedTargets = [
474                '/Root/Instance_2/NestedInstance_2/B',
475                '/Root/Instance_2/NestedInstance_2/B.attr'])
476
477    def test_GetConnections(self):
478        s = Usd.Stage.Open('attrs/root.usda')
479
480        def _ValidateConnections(attrPath, expectedSrcs):
481            attrPath = Sdf.Path(attrPath)
482            prim = s.GetPrimAtPath(attrPath.GetPrimPath())
483            self._ValidateInstanceProxy(attrPath.GetPrimPath(), prim)
484
485            attr = prim.GetAttribute(attrPath.name)
486            self.assertTrue(attr)
487            self.assertEqual(attr.GetPath(), attrPath)
488            self.assertEqual(
489                attr.GetConnections(), [Sdf.Path(p) for p in expectedSrcs])
490
491        _ValidateConnections(
492            attrPath = '/Root/Instance_1/A.con',
493            expectedSrcs = [
494                '/Root/Instance_1',
495                '/Root/Instance_1.attr',
496                '/Root/Instance_1/A',
497                '/Root/Instance_1/A.attr',
498                '/Root/Instance_1/NestedInstance_1',
499                '/Root/Instance_1/NestedInstance_1.attr',
500                '/Root/Instance_1/NestedInstance_1/B',
501                '/Root/Instance_1/NestedInstance_1/B.attr',
502                '/Root/Instance_1/NestedInstance_2',
503                '/Root/Instance_1/NestedInstance_2.attr',
504                '/Root/Instance_1/NestedInstance_2/B',
505                '/Root/Instance_1/NestedInstance_2/B.attr'])
506
507        _ValidateConnections(
508            attrPath = '/Root/Instance_2/A.con',
509            expectedSrcs = [
510                '/Root/Instance_2',
511                '/Root/Instance_2.attr',
512                '/Root/Instance_2/A',
513                '/Root/Instance_2/A.attr',
514                '/Root/Instance_2/NestedInstance_1',
515                '/Root/Instance_2/NestedInstance_1.attr',
516                '/Root/Instance_2/NestedInstance_1/B',
517                '/Root/Instance_2/NestedInstance_1/B.attr',
518                '/Root/Instance_2/NestedInstance_2',
519                '/Root/Instance_2/NestedInstance_2.attr',
520                '/Root/Instance_2/NestedInstance_2/B',
521                '/Root/Instance_2/NestedInstance_2/B.attr'])
522
523        _ValidateConnections(
524            attrPath = '/Root/Instance_1/NestedInstance_1/B.con',
525            expectedSrcs = [
526                '/Root/Instance_1/NestedInstance_1/B',
527                '/Root/Instance_1/NestedInstance_1/B.attr'])
528
529        _ValidateConnections(
530            attrPath = '/Root/Instance_1/NestedInstance_2/B.con',
531            expectedSrcs = [
532                '/Root/Instance_1/NestedInstance_2/B',
533                '/Root/Instance_1/NestedInstance_2/B.attr'])
534
535        _ValidateConnections(
536            attrPath = '/Root/Instance_2/NestedInstance_1/B.con',
537            expectedSrcs = [
538                '/Root/Instance_2/NestedInstance_1/B',
539                '/Root/Instance_2/NestedInstance_1/B.attr'])
540
541        _ValidateConnections(
542            attrPath = '/Root/Instance_2/NestedInstance_2/B.con',
543            expectedSrcs = [
544                '/Root/Instance_2/NestedInstance_2/B',
545                '/Root/Instance_2/NestedInstance_2/B.attr'])
546
547    def test_Editing(self):
548        """Test that edits cannot be made on instance proxies"""
549
550        # Verify that edits cannot be made via instance proxies
551        # in the local layer stack, since they represent prims
552        # beneath instances and those opinions would be ignored.
553        s = Usd.Stage.Open('nested/root.usda')
554
555        proxy = s.GetPrimAtPath('/World/sets/Set_1/Prop_1')
556        assert proxy
557        assert proxy.IsInstanceProxy()
558
559        with self.assertRaises(Tf.ErrorException):
560            s.DefinePrim(proxy.GetPath())
561        with self.assertRaises(Tf.ErrorException):
562            s.OverridePrim(proxy.GetPath())
563        with self.assertRaises(Tf.ErrorException):
564            s.CreateClassPrim(proxy.GetPath())
565
566        with self.assertRaises(Tf.ErrorException):
567            proxy.SetDocumentation('test')
568        with self.assertRaises(Tf.ErrorException):
569            proxy.ClearDocumentation()
570        with self.assertRaises(Tf.ErrorException):
571            proxy.CreateRelationship('testRel')
572        with self.assertRaises(Tf.ErrorException):
573            proxy.CreateAttribute('testAttr', Sdf.ValueTypeNames.Int)
574
575        attrInProxy = proxy.GetChild('geom').GetAttribute('x')
576        assert attrInProxy
577
578        with self.assertRaises(Tf.ErrorException):
579            attrInProxy.SetDocumentation('test')
580        with self.assertRaises(Tf.ErrorException):
581            attrInProxy.ClearDocumentation()
582        with self.assertRaises(Tf.ErrorException):
583            attrInProxy.Set(2.0, time=1.0)
584        with self.assertRaises(Tf.ErrorException):
585            attrInProxy.Set(2.0, time=Usd.TimeCode.Default())
586        with self.assertRaises(Tf.ErrorException):
587            attrInProxy.Clear()
588        with self.assertRaises(Tf.ErrorException):
589            attrInProxy.ClearAtTime(time=1.0)
590        with self.assertRaises(Tf.ErrorException):
591            attrInProxy.SetConnections(['/Some/Connection'])
592
593        relInProxy = proxy.GetChild('geom').GetRelationship('y')
594        assert relInProxy
595
596        with self.assertRaises(Tf.ErrorException):
597            relInProxy.SetDocumentation('test')
598        with self.assertRaises(Tf.ErrorException):
599            relInProxy.ClearDocumentation()
600        with self.assertRaises(Tf.ErrorException):
601            relInProxy.SetTargets(['/Some/Target'])
602
603if __name__ == '__main__':
604    unittest.main()
605