Exemplo n.º 1
0
    def test_Basic(self):
        rootLayer = Sdf.Layer.FindOrOpen('bug90706/root.sdf')
        pcpCache = Pcp.Cache(Pcp.LayerStackIdentifier(rootLayer))

        (index, err) = pcpCache.ComputePrimIndex('/Sarah/EmptyPrim')
        self.assertTrue(index)
        self.assertEqual(len(err), 0)

        # This prim index should only contain the root node; the variant
        # arc to /Sarah{displayColor=red}EmptyPrim will have been culled
        # because there's no prim spec there.
        self.assertEqual(len(index.rootNode.children), 0)

        with Pcp._TestChangeProcessor(pcpCache):
            p = Sdf.CreatePrimInLayer(rootLayer,
                                      '/Sarah{displayColor=red}EmptyPrim')

        # The addition of the inert prim should have caused the prim index
        # to be blown, because it needs to be re-computed to accommodate the
        # no-longer-inert variant node.
        self.assertFalse(pcpCache.FindPrimIndex('/Sarah/EmptyPrim'))
        (index, err) = pcpCache.ComputePrimIndex('/Sarah/EmptyPrim')
        self.assertTrue(index)
        self.assertEqual(len(err), 0)

        # There should now be a variant arc for /Sarah{displayColor=red}EmptyPrim
        # in the local layer stack.
        self.assertEqual(len(index.rootNode.children), 1)
        self.assertEqual(index.rootNode.children[0].arcType,
                         Pcp.ArcTypeVariant)
        self.assertEqual(index.rootNode.children[0].layerStack,
                         index.rootNode.layerStack)
        self.assertEqual(index.rootNode.children[0].path,
                         '/Sarah{displayColor=red}EmptyPrim')
Exemplo n.º 2
0
        def _Test(referencingLayer):
            # Make a PcpCache.
            pcp = Pcp.Cache(Pcp.LayerStackIdentifier(referencingLayer))

            (pi, err) = pcp.ComputePrimIndex('/source')

            # First child node should be the referenced target1.
            self.assertEqual(pi.rootNode.children[0].path, '/target1')

            # Now clear defaultPrim.  This should issue an error and
            # fail to pick up the referenced prim.
            with Pcp._TestChangeProcessor(pcp):
                targLyr.ClearDefaultPrim()

            (pi, err) = pcp.ComputePrimIndex('/source')
            self.assertTrue(isinstance(err[0], Pcp.ErrorUnresolvedPrimPath))
            # If the reference to the defaultPrim is an external reference,
            # the one child node should be the pseudoroot dependency placeholder.
            # If the reference is an internal reference, that dependency
            # placeholder is unneeded.
            if referencingLayer != targLyr:
                self.assertEqual(len(pi.rootNode.children), 1)
                self.assertEqual(pi.rootNode.children[0].path, '/')

            # Change defaultPrim to other target.  This should pick
            # up the reference again, but to the new prim target2.
            with Pcp._TestChangeProcessor(pcp):
                targLyr.defaultPrim = 'target2'

            (pi, err) = pcp.ComputePrimIndex('/source')
            self.assertEqual(len(err), 0)
            self.assertEqual(pi.rootNode.children[0].path, '/target2')

            # Reset defaultPrim to original target
            targLyr.defaultPrim = 'target1'
Exemplo n.º 3
0
    def test_Basic(self):
        # Create a PcpCache for a reference chain, but do not perform any actual
        # composition before querying its used layers. Verify that this does not crash.
        file = 'BasicReference/root.sdf'
        self.assertTrue(os.path.isfile(file))
        layer = Sdf.Layer.FindOrOpen(file)
        self.assertTrue(layer)
        lsi = Pcp.LayerStackIdentifier(layer)
        self.assertTrue(lsi)
        pcpCache = Pcp.Cache(lsi)
        self.assertTrue(pcpCache)
        pcpCache.GetUsedLayers()

        # Create a PcpCache with a file format target, ensuring that layers
        # without the correct target will be marked invalid during composition.
        pcpCache = Pcp.Cache(lsi, fileFormatTarget='sdf')
        (pi, _) = pcpCache.ComputePrimIndex('/PrimWithReferences')
        self.assertTrue(pi.IsValid())
        self.assertEqual(len(pi.localErrors), 0)

        # Should be two local errors corresponding to invalid asset paths,
        # since this prim has two references to layers with a different target.
        pcpCache = Pcp.Cache(lsi, fileFormatTarget='Presto')
        (pi, _) = pcpCache.ComputePrimIndex('/PrimWithReferences')
        self.assertTrue(pi.IsValid())
        self.assertEqual(len(pi.localErrors), 2)
        self.assertTrue(
            all([(isinstance(e, Pcp.ErrorInvalidAssetPath)
                  for e in pi.localErrors)]))
    def test_Basic(self):
        rootLayer = Sdf.Layer.FindOrOpen('bug92955/root.sdf')
        pcpCache = Pcp.Cache(Pcp.LayerStackIdentifier(rootLayer))

        # Populate all prims in the scene
        paths = [Sdf.Path('/')]
        while paths:
            path, paths = paths[0], paths[1:]
            primIndex, _ = pcpCache.ComputePrimIndex(path)
            for name in primIndex.ComputePrimChildNames()[0]:
                paths.append(path.AppendChild(name))

        # Verify there are symmetric corresponding paths on SymRig.
        layerStack = pcpCache.layerStack
        x = pcpCache.FindSiteDependencies(layerStack, '/Model/Rig/SymRig',
                                        Pcp.DependencyTypeDirect |
                                        Pcp.DependencyTypeNonVirtual)
        self.assertNotEqual(len(x), 0)

        # Delete the unrelated class.
        with Pcp._TestChangeProcessor(pcpCache):
            del rootLayer.GetPrimAtPath('/Model/Rig').nameChildren['SymScope']

        # Verify the same symmetric corresponding paths are on SymRig.
        y = pcpCache.FindSiteDependencies(layerStack, '/Model/Rig/SymRig',
                                        Pcp.DependencyTypeDirect |
                                        Pcp.DependencyTypeNonVirtual)
        self.assertEqual(x, y)
Exemplo n.º 5
0
    def test_EmptySublayerChanges(self):
        subLayer1 = Sdf.Layer.CreateAnonymous()
        primSpec = Sdf.CreatePrimInLayer(subLayer1, '/Test')

        rootLayer = Sdf.Layer.CreateAnonymous()
        rootLayer.subLayerPaths.append(subLayer1.identifier)

        layerStackId = Pcp.LayerStackIdentifier(rootLayer)
        pcp = Pcp.Cache(layerStackId)

        (pi, err) = pcp.ComputePrimIndex('/Test')
        self.assertFalse(err)
        self.assertEqual(pi.primStack, [primSpec])

        subLayer2 = Sdf.Layer.CreateAnonymous()
        self.assertTrue(subLayer2.empty)

        # Adding an empty sublayer should not require recomputing any
        # prim indexes or change their prim stacks.
        with Pcp._TestChangeProcessor(pcp):
            rootLayer.subLayerPaths.insert(0, subLayer2.identifier)

        pi = pcp.FindPrimIndex('/Test')
        self.assertTrue(pi)
        self.assertEqual(pi.primStack, [primSpec])

        # Same with deleting an empty sublayer.
        with Pcp._TestChangeProcessor(pcp):
            del rootLayer.subLayerPaths[0]

        pi = pcp.FindPrimIndex('/Test')
        self.assertTrue(pi)
        self.assertEqual(pi.primStack, [primSpec])
Exemplo n.º 6
0
    def test_Basic(self):
        rootLayer = Sdf.Layer.FindOrOpen('bug70951/root.sdf')
        refLayer = Sdf.Layer.FindOrOpen('bug70951/JoyGroup.sdf')

        pcpCache = Pcp.Cache(Pcp.LayerStackIdentifier(rootLayer))

        # Compute the prim index for the Sim scope under JoyGroup. This index
        # should consist of two nodes: the direct node and the reference node.
        # Since there is no spec for the Sim scope in the root layer, the root node
        # should be marked as such.
        (primIndex, errors) = \
            pcpCache.ComputePrimIndex('/World/anim/chars/JoyGroup/Sim')
        self.assertEqual(len(errors), 0)
        self.assertEqual(primIndex.primStack,
                         [refLayer.GetPrimAtPath('/JoyGroup/Sim')])
        self.assertFalse(primIndex.rootNode.hasSpecs)

        # Now create an empty over for the Sim scope in the root layer and verify
        # that the prim index sees this new spec after change processing.
        with Pcp._TestChangeProcessor(pcpCache):
            emptyOver = \
                Sdf.CreatePrimInLayer(rootLayer, '/World/anim/chars/JoyGroup/Sim')
            self.assertTrue(emptyOver.IsInert())

        (primIndex, errors) = \
            pcpCache.ComputePrimIndex('/World/anim/chars/JoyGroup/Sim')
        self.assertEqual(len(errors), 0)
        self.assertEqual(primIndex.primStack, [
            rootLayer.GetPrimAtPath('/World/anim/chars/JoyGroup/Sim'),
            refLayer.GetPrimAtPath('/JoyGroup/Sim')
        ])
        self.assertTrue(primIndex.rootNode.hasSpecs)
Exemplo n.º 7
0
    def test_Basic(self):
        rootLayer = Sdf.Layer.FindOrOpen('bug101300/root.sdf')
        pcpCache = Pcp.Cache(Pcp.LayerStackIdentifier(rootLayer))

        # Compute the prim index for /Root/A. The relocates authored on /Root/A
        # should be applied, causing /Root/A/B to be renamed /Root/A/B_2.
        (pi, err) = pcpCache.ComputePrimIndex('/Root/A')
        self.assertEqual(len(err), 0)
        self.assertEqual(pi.ComputePrimChildNames(), (['B_2'],['B']))
        self.assertEqual(pcpCache.layerStack.relocatesSourceToTarget,
                    {Sdf.Path('/Root/A/B'): Sdf.Path('/Root/A/B_2')})
        self.assertEqual(pcpCache.layerStack.pathsToPrimsWithRelocates,
                    [Sdf.Path('/Root/A')])

        # Remove the over on /Root/A that provides the relocates. 
        with Pcp._TestChangeProcessor(pcpCache):
            del rootLayer.GetPrimAtPath('/Root').nameChildren['A']

        # The prim at /Root/A should still exist, but there should no longer be
        # any relocates to apply.
        (pi, err) = pcpCache.ComputePrimIndex('/Root/A')
        self.assertEqual(len(err), 0)
        self.assertEqual(pi.ComputePrimChildNames(), (['B'],[]))
        self.assertEqual(pcpCache.layerStack.relocatesSourceToTarget, {})
        self.assertEqual(pcpCache.layerStack.pathsToPrimsWithRelocates, [])
Exemplo n.º 8
0
    def test_SublayerOffsetChanges(self):
        rootLayerPath = 'TestSublayerOffsetChanges/root.sdf'
        rootSublayerPath = 'TestSublayerOffsetChanges/root-sublayer.sdf'
        refLayerPath = 'TestSublayerOffsetChanges/ref.sdf'
        refSublayerPath = 'TestSublayerOffsetChanges/ref-sublayer.sdf'
        ref2LayerPath = 'TestSublayerOffsetChanges/ref2.sdf'

        rootLayer = Sdf.Layer.FindOrOpen(rootLayerPath)
        pcp = Pcp.Cache(Pcp.LayerStackIdentifier(rootLayer))

        (pi, err) = pcp.ComputePrimIndex('/A')
        self.assertTrue(pi)
        self.assertEqual(len(err), 0)

        # Verify the expected structure of the test asset. It should simply be
        # a chain of two references, with layer offsets of 100.0 and 50.0
        # respectively.
        refNode = pi.rootNode.children[0]
        self.assertEqual(
            refNode.layerStack.layers,
            [Sdf.Layer.Find(refLayerPath),
             Sdf.Layer.Find(refSublayerPath)])
        self.assertEqual(refNode.arcType, Pcp.ArcTypeReference)
        self.assertEqual(refNode.mapToRoot.timeOffset, Sdf.LayerOffset(100.0))

        ref2Node = refNode.children[0]
        self.assertEqual(ref2Node.layerStack.layers,
                         [Sdf.Layer.Find(ref2LayerPath)])
        self.assertEqual(ref2Node.arcType, Pcp.ArcTypeReference)
        self.assertEqual(ref2Node.mapToRoot.timeOffset, Sdf.LayerOffset(150.0))

        # Change the layer offset in the local layer stack and verify that
        # invalidates the prim index and that the updated layer offset is
        # taken into account after recomputing the index.
        with Pcp._TestChangeProcessor(pcp):
            rootLayer.subLayerOffsets[0] = Sdf.LayerOffset(200.0)

        self.assertFalse(pcp.FindPrimIndex('/A'))
        (pi, err) = pcp.ComputePrimIndex('/A')
        refNode = pi.rootNode.children[0]
        ref2Node = refNode.children[0]

        self.assertEqual(refNode.mapToRoot.timeOffset, Sdf.LayerOffset(200.0))
        self.assertEqual(ref2Node.mapToRoot.timeOffset, Sdf.LayerOffset(250.0))

        # Change the layer offset in a referenced layer stack and again verify
        # that the prim index is invalidated and the updated layer offset is
        # taken into account.
        refLayer = refNode.layerStack.layers[0]
        with Pcp._TestChangeProcessor(pcp):
            refLayer.subLayerOffsets[0] = Sdf.LayerOffset(200.0)

        self.assertFalse(pcp.FindPrimIndex('/A'))
        (pi, err) = pcp.ComputePrimIndex('/A')
        refNode = pi.rootNode.children[0]
        ref2Node = refNode.children[0]

        self.assertEqual(refNode.mapToRoot.timeOffset, Sdf.LayerOffset(200.0))
        self.assertEqual(ref2Node.mapToRoot.timeOffset, Sdf.LayerOffset(400.0))
Exemplo n.º 9
0
 def _FindSiteDeps(self, rootLayerPath, siteLayerPath, sitePath,
                   depMask = Pcp.DependencyTypeAnyNonVirtual,
                   recurseOnSite = False,
                   recurseOnIndex = False):
     sitePath = Sdf.Path(sitePath)
     self.assertFalse(sitePath.isEmpty)
     rootLayer = Sdf.Layer.FindOrOpen(rootLayerPath)
     self.assertTrue(rootLayer)
     siteLayer = Sdf.Layer.FindOrOpen(siteLayerPath)
     self.assertTrue(siteLayer)
     cache = Pcp.Cache( Pcp.LayerStackIdentifier(rootLayer) )
     siteLayerStack = cache.ComputeLayerStack(
         Pcp.LayerStackIdentifier(siteLayer))[0]
     self.assertTrue(siteLayerStack)
     self._ForcePopulateCache(cache)
     return cache.FindSiteDependencies( siteLayerStack, sitePath, depMask,
                                        recurseOnSite, recurseOnIndex,
                                        False )
Exemplo n.º 10
0
    def test_InertPrimRemovalChanges(self):
        subLayer = Sdf.Layer.CreateAnonymous()
        subParentSpec = Sdf.PrimSpec(subLayer, 'Parent', Sdf.SpecifierDef)
        subChildSpec = Sdf.PrimSpec(subParentSpec, 'Child', Sdf.SpecifierDef)
        subAttrSpec = Sdf.AttributeSpec(subChildSpec, 'attr',
                                        Sdf.ValueTypeNames.Double)
        subAttrSpec.default = 1.0

        rootLayer = Sdf.Layer.CreateAnonymous()
        rootParentSpec = Sdf.PrimSpec(rootLayer, 'Parent', Sdf.SpecifierOver)
        rootChildSpec = Sdf.PrimSpec(rootParentSpec, 'Child',
                                     Sdf.SpecifierOver)
        rootAttrSpec = Sdf.AttributeSpec(rootChildSpec, 'attr',
                                         Sdf.ValueTypeNames.Double)
        rootLayer.subLayerPaths.append(subLayer.identifier)

        pcp = Pcp.Cache(Pcp.LayerStackIdentifier(rootLayer))

        (pi, err) = pcp.ComputePrimIndex('/Parent')
        self.assertEqual(err, [])
        self.assertEqual(pi.primStack, [rootParentSpec, subParentSpec])

        (pi, err) = pcp.ComputePrimIndex('/Parent/Child')
        self.assertEqual(err, [])
        self.assertEqual(pi.primStack, [rootChildSpec, subChildSpec])

        (pi, err) = pcp.ComputePropertyIndex('/Parent/Child.attr')
        self.assertEqual(err, [])
        self.assertEqual(pi.propertyStack, [rootAttrSpec, subAttrSpec])

        revCount = pcp.GetUsedLayersRevision()
        with Pcp._TestChangeProcessor(pcp) as cp:
            del rootLayer.pseudoRoot.nameChildren['Parent']
            self.assertFalse(rootParentSpec)
            self.assertFalse(rootChildSpec)
            self.assertFalse(rootAttrSpec)

            self.assertEqual(cp.GetSignificantChanges(), [])
            self.assertEqual(
                cp.GetSpecChanges(),
                ['/Parent', '/Parent/Child', '/Parent/Child.attr'])
            self.assertEqual(cp.GetPrimChanges(), [])

        self.assertEqual(revCount, pcp.GetUsedLayersRevision())

        (pi, err) = pcp.ComputePrimIndex('/Parent')
        self.assertEqual(err, [])
        self.assertEqual(pi.primStack, [subParentSpec])

        (pi, err) = pcp.ComputePrimIndex('/Parent/Child')
        self.assertEqual(err, [])
        self.assertEqual(pi.primStack, [subChildSpec])

        (pi, err) = pcp.ComputePropertyIndex('/Parent/Child.attr')
        self.assertEqual(err, [])
        self.assertEqual(pi.propertyStack, [subAttrSpec])
Exemplo n.º 11
0
    def test_InstancingChanges(self):
        refLayer = Sdf.Layer.CreateAnonymous()
        refParentSpec = Sdf.PrimSpec(refLayer, 'Parent', Sdf.SpecifierDef)
        refChildSpec = Sdf.PrimSpec(refParentSpec, 'RefChild',
                                    Sdf.SpecifierDef)

        rootLayer = Sdf.Layer.CreateAnonymous()
        parentSpec = Sdf.PrimSpec(rootLayer, 'Parent', Sdf.SpecifierOver)
        parentSpec.referenceList.Add(
            Sdf.Reference(refLayer.identifier, '/Parent'))
        childSpec = Sdf.PrimSpec(parentSpec, 'DirectChild', Sdf.SpecifierDef)

        # Instancing is only enabled in Usd mode.
        pcp = Pcp.Cache(Pcp.LayerStackIdentifier(rootLayer), usd=True)

        # /Parent is initially not tagged as an instance, so we should
        # see both RefChild and DirectChild name children.
        (pi, err) = pcp.ComputePrimIndex('/Parent')
        self.assertEqual(len(err), 0)
        self.assertFalse(pi.IsInstanceable())
        self.assertEqual(pi.ComputePrimChildNames(),
                         (['RefChild', 'DirectChild'], []))

        with Pcp._TestChangeProcessor(pcp) as cp:
            parentSpec.instanceable = True
            self.assertEqual(cp.GetSignificantChanges(), ['/Parent'])
            self.assertEqual(cp.GetSpecChanges(), [])
            self.assertEqual(cp.GetPrimChanges(), [])

        # After being made an instance, DirectChild should no longer
        # be reported as a name child since instances may not introduce
        # new prims locally.
        (pi, err) = pcp.ComputePrimIndex('/Parent')
        self.assertEqual(len(err), 0)
        self.assertTrue(pi.IsInstanceable())
        self.assertEqual(pi.ComputePrimChildNames(), (['RefChild'], []))

        with Pcp._TestChangeProcessor(pcp) as cp:
            parentSpec.instanceable = False
            self.assertEqual(cp.GetSignificantChanges(), ['/Parent'])
            self.assertEqual(cp.GetSpecChanges(), [])
            self.assertEqual(cp.GetPrimChanges(), [])

        # Flipping the instance flag back should restore us to the
        # original state.
        (pi, err) = pcp.ComputePrimIndex('/Parent')
        self.assertEqual(len(err), 0)
        self.assertFalse(pi.IsInstanceable())
        self.assertEqual(pi.ComputePrimChildNames(),
                         (['RefChild', 'DirectChild'], []))
Exemplo n.º 12
0
    def test_Basic(self):
        rootLayer = Sdf.Layer.FindOrOpen('bug82180/root.sdf')
        sessionLayer = Sdf.Layer.CreateAnonymous()

        pcpCache = Pcp.Cache(Pcp.LayerStackIdentifier(rootLayer, sessionLayer))

        # Compute the cache's root layer stack and verify its contents.
        (layerStack, errors) = \
            pcpCache.ComputeLayerStack(pcpCache.GetLayerStackIdentifier())

        self.assertTrue(layerStack)
        self.assertEqual(layerStack.layers, [sessionLayer, rootLayer])
        self.assertEqual(
            layerStack.relocatesSourceToTarget,
            {Sdf.Path('/ModelGroup/Model'): Sdf.Path('/ModelGroup/Model_1')})
        self.assertEqual(
            layerStack.relocatesTargetToSource,
            {Sdf.Path('/ModelGroup/Model_1'): Sdf.Path('/ModelGroup/Model')})

        self.assertEqual(len(errors), 0)

        # Now add an empty sublayer to the session layer, which should be regarded
        # as an insignificant layer stack change.
        #
        # Note that this bug isn't specific to the session layer; it occurred with
        # any insignificant layer stack change. The test just uses the session layer
        # since that's the repro steps from the bug report.
        emptyLayer = Sdf.Layer.FindOrOpen('bug82180/empty.sdf')

        with Pcp._TestChangeProcessor(pcpCache):
            sessionLayer.subLayerPaths.insert(0, emptyLayer.identifier)

        # Verify that the layer stack's contents are still as expect; in particular,
        # the relocations should be unaffected.
        (layerStack, errors) = \
            pcpCache.ComputeLayerStack(pcpCache.GetLayerStackIdentifier())

        self.assertTrue(layerStack)
        self.assertEqual(layerStack.layers,
                         [sessionLayer, emptyLayer, rootLayer])
        self.assertEqual(
            layerStack.relocatesSourceToTarget,
            {Sdf.Path('/ModelGroup/Model'): Sdf.Path('/ModelGroup/Model_1')})
        self.assertEqual(
            layerStack.relocatesTargetToSource,
            {Sdf.Path('/ModelGroup/Model_1'): Sdf.Path('/ModelGroup/Model')})

        self.assertEqual(len(errors), 0)
Exemplo n.º 13
0
    def test_VariantChanges(self):
        rootLayer = Sdf.Layer.CreateAnonymous()
        modelSpec = Sdf.PrimSpec(rootLayer, 'Variant', Sdf.SpecifierDef)

        pcp = Pcp.Cache(Pcp.LayerStackIdentifier(rootLayer), usd=True)

        # Test changes that are emitted as a variant set and variant
        # are created.

        pcp.ComputePrimIndex('/Variant')
        with Pcp._TestChangeProcessor(pcp) as cp:
            varSetSpec = Sdf.VariantSetSpec(modelSpec, 'test')
            self.assertEqual(cp.GetSignificantChanges(), ['/Variant'])
            self.assertEqual(cp.GetSpecChanges(), [])
            self.assertEqual(cp.GetPrimChanges(), [])

        pcp.ComputePrimIndex('/Variant')
        with Pcp._TestChangeProcessor(pcp) as cp:
            modelSpec.variantSelections['test'] = 'A'
            self.assertEqual(cp.GetSignificantChanges(), ['/Variant'])
            self.assertEqual(cp.GetSpecChanges(), [])
            self.assertEqual(cp.GetPrimChanges(), [])

        pcp.ComputePrimIndex('/Variant')
        with Pcp._TestChangeProcessor(pcp) as cp:
            modelSpec.variantSetNameList.Add('test')
            self.assertEqual(cp.GetSignificantChanges(), ['/Variant'])
            self.assertEqual(cp.GetSpecChanges(), [])
            self.assertEqual(cp.GetPrimChanges(), [])

        pcp.ComputePrimIndex('/Variant')
        with Pcp._TestChangeProcessor(pcp) as cp:
            varSpec = Sdf.VariantSpec(varSetSpec, 'A')
            self.assertEqual(cp.GetSignificantChanges(), [])
            self.assertEqual(cp.GetSpecChanges(), ['/Variant'])
            # Creating the variant spec adds an inert spec to /Variant's prim
            # stack but does not require rebuilding /Variant's prim index to
            # account for the new variant node.
            self.assertEqual(cp.GetPrimChanges(), [])

        pcp.ComputePrimIndex('/Variant')
        with Pcp._TestChangeProcessor(pcp) as cp:
            varSpec.primSpec.referenceList.Add(
                Sdf.Reference('./dummy.sdf', '/Dummy'))
            self.assertEqual(cp.GetSignificantChanges(), ['/Variant'])
            self.assertEqual(cp.GetSpecChanges(), [])
            self.assertEqual(cp.GetPrimChanges(), [])
Exemplo n.º 14
0
    def test_InvalidSublayerRemoval(self):
        invalidSublayerId = "/tmp/testPcpChanges_invalidSublayer.sdf"

        layer = Sdf.Layer.CreateAnonymous()
        layer.subLayerPaths.append(invalidSublayerId)

        layerStackId = Pcp.LayerStackIdentifier(layer)
        pcp = Pcp.Cache(layerStackId)

        self.assertEqual(len(pcp.ComputeLayerStack(layerStackId)[1]), 1)
        self.assertTrue(pcp.IsInvalidSublayerIdentifier(invalidSublayerId))

        with Pcp._TestChangeProcessor(pcp):
            layer.subLayerPaths.remove(invalidSublayerId)

        self.assertEqual(len(pcp.ComputeLayerStack(layerStackId)[1]), 0)
        self.assertFalse(pcp.IsInvalidSublayerIdentifier(invalidSublayerId))
Exemplo n.º 15
0
    def test_UnusedVariantChanges(self):
        layer = Sdf.Layer.CreateAnonymous()
        parent = Sdf.PrimSpec(layer, 'Root', Sdf.SpecifierDef, 'Scope')
        vA = Sdf.CreateVariantInLayer(layer, parent.path, 'var', 'A')
        vB = Sdf.CreateVariantInLayer(layer, parent.path, 'var', 'B')
        parent.variantSelections['var'] = 'A'

        layerStackId = Pcp.LayerStackIdentifier(layer)
        pcp = Pcp.Cache(layerStackId)

        (pi, err) = pcp.ComputePrimIndex('/Root')
        self.assertTrue(pi)
        self.assertEqual(len(err), 0)

        # Add a new prim spec inside the unused variant and verify that this
        # does not cause the cached prim index to be blown.
        with Pcp._TestChangeProcessor(pcp):
            newPrim = Sdf.PrimSpec(vB.primSpec, 'Child', Sdf.SpecifierDef, 'Scope')

        self.assertTrue(pcp.FindPrimIndex('/Root'))
Exemplo n.º 16
0
    def test_InternalReferenceChanges(self):
        rootLayer = Sdf.Layer.CreateAnonymous()

        Sdf.PrimSpec(rootLayer, 'target1', Sdf.SpecifierDef)
        Sdf.PrimSpec(rootLayer, 'target2', Sdf.SpecifierDef)

        srcPrimSpec = Sdf.PrimSpec(rootLayer, 'source', Sdf.SpecifierDef)
        srcPrimSpec.referenceList.Add(Sdf.Reference(primPath='/target1'))

        # Initially, the prim index for /source should contain a single
        # reference node to /target1 in rootLayer.
        pcp = Pcp.Cache(Pcp.LayerStackIdentifier(rootLayer))
        (pi, err) = pcp.ComputePrimIndex('/source')

        self.assertEqual(len(err), 0)
        self.assertEqual(
            pi.rootNode.children[0].layerStack.identifier.rootLayer, rootLayer)
        self.assertEqual(pi.rootNode.children[0].path, '/target1')

        # Modify the internal reference to point to /target2 and verify the
        # reference node is updated.
        with Pcp._TestChangeProcessor(pcp):
            srcPrimSpec.referenceList.addedItems[0] = \
                Sdf.Reference(primPath = '/target2')

        (pi, err) = pcp.ComputePrimIndex('/source')

        self.assertEqual(len(err), 0)
        self.assertEqual(
            pi.rootNode.children[0].layerStack.identifier.rootLayer, rootLayer)
        self.assertEqual(pi.rootNode.children[0].path, '/target2')

        # Clear out all references and verify that the prim index contains no
        # reference nodes.
        with Pcp._TestChangeProcessor(pcp):
            srcPrimSpec.referenceList.ClearEdits()

        (pi, err) = pcp.ComputePrimIndex('/source')

        self.assertEqual(len(err), 0)
        self.assertEqual(len(pi.rootNode.children), 0)
Exemplo n.º 17
0
    def test_InvalidSublayerAdd(self):
        invalidSublayerId = "/tmp/testPcpChanges_invalidSublayer.sdf"

        layer = Sdf.Layer.CreateAnonymous()
        layerStackId = Pcp.LayerStackIdentifier(layer)
        pcp = Pcp.Cache(layerStackId)

        (layerStack, errs) = pcp.ComputeLayerStack(layerStackId)
        self.assertEqual(len(errs), 0)
        self.assertEqual(len(layerStack.localErrors), 0)

        with Pcp._TestChangeProcessor(pcp):
            layer.subLayerPaths.append(invalidSublayerId)

        (layerStack, errs) = pcp.ComputeLayerStack(layerStackId)
        # This is potentially surprising. Layer stacks are recomputed
        # immediately during change processing, so any composition
        # errors generated during that process won't be reported
        # during the call to ComputeLayerStack. The errors will be
        # stored in the layer stack's localErrors field, however.
        self.assertEqual(len(errs), 0)
        self.assertEqual(len(layerStack.localErrors), 1)
Exemplo n.º 18
0
    def test_InertPrimChanges(self):
        refLayer = Sdf.Layer.CreateAnonymous()
        refParentSpec = Sdf.PrimSpec(refLayer, 'Parent', Sdf.SpecifierDef)
        refChildSpec = Sdf.PrimSpec(refParentSpec, 'Child', Sdf.SpecifierDef)

        rootLayer = Sdf.Layer.CreateAnonymous()
        parentSpec = Sdf.PrimSpec(rootLayer, 'Parent', Sdf.SpecifierOver)
        parentSpec.referenceList.Add(
            Sdf.Reference(refLayer.identifier, '/Parent'))

        pcp = Pcp.Cache(Pcp.LayerStackIdentifier(rootLayer))

        # Adding an empty over to a prim that already exists (has specs)
        # is an insignificant change.
        (pi, err) = pcp.ComputePrimIndex('/Parent/Child')
        self.assertEqual(err, [])
        with Pcp._TestChangeProcessor(pcp) as cp:
            Sdf.CreatePrimInLayer(rootLayer, '/Parent/Child')
            self.assertEqual(cp.GetSignificantChanges(), [])
            self.assertEqual(cp.GetSpecChanges(), ['/Parent/Child'])
            self.assertEqual(cp.GetPrimChanges(), [])

        # Adding an empty over as the first spec for a prim is a
        # a significant change, even if we haven't computed a prim index
        # for that path yet.
        with Pcp._TestChangeProcessor(pcp) as cp:
            Sdf.CreatePrimInLayer(rootLayer, '/Parent/NewChild')
            self.assertEqual(cp.GetSignificantChanges(), ['/Parent/NewChild'])
            self.assertEqual(cp.GetSpecChanges(), [])
            self.assertEqual(cp.GetPrimChanges(), [])

        (pi, err) = pcp.ComputePrimIndex('/Parent/NewChild2')
        self.assertEqual(err, [])
        with Pcp._TestChangeProcessor(pcp) as cp:
            Sdf.CreatePrimInLayer(rootLayer, '/Parent/NewChild2')
            self.assertEqual(cp.GetSignificantChanges(), ['/Parent/NewChild2'])
            self.assertEqual(cp.GetSpecChanges(), [])
            self.assertEqual(cp.GetPrimChanges(), [])
Exemplo n.º 19
0
    def test_Basic(self):
        # Create a PcpCache for a reference chain, but do not perform any actual
        # composition before querying its used layers. Verify that this does not crash.
        file = 'BasicReference/root.sdf'
        self.assertTrue(os.path.isfile(file))
        layer = Sdf.Layer.FindOrOpen(file)
        self.assertTrue(layer)
        lsi = Pcp.LayerStackIdentifier(layer)
        self.assertTrue(lsi)
        pcpCache = Pcp.Cache(lsi)
        self.assertTrue(pcpCache)
        pcpCache.GetUsedLayers()

        # Create a PcpCache with a target schema, ensuring that layers
        # without the correct target will be marked invalid during composition.
        pcpCache = Pcp.Cache(lsi, targetSchema='sdf')
        (pi, _) = pcpCache.ComputePrimIndex('/PrimWithReferences')
        self.assertTrue(pi.IsValid())
        self.assertEqual(len(pi.localErrors), 0)

        # XXX: Sdf currently emits coding errors when it cannot find a file format
        #      for the given target. I'm not sure this should be the case; it
        #      probably should treat it as though the file didn't exist, which
        #      does not emit errors.
        pcpCache = Pcp.Cache(lsi, targetSchema='Presto')

        with self.assertRaises(Tf.ErrorException):
            pcpCache.ComputePrimIndex('/PrimWithReferences')

        # Should be two local errors corresponding to invalid asset paths,
        # since this prim has two references to layers with a different target
        # schema.
        (pi, _) = pcpCache.ComputePrimIndex('/PrimWithReferences')
        self.assertTrue(pi.IsValid())
        self.assertEqual(len(pi.localErrors), 2)
        self.assertTrue(all([(isinstance(e, Pcp.ErrorInvalidAssetPath) 
                         for e in pi.localErrors)]))
Exemplo n.º 20
0
    def setUp(self):
        """Automatically invoked once before any test cases are run."""

        # Find the sibling sublayers that contain value opinions.
        self.animLayer     = Sdf.Layer.FindOrOpen("anim.sdf")
        self.strongerLayer = Sdf.Layer.FindOrOpen("stronger.sdf")
        self.userLayer     = Sdf.Layer.FindOrOpen("owned.sdf")
        self.weakerLayer   = Sdf.Layer.FindOrOpen("weaker.sdf")

        self.assertTrue(self.strongerLayer)
        self.assertTrue(self.userLayer)
        self.assertTrue(self.weakerLayer)

        # Open the shot, and ensure that it has a session layer.
        self.rootLayer = Sdf.Layer.FindOrOpen("shot.sdf")
        self.assertTrue(self.rootLayer)

        self.sessionLayer = Sdf.Layer.CreateAnonymous("session")
        self.assertTrue(self.sessionLayer)
        self.sessionLayer.sessionOwner = "testUser"
        self.assertTrue(self.sessionLayer.sessionOwner)

        self.layerStackId = \
            Pcp.LayerStackIdentifier( self.rootLayer, self.sessionLayer )
Exemplo n.º 21
0
    def test_PcpCacheReloadSessionLayers(self):
        rootLayer = Sdf.Layer.CreateAnonymous()

        sessionRootLayer = Sdf.Layer.CreateAnonymous()
        self.assertTrue(sessionRootLayer)
        sessionSubLayer = Sdf.Layer.CreateAnonymous()
        self.assertTrue(sessionSubLayer)

        sessionRootLayer.subLayerPaths.append(sessionSubLayer.identifier)

        # Author something to the sublayer
        primSpec = Sdf.PrimSpec(sessionSubLayer, "Root", Sdf.SpecifierDef)
        self.assertTrue(sessionSubLayer.GetPrimAtPath("/Root"))

        # Create the Pcp structures
        lsi = Pcp.LayerStackIdentifier(rootLayer, sessionRootLayer)
        self.assertTrue(lsi)
        pcpCache = Pcp.Cache(lsi)
        self.assertTrue(pcpCache)
        pcpCache.ComputeLayerStack(lsi)

        # Now reload and make sure that the spec on the sublayer stays intact
        pcpCache.Reload()
        self.assertTrue(sessionSubLayer.GetPrimAtPath("/Root"))
Exemplo n.º 22
0
    def test_Basic(self):
        rootLayer = Sdf.Layer.FindOrOpen('bug90508/root.sdf')
        pcpCache = Pcp.Cache(Pcp.LayerStackIdentifier(rootLayer))

        for p in [
                Sdf.Path('/Model'),
                Sdf.Path('/Model/Child'),
                Sdf.Path('/Model/Child/Child2')
        ]:
            self.assertTrue(pcpCache.ComputePrimIndex(p))
            self.assertTrue(pcpCache.FindPrimIndex(p))

        # The prim index at /Model/Child should have an an implied inherit arc to
        # the site @root.sdf@</_class_Model/Child>; however, this node is culled
        # because there are no prim specs at that location. Adding a spec there
        # should cause the PcpCache to evict the prim index, since it needs to be
        # regenerated to accommodate the new node. However, this change doesn't
        # affect any other prim index, so those should remain in the cache.
        with Pcp._TestChangeProcessor(pcpCache):
            Sdf.CreatePrimInLayer(rootLayer, '/_class_Model/Child')

        self.assertTrue(pcpCache.FindPrimIndex('/Model'))
        self.assertFalse(pcpCache.FindPrimIndex('/Model/Child'))
        self.assertTrue(pcpCache.FindPrimIndex('/Model/Child/Child2'))
Exemplo n.º 23
0
    def _GetPcpCacheForLayer(self, rootLayerPath):
        rootLayer = Sdf.Layer.FindOrOpen(rootLayerPath)
        self.assertTrue(rootLayer, "Cannot open layer %s" % (rootLayerPath))

        return Pcp.Cache(Pcp.LayerStackIdentifier(rootLayer))
Exemplo n.º 24
0
 def _LoadPcpCache(self, layerPath, sessionLayerPath=None):
     layer = self._LoadLayer(layerPath)
     sessionLayer = None if not sessionLayerPath else self._LoadLayer(
         sessionLayerPath)
     return Pcp.Cache(Pcp.LayerStackIdentifier(layer, sessionLayer))
Exemplo n.º 25
0
    def GetLayerLabel(layer):
        # Convert backslashes to forward slashes so comparisons
        # against baselines work on Windows
        return (os.path.relpath(layer.realPath,
                                os.path.dirname(rootLayer.realPath)).replace(
                                    "\\", "/"))

    def WalkNodes(node):
        yield node
        for child in node.children:
            for descendant in WalkNodes(child):
                yield descendant

    # Dump the layer stack.
    errors = []
    layerStackId = Pcp.LayerStackIdentifier(rootLayer, sessionLayer)
    pcpCache = Pcp.Cache(layerStackId)
    assert pcpCache.GetVariantFallbacks() == {}
    pcpCache.SetVariantFallbacks(variantFallbacks)
    assert pcpCache.GetVariantFallbacks() == variantFallbacks
    (layerStackData, errors) = pcpCache.ComputeLayerStack(layerStackId)
    layerStack = layerStackData.layers

    print '-' * 72
    print 'Layer Stack:'
    for layer in layerStack:
        print '    ', GetLayerLabel(layer)
    print ''

    if len(layerStackData.localErrors) > 0:
        PrintErrorMessage(errorFile, '-' * 72)
Exemplo n.º 26
0
 def _LoadPcpCache(self, layerPath):
     rootLayer = Sdf.Layer.FindOrOpen(layerPath)
     cache = Pcp.Cache(Pcp.LayerStackIdentifier(rootLayer), usd=True)
     return cache
Exemplo n.º 27
0
 def _CreatePcpCache(self, rootLayer):
     return Pcp.Cache(Pcp.LayerStackIdentifier(rootLayer))
Exemplo n.º 28
0
 def _CreatePcpCache(self, rootLayer, decorator):
     layerStackId = Pcp.LayerStackIdentifier(rootLayer)
     return Pcp.Cache(layerStackId, payloadDecorator=decorator)
Exemplo n.º 29
0
    def test_InstancingChangesForSubrootArcs(self):
        # First layer: Build up the first reference structure
        refLayer = Sdf.Layer.CreateAnonymous()
        # Base spec name space hierarchy: /Base/Child/BaseLeaf.
        baseSpec = Sdf.PrimSpec(refLayer, 'Base', Sdf.SpecifierDef)
        baseChildSpec = Sdf.PrimSpec(baseSpec, 'Child', Sdf.SpecifierDef)
        baseLeafSpec = Sdf.PrimSpec(baseChildSpec, 'BaseLeaf',
                                    Sdf.SpecifierDef)

        # /A references /Base
        refASpec = Sdf.PrimSpec(refLayer, 'A', Sdf.SpecifierDef)
        refASpec.referenceList.Add(Sdf.Reference('', '/Base'))

        # /B references /A
        refBSpec = Sdf.PrimSpec(refLayer, 'B', Sdf.SpecifierDef)
        refBSpec.referenceList.Add(Sdf.Reference('', '/A'))

        # Second layer: Same structure as layer with incmented names for clarity
        # when both layers have prims referenced
        refLayer2 = Sdf.Layer.CreateAnonymous()
        base2Spec = Sdf.PrimSpec(refLayer2, 'Base2', Sdf.SpecifierDef)
        base2ChildSpec = Sdf.PrimSpec(base2Spec, 'Child', Sdf.SpecifierDef)
        base2LeafSpec = Sdf.PrimSpec(base2ChildSpec, 'Base2Leaf',
                                     Sdf.SpecifierDef)

        # /A2 references /Base2
        refA2Spec = Sdf.PrimSpec(refLayer2, 'A2', Sdf.SpecifierDef)
        refA2Spec.referenceList.Add(Sdf.Reference('', '/Base2'))

        # /B2 references /A2
        refB2Spec = Sdf.PrimSpec(refLayer2, 'B2', Sdf.SpecifierDef)
        refB2Spec.referenceList.Add(Sdf.Reference('', '/A2'))

        # Root layer:
        # Instance spec namespace hierarchy: /Instance/Child/InstanceLeaf
        # /Instance references /B2.
        # /Instance/Child subroot references /B/Child
        #
        # What this gives us is the following prim index graph for
        # /Instance/Child:
        #
        # /Instance/Child --> /B/Child -a-> /A/Child -a-> /Base/Child
        #         |
        #         +-a-> /B2/Child -a-> /A2/Child -a-> /Base2/Child
        #
        # All reference arcs are "ancestral" except the direct reference from
        # /Instance/Child to /B/Child. Ancestral arcs under a direct arc are
        # treated differently for instancing than normal ancestral arcs.
        layer = Sdf.Layer.CreateAnonymous()
        instanceSpec = Sdf.PrimSpec(layer, 'Instance', Sdf.SpecifierDef)
        instanceSpec.referenceList.Add(
            Sdf.Reference(refLayer2.identifier, '/B2'))
        instanceChildSpec = Sdf.PrimSpec(instanceSpec, 'Child',
                                         Sdf.SpecifierDef)
        instanceChildSpec.referenceList.Add(
            Sdf.Reference(refLayer.identifier, '/B/Child'))
        instanceLeafSpec = Sdf.PrimSpec(instanceChildSpec, 'InstanceLeaf',
                                        Sdf.SpecifierDef)

        # Instancing is only enabled in Usd mode.
        pcp = Pcp.Cache(Pcp.LayerStackIdentifier(layer), usd=True)

        # Compute our initial prim index. It is not yet instanceable and
        # all leaf nodes appear when computing prim child names.
        (pi, err) = pcp.ComputePrimIndex('/Instance/Child')
        self.assertEqual(len(err), 0)
        self.assertFalse(pi.IsInstanceable())
        self.assertEqual(pi.ComputePrimChildNames(),
                         (['Base2Leaf', 'BaseLeaf', 'InstanceLeaf'], []))

        # Helper context for verifying the change processing of the changes
        # affecting /Instance/Child
        @contextmanager
        def _VerifyChanges(significant=False, spec=False, prim=False):
            primIndexPath = '/Instance/Child'
            # Verify that we have a computed prim index for /Instance/Child
            # before making the change .
            self.assertTrue(pcp.FindPrimIndex(primIndexPath))
            with Pcp._TestChangeProcessor(pcp) as cp:
                try:
                    yield cp
                finally:
                    self.assertEqual(cp.GetSignificantChanges(),
                                     [primIndexPath] if significant else [])
                    self.assertEqual(cp.GetSpecChanges(),
                                     [primIndexPath] if spec else [])
                    self.assertEqual(cp.GetPrimChanges(),
                                     [primIndexPath] if prim else [])
                    # Significant and prim changes do invalidate the prim index.
                    if significant or prim:
                        self.assertFalse(pcp.FindPrimIndex(primIndexPath))
                    else:
                        self.assertTrue(pcp.FindPrimIndex(primIndexPath))

        # Add Child spec to /A. This is just a spec change to /Instance/Child
        # as /Instance/Child is not instanceable yet.
        with _VerifyChanges(spec=True):
            Sdf.PrimSpec(refASpec, 'Child', Sdf.SpecifierOver)

        # Add Child spec to /A2. This is just a spec change to /Instance/Child.
        with _VerifyChanges(spec=True):
            Sdf.PrimSpec(refA2Spec, 'Child', Sdf.SpecifierOver)

        # Delete both Child specs we just added.
        with _VerifyChanges(spec=True):
            del refASpec.nameChildren['Child']
        with _VerifyChanges(spec=True):
            del refA2Spec.nameChildren['Child']

        # Now set /Base/Child to instanceable which is always a significant
        # change.
        with _VerifyChanges(significant=True):
            baseChildSpec.instanceable = True

        # /Instance/Child is now instanceable. BaseLeaf is still returned by
        # ComputePrimChildren because the ancestral node that provides it comes
        # from a subtree composed for a direct subroot reference arc so it is
        # part of the instance. Base2Leaf comes from an actual ancestral arc so
        # it gets skipped when computing children as does the local child
        # opinion for InstanceLeaf.
        (pi, err) = pcp.ComputePrimIndex('/Instance/Child')
        self.assertEqual(len(err), 0)
        self.assertTrue(pi.IsInstanceable())
        self.assertEqual(pi.ComputePrimChildNames(), (['BaseLeaf'], []))

        # Add Child spec to /A2 again now that /Instance/Child is instanceable.
        # This is still just a spec change to /Instance/Child as true ancestral
        # nodes are ignored by the instance key.
        with _VerifyChanges(spec=True):
            Sdf.PrimSpec(refA2Spec, 'Child', Sdf.SpecifierOver)

        # Add Child spec to /A again. This is a significant change as /A/Child
        # is an ancestral node that's part of a direct arc's subtree and is
        # part of the instance key.
        with _VerifyChanges(significant=True):
            Sdf.PrimSpec(refASpec, 'Child', Sdf.SpecifierOver)

        (pi, err) = pcp.ComputePrimIndex('/Instance/Child')
        self.assertEqual(len(err), 0)
        self.assertTrue(pi.IsInstanceable())
        self.assertEqual(pi.ComputePrimChildNames(), (['BaseLeaf'], []))
Exemplo n.º 30
0
    def test_TcpsChanges(self):
        """
        Tests change processing for changes that affect the time codes per
        second of all layers in the layer stacks of a PcpCache.
        """

        # Use the same layers as the sublayer offset test case.
        rootLayerPath = 'TestSublayerOffsetChanges/root.sdf'
        rootSublayerPath = 'TestSublayerOffsetChanges/root-sublayer.sdf'
        refLayerPath = 'TestSublayerOffsetChanges/ref.sdf'
        refSublayerPath = 'TestSublayerOffsetChanges/ref-sublayer.sdf'
        ref2LayerPath = 'TestSublayerOffsetChanges/ref2.sdf'

        rootLayer = Sdf.Layer.FindOrOpen(rootLayerPath)
        sessionLayer = Sdf.Layer.CreateAnonymous()
        pcp = Pcp.Cache(Pcp.LayerStackIdentifier(rootLayer, sessionLayer))

        (pi, err) = pcp.ComputePrimIndex('/A')
        self.assertTrue(pi)
        self.assertEqual(len(err), 0)

        rootSublayer = Sdf.Layer.Find(rootSublayerPath)
        refLayer = Sdf.Layer.Find(refLayerPath)
        refSublayer = Sdf.Layer.Find(refSublayerPath)
        ref2Layer = Sdf.Layer.Find(ref2LayerPath)

        # Verify the expected structure of the test asset. It should simply be
        # a chain of two references, with layer offsets of 100.0 and 50.0
        # respectively.
        self.assertEqual(pi.rootNode.layerStack.layers,
                         [sessionLayer, rootLayer, rootSublayer])

        refNode = pi.rootNode.children[0]
        self.assertEqual(refNode.layerStack.layers, [refLayer, refSublayer])
        self.assertEqual(refNode.arcType, Pcp.ArcTypeReference)
        self.assertEqual(refNode.mapToRoot.timeOffset, Sdf.LayerOffset(100.0))
        for layer in refNode.layerStack.layers:
            self.assertFalse(layer.HasTimeCodesPerSecond())
            self.assertEqual(layer.timeCodesPerSecond, 24.0)

        ref2Node = refNode.children[0]
        self.assertEqual(ref2Node.layerStack.layers, [ref2Layer])
        self.assertEqual(ref2Node.arcType, Pcp.ArcTypeReference)
        self.assertEqual(ref2Node.mapToRoot.timeOffset, Sdf.LayerOffset(150.0))
        for layer in ref2Node.layerStack.layers:
            self.assertFalse(layer.HasTimeCodesPerSecond())
            self.assertEqual(layer.timeCodesPerSecond, 24.0)

        # Run the TCPS change suite on the root layer.
        tcpsToOffsets = {
            12.0: (Sdf.LayerOffset(100.0, 0.5), Sdf.LayerOffset(125.0, 0.5)),
            24.0: (Sdf.LayerOffset(100.0), Sdf.LayerOffset(150.0)),
            48.0: (Sdf.LayerOffset(100.0, 2.0), Sdf.LayerOffset(200.0, 2.0))
        }
        self._RunTcpsChangesForLayer(pcp, rootLayer, tcpsToOffsets, ['/'])

        # Run the TCPS change suite on the first reference layer.
        tcpsToOffsets = {
            12.0: (Sdf.LayerOffset(100.0, 2.0), Sdf.LayerOffset(200.0)),
            24.0: (Sdf.LayerOffset(100.0), Sdf.LayerOffset(150.0)),
            48.0: (Sdf.LayerOffset(100.0, 0.5), Sdf.LayerOffset(125.0))
        }
        self._RunTcpsChangesForLayer(pcp, refLayer, tcpsToOffsets, ['/A'])

        # Run the TCPS change suite on the second reference layer.
        tcpsToOffsets = {
            12.0: (Sdf.LayerOffset(100.0), Sdf.LayerOffset(150.0, 2.0)),
            24.0: (Sdf.LayerOffset(100.0), Sdf.LayerOffset(150.0)),
            48.0: (Sdf.LayerOffset(100.0), Sdf.LayerOffset(150.0, 0.5))
        }
        self._RunTcpsChangesForLayer(pcp, ref2Layer, tcpsToOffsets, ['/A'])

        # Run the TCPS change suite on the sublayers of the root and reference
        # layers. In the particular setup of these layer, TCPS of either
        # sublayer doesn't change the layer offsets applied to the reference
        # nodes, but will still cause change management to report significant
        # changes to prim indexes.
        tcpsToOffsets = {
            12.0: (Sdf.LayerOffset(100.0), Sdf.LayerOffset(150.0)),
            24.0: (Sdf.LayerOffset(100.0), Sdf.LayerOffset(150.0)),
            48.0: (Sdf.LayerOffset(100.0), Sdf.LayerOffset(150.0))
        }
        self._RunTcpsChangesForLayer(pcp, rootSublayer, tcpsToOffsets, ['/'])
        self._RunTcpsChangesForLayer(pcp, refSublayer, tcpsToOffsets, ['/A'])

        # Run the TCPS change suite on the session layer.
        tcpsToOffsets = {
            12.0: (Sdf.LayerOffset(50.0, 0.5), Sdf.LayerOffset(75.0, 0.5)),
            24.0: (Sdf.LayerOffset(100.0), Sdf.LayerOffset(150.0)),
            48.0: (Sdf.LayerOffset(200.0, 2.0), Sdf.LayerOffset(300.0, 2.0))
        }
        self._RunTcpsChangesForLayer(pcp, sessionLayer, tcpsToOffsets, ['/'])

        # Special cases for the session layer when root layer has a tcps value
        rootLayer.timeCodesPerSecond = 24.0
        self.assertTrue(rootLayer.HasTimeCodesPerSecond())
        self.assertFalse(sessionLayer.HasTimeCodesPerSecond())
        with Pcp._TestChangeProcessor(pcp) as cp:
            # Set the session layer's FPS. This will change the session layer's
            # computed TCPS and is a significant change even though the overall
            # TCPS of the root layer stack is 24 as it is authored on the root
            # layer.
            sessionLayer.framesPerSecond = 48.0
            self.assertEqual(sessionLayer.timeCodesPerSecond, 48.0)
            self.assertEqual(cp.GetSignificantChanges(), ['/'])
            self.assertFalse(pcp.FindPrimIndex('/A'))
            # Recompute the new prim index
            (pi, err) = pcp.ComputePrimIndex('/A')
            refNode = pi.rootNode.children[0]
            ref2Node = refNode.children[0]
            # The reference layer offsets are still the same as authored as
            # the root layer TCPS still matches its layer stack's overall TCPS
            self.assertEqual(refNode.mapToRoot.timeOffset,
                             Sdf.LayerOffset(100.0))
            self.assertEqual(ref2Node.mapToRoot.timeOffset,
                             Sdf.LayerOffset(150.0))

        # Continuing from the previous case, root layer has TCPS set to 24 and
        # session layer has FPS set to 48. Now we set the session TCPS to 48.
        # While this does not cause a TCPS change to session layer taken by
        # itself, this does mean that the session now overrides the overall
        # TCPS of the layer stack which used to come the root. We verify here
        # that this is a significant change and that it scales the layer offsets
        # to the references.
        self.assertFalse(sessionLayer.HasTimeCodesPerSecond())
        with Pcp._TestChangeProcessor(pcp) as cp:
            sessionLayer.timeCodesPerSecond = 48.0
            self.assertEqual(sessionLayer.timeCodesPerSecond, 48.0)
            self.assertEqual(cp.GetSignificantChanges(), ['/'])
            self.assertFalse(pcp.FindPrimIndex('/A'))
            # Recompute the new prim index
            (pi, err) = pcp.ComputePrimIndex('/A')
            refNode = pi.rootNode.children[0]
            ref2Node = refNode.children[0]
            self.assertEqual(refNode.mapToRoot.timeOffset,
                             Sdf.LayerOffset(200.0, 2.0))
            self.assertEqual(ref2Node.mapToRoot.timeOffset,
                             Sdf.LayerOffset(300.0, 2.0))

        # And as a parallel to the previous case, we now clear the session TCPS
        # again. This is still no effective change to the session layer TCPS
        # itself, but root layer's TCPS is once again the overall layer stack
        # TCPS. This is significant changes and the layer offsets return to
        # their original values.
        with Pcp._TestChangeProcessor(pcp) as cp:
            sessionLayer.ClearTimeCodesPerSecond()
            self.assertEqual(sessionLayer.timeCodesPerSecond, 48.0)
            self.assertEqual(cp.GetSignificantChanges(), ['/'])
            self.assertFalse(pcp.FindPrimIndex('/A'))
            # Recompute the new prim index
            (pi, err) = pcp.ComputePrimIndex('/A')
            refNode = pi.rootNode.children[0]
            ref2Node = refNode.children[0]
            # The reference layer offsets are still the same as authored as
            # the root layer TCPS still matches its layer stack's overall TCPS
            self.assertEqual(refNode.mapToRoot.timeOffset,
                             Sdf.LayerOffset(100.0))
            self.assertEqual(ref2Node.mapToRoot.timeOffset,
                             Sdf.LayerOffset(150.0))

        # One more special case. Neither session or root layers have TCPS set.
        # Root layer has FPS set to 48, session layer has FPS set to 24. Overall
        # computed TCPS of the layer stack will be 24, matching session FPS.
        # We then author a TCPS value of 48 to the root layer, matching its FPS
        # value. There is no effective change to the root layer's TCPS itself
        # but we do end up with a significant change as the overall layer stack
        # TCPS will now compute to 48.
        sessionLayer.ClearTimeCodesPerSecond()
        rootLayer.ClearTimeCodesPerSecond()
        sessionLayer.framesPerSecond = 24.0
        rootLayer.framesPerSecond = 48.0
        with Pcp._TestChangeProcessor(pcp) as cp:
            rootLayer.timeCodesPerSecond = 48.0
            self.assertEqual(rootLayer.timeCodesPerSecond, 48.0)
            self.assertEqual(cp.GetSignificantChanges(), ['/'])
            self.assertFalse(pcp.FindPrimIndex('/A'))
            # Recompute the new prim index
            (pi, err) = pcp.ComputePrimIndex('/A')
            refNode = pi.rootNode.children[0]
            ref2Node = refNode.children[0]
            self.assertEqual(refNode.mapToRoot.timeOffset,
                             Sdf.LayerOffset(100.0, 2.0))
            self.assertEqual(ref2Node.mapToRoot.timeOffset,
                             Sdf.LayerOffset(200.0, 2.0))