def test_NewUsdLayer(self): def _TestNewLayer(layer, expectedFileFormat): """Check that the new layer was created successfully and its file format is what we expect.""" self.assertTrue(layer) self.assertEqual(layer.GetFileFormat(), Sdf.FileFormat.FindById('usd')) # Write something to the layer to ensure it's functional. primSpec = Sdf.PrimSpec(layer, 'Scope', Sdf.SpecifierDef, 'Scope') self.assertTrue(primSpec) # Ensure the layer is saved to disk, then check that its # underlying file format matches what we expect. self.assertTrue(layer.Save()) self.assertEqual(GetUnderlyingUsdFileFormat(layer), expectedFileFormat) usdFileFormat = Sdf.FileFormat.FindById('usd') # Newly-created .usd layers default to the USD_DEFAULT_FILE_FORMAT format. _TestNewLayer(Sdf.Layer.CreateNew('testNewUsdLayer.usd'), Tf.GetEnvSetting('USD_DEFAULT_FILE_FORMAT')) _TestNewLayer(Sdf.Layer.New(usdFileFormat, 'testNewUsdLayer_2.usd'), Tf.GetEnvSetting('USD_DEFAULT_FILE_FORMAT')) # Verify that file format arguments can be used to control the # underlying file format for new .usd layers. _TestNewLayer(Sdf.Layer.CreateNew('testNewUsdLayer_text.usd', args={'format':'usda'}), 'usda') _TestNewLayer(Sdf.Layer.New(usdFileFormat, 'testNewUsdLayer_text_2.usd', args={'format':'usda'}), 'usda') _TestNewLayer(Sdf.Layer.CreateNew('testNewUsdLayer_crate.usd', args={'format':'usdc'}), 'usdc') _TestNewLayer(Sdf.Layer.New(usdFileFormat, 'testNewUsdLayer_crate_2.usd', args={'format':'usdc'}), 'usdc')
def testError(self): """Simulate error in non-Python-invoked code by using Tf.RepostErrors.""" self._StartRecording() try: Tf.RaiseCodingError("blah") except Tf.ErrorException as e: Tf.RepostErrors(e) log = self._StopRecording() self.assertEqual(len(log), 1) logText, logCode = log[0] # When this test is executed as a result of the unittest.main() call at # the bottom of this file (e.g. when this script is executed directly # via the shebang, when the script file is passed to a Python # interpreter on the command-line, or when the script file's contents # is read and executed through compile() and exec(), the module will be # reported as "__main__". Otherwise, when this file is imported as a # module and then executed using unittest.main(module=<module name>), # the module name will match the file name and be reported as # "testDiagnosticDelegate". We make the regex here recognize both # cases. if (Tf.GetEnvSetting('MAYAUSD_SHOW_FULL_DIAGNOSTICS')): self.assertRegex( logText, "^Python coding error: blah -- Coding Error in " "(__main__|testDiagnosticDelegate)\.testError at line [0-9]+ of " ) else: self.assertEqual(logText, "Python coding error: blah") self.assertEqual(logCode, OM.MCommandMessage.kError)
def test_StageMaskDependencyExpansion(self): """ Tests dependency based (rels, attr connections) population expansion. """ if not (Tf.GetEnvSetting("GUSD_STAGEMASK_ENABLE") and Tf.GetEnvSetting("GUSD_STAGEMASK_EXPANDRELS")): return path = "test.usda" cache = Gusd.StageCache() prim, stage = GetPrim(cache, path, "/Root/Component/B") # External prim should have been detected as a dependency and # included in the mask. assert Sdf.Path("/Root/ExternalDependency") in \ stage.GetPopulationMask().GetPaths() # Make sure the mask composed prims as expected. assert stage.GetPrimAtPath("/Root/ExternalDependency") assert not stage.GetPrimAtPath("/Root/NonReferencedPrim") assert not stage.GetPrimAtPath("/Root2")
def test_StageMaskComponentExpansion(self): """ Tests kind-based population mask expansion. """ if not Tf.GetEnvSetting("GUSD_STAGEMASK_ENABLE"): return path = "test.usda" cache = Gusd.StageCache() prim, stage = GetPrim(cache, path, "/Root/Component/A") # Mask should have been expanded to include full /Root/Component. assert Sdf.Path("/Root/Component") in \ stage.GetPopulationMask().GetPaths() # Make sure the mask composed prims as expected. assert stage.GetPrimAtPath("/Root/Component/B") assert not stage.GetPrimAtPath("/Root/NonReferencedPrim") assert not stage.GetPrimAtPath("/Root2") if not Tf.GetEnvSetting("GUSD_STAGEMASK_EXPANDRELS"): assert not stage.GetPrimAtPath("/Root/ExternalDependency")
def test_ValidClipMetadata(self): clipPrim = self.rootLayer.GetPrimAtPath(self.clipPath) self.assertTrue(clipPrim) if Tf.GetEnvSetting('USD_AUTHOR_LEGACY_CLIPS'): self.assertEqual(set(clipPrim.ListInfoKeys()), set(['clipTimes', 'clipAssetPaths', 'clipPrimPath', 'clipManifestAssetPath', 'clipActive', 'specifier'])) else: self.assertEqual(set(clipPrim.ListInfoKeys()), set(['clips', 'specifier'])) self.assertEqual(set(clipPrim.GetInfo('clips').keys()), set(['default'])) self.assertEqual(set(clipPrim.GetInfo('clips')['default'].keys()), set(['times', 'assetPaths', 'primPath', 'manifestAssetPath', 'active']))
def testProxyShapeBoundingBox(self): mayaFile = os.path.abspath('ProxyShape.ma') cmds.file(mayaFile, open=True, force=True) # Verify that the proxy shape read something from the USD file. bboxSize = cmds.getAttr('Cube_usd.boundingBoxSize')[0] self.assertEqual(bboxSize, (1.0, 1.0, 1.0)) # The VP2 render delegate doesn't use additional proxy shape if not Tf.GetEnvSetting('VP2_RENDER_DELEGATE_PROXY'): # The proxy shape is imaged by the pxrHdImagingShape, which should be # created by the proxy shape's postConstructor() method. Make sure the # pxrHdImagingShape (and its parent transform) exist. hdImagingTransformPath = '|HdImaging' hdImagingShapePath = '%s|HdImagingShape' % hdImagingTransformPath self.assertTrue(cmds.objExists(hdImagingTransformPath)) self.assertEqual(cmds.nodeType(hdImagingTransformPath), 'transform') self.assertTrue(cmds.objExists(hdImagingShapePath)) self.assertEqual(cmds.nodeType(hdImagingShapePath), 'pxrHdImagingShape') self.assertNotEqual(cmds.ls(hdImagingTransformPath, uuid=True), cmds.ls(hdImagingShapePath, uuid=True)) # The pxrHdImagingShape and its parent transform are set so that they # do not write to the Maya scene file and are not exported by # usdExport, so do a test export and make sure that's the case. usdFilePath = os.path.abspath('ProxyShapeExportTest.usda') cmds.usdExport(file=usdFilePath) usdStage = Usd.Stage.Open(usdFilePath) prim = usdStage.GetPrimAtPath('/HdImaging') self.assertFalse(prim) prim = usdStage.GetPrimAtPath('/HdImaging/HdImagingShape') self.assertFalse(prim) # Make sure that we can reorder root nodes in the scene with the # pxrHdImagingShape present. cmds.polyCube(n="testNode1") cmds.polyCube(n="testNode2") cmds.reorder("testNode1", back=True) cmds.reorder("testNode2", front=True)
def _ValidateSelection(self, expectedSelectionSet): if not Tf.GetEnvSetting('MAYAUSD_DISABLE_VP2_RENDER_DELEGATE'): # When the Viewport 2.0 render delegate is being used, we will have # selected USD prims rather than proxy shape nodes or their # transform nodes, so we query UFE for the selection and manipulate # the paths of the selected scene items to yield the Maya-side # selection. ufeSelection = ufe.GlobalSelection.get() self.assertEqual(len(ufeSelection), len(expectedSelectionSet)) # Pop the USD root prim name, and then the proxy shape name off of # the UFE path to leave the name of the proxy shape's transform # node at the end of the path. ufePaths = [ufeItem.path().pop().pop() for ufeItem in ufeSelection] actualSelectionSet = {str(ufePath.back()) for ufePath in ufePaths} else: actualSelectionSet = set(cmds.ls(selection=True) or []) self.assertEqual(actualSelectionSet, expectedSelectionSet)
def test_StageMaskPreemption(self): """ Test that the presence of a full stage on the cache preempts the use of masked stage queries. """ if not Tf.GetEnvSetting("GUSD_STAGEMASK_ENABLE"): return path = "test.usda" cache = Gusd.StageCache() # Pre-populate a complete stage on the cache. stage = FindOrOpen(cache, path) # Individual prim queries should now return the same stage. assert GetPrim(cache, path, "/Root/Component")[1] == stage assert GetPrim(cache, path, "/Root/NonReferencedPrim")[1] == stage assert GetPrim(cache, path, "/Root/ExternalDependency")[1] == stage assert GetPrim(cache, path, "/Root/ModelWithVariants")[1] == stage
def test_StageMaskRootExpansion(self): """ Test the fallback behavior of expanding to the root in componentless hierarchcies. """ if not Tf.GetEnvSetting("GUSD_STAGEMASK_ENABLE"): return path = "test.usda" cache = Gusd.StageCache() prim, stage = GetPrim(cache, path, "/Root/ComponentlessHierarchy") # Since there's no component as an ancestor or descendant # of this prim, we should have expanded out to the full stage. assert stage.GetPopulationMask().GetPaths() == \ [Sdf.Path.absoluteRootPath] # Make sure the mask composed prims as expected. assert stage.GetPrimAtPath("/Root") assert stage.GetPrimAtPath("/Root2")
def test_StageMaskDescendantComponentExpansion(self): """ Tests kind-based population mask expansion when expanding a primitve that contains a descendant that is a component. """ if not Tf.GetEnvSetting("GUSD_STAGEMASK_ENABLE"): return path = "test.usda" cache = Gusd.StageCache() prim, stage = GetPrim(cache, path, "/Root") # Since /Root contains a component prim, expansion should # have gone no further than /Root. assert stage.GetPopulationMask().GetPaths() == [Sdf.Path("/Root")] # Make sure the mask composed prims as expected. assert stage.GetPrimAtPath("/Root") assert not stage.GetPrimAtPath("/Root2")
def test_Export(self): # Verify that exporting to a .usd file produces the default usd file format. composed = Usd.Stage.Open("root.usd") assert composed.Export('TestExport.usd') newFileName = 'TestExport.' + Tf.GetEnvSetting( 'USD_DEFAULT_FILE_FORMAT') shutil.copyfile('TestExport.usd', newFileName) assert Sdf.Layer.FindOrOpen(newFileName) # Verify that exporting to a .usd file but specifying ASCII # via file format arguments produces an ASCII file. assert composed.Export('TestExport_ascii.usd', args={'format': 'usda'}) shutil.copyfile('TestExport_ascii.usd', 'TestExport_ascii.usda') assert Sdf.Layer.FindOrOpen('TestExport_ascii.usda') # Verify that exporting to a .usd file but specifying crate # via file format arguments produces a usd crate file. assert composed.Export('TestExport_crate.usd', args={'format': 'usdc'}) shutil.copyfile('TestExport_crate.usd', 'TestExport_crate.usdc') assert Sdf.Layer.FindOrOpen('TestExport_crate.usdc')
def test_Clear(self): """ Tests cache clearing. """ path = "test.usda" cache = Gusd.StageCache() stage = FindOrOpen(cache, path) assert stage stage2 = cache.Find(path) cache.Clear(["test.usda"]) # should not longer find the stage on the cache. assert not cache.Find("test.usda") assert not cache.FindStages(["test.usda"]) # but our stage variable should still be valid. assert stage if Tf.GetEnvSetting("GUSD_STAGEMASK_ENABLE"): # Make sure this clearing behavior extends to masked stages. prim, primStage = GetPrim(cache, path, "/Root/Component") cache.Clear(["test.usda"]) assert not cache.Find("test.usda") assert not cache.FindStages(["test.usda"]) assert prim assert primStage # the above primStage should be the only stage reference; # release it, and our prim should expire. primStage = None assert not prim
class TestPcpChanges(unittest.TestCase): 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]) 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) 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) (layerStack, errs) = pcp.ComputeLayerStack(layerStackId) self.assertEqual(len(errs), 1) self.assertEqual(len(layerStack.localErrors), 1) self.assertTrue(pcp.IsInvalidSublayerIdentifier(invalidSublayerId)) with Pcp._TestChangeProcessor(pcp): layer.subLayerPaths.remove(invalidSublayerId) (layerStack, errs) = pcp.ComputeLayerStack(layerStackId) self.assertEqual(len(errs), 0) self.assertEqual(len(layerStack.localErrors), 0) self.assertFalse(pcp.IsInvalidSublayerIdentifier(invalidSublayerId)) 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')) 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')) # Compute the prim index in the change processing block as the # changed refLayer is only being held onto by the changes' lifeboat # as its referencing prim index has been invalidated. (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)) def _RunTcpsChangesForLayer(self, pcpCache, layer, tcpsToExpecteOffsetsMap, affectedPaths): """ Helper function for test_TcpsChanges to run a suite of various TCPS and FPS metadata changes on a particular layer and verifying that the correct change processing is run for every change. """ # Helper function for a making a TCPS and/or FPS change and verify the # expected change processing, prim index invalidation, and new computed # values. def _ChangeAndVerify(newValDict, expectSignificantChange, expectedTcps): # Just verify we have a tcps value and/or fps value to set self.assertTrue('tcps' in newValDict or 'fps' in newValDict) with Pcp._TestChangeProcessor(pcpCache) as cp: # Change block for when we're setting both fps and tcps with Sdf.ChangeBlock(): # Set the tcps value if present (None -> Clear) if 'tcps' in newValDict: val = newValDict['tcps'] if val is None: layer.ClearTimeCodesPerSecond() self.assertFalse(layer.HasTimeCodesPerSecond()) else: layer.timeCodesPerSecond = val self.assertTrue(layer.HasTimeCodesPerSecond()) # Set the fps value if present (None -> Clear) if 'fps' in newValDict: val = newValDict['fps'] if val is None: layer.ClearFramesPerSecond() self.assertFalse(layer.HasFramesPerSecond()) else: layer.framesPerSecond = val self.assertTrue(layer.HasFramesPerSecond()) # Verify whether the change processor logged a significant # change for the expected affected paths or not based on # whether we expect a significant change. if expectSignificantChange: self.assertEqual(cp.GetSignificantChanges(), affectedPaths) # A significant change will have invalidated our # prim's prim index. self.assertFalse(pcpCache.FindPrimIndex('/A')) # Recompute the new prim index (pi, err) = pcpCache.ComputePrimIndex('/A') else: # No significant should leave our prim's prim index # valid. self.assertEqual(cp.GetSignificantChanges(), []) pi = pcpCache.FindPrimIndex('/A') self.assertTrue(pi) refNode = pi.rootNode.children[0] ref2Node = refNode.children[0] # Verify the layer has the expected computed TCPS self.assertEqual(layer.timeCodesPerSecond, expectedTcps) # Verify the ref node offesets match the expected offsets # for the layer's expected computed TCPS. expectedOffsets = tcpsToExpecteOffsetsMap[expectedTcps] self.assertEqual(refNode.mapToRoot.timeOffset, expectedOffsets[0]) self.assertEqual(ref2Node.mapToRoot.timeOffset, expectedOffsets[1]) # Expect the layer to start with no authored TCPS of FPS. Verify # various changes to authored timeCodesPerSecond self.assertFalse(layer.HasTimeCodesPerSecond()) self.assertFalse(layer.HasFramesPerSecond()) _ChangeAndVerify({'tcps': 24.0}, False, 24.0) _ChangeAndVerify({'tcps': None}, False, 24.0) _ChangeAndVerify({'tcps': 48.0}, True, 48.0) _ChangeAndVerify({'tcps': 12.0}, True, 12.0) _ChangeAndVerify({'tcps': None}, True, 24.0) # Expect the layer to start with no authored TCPS of FPS again. # Verify various changes to authored framesPerSecond self.assertFalse(layer.HasTimeCodesPerSecond()) self.assertFalse(layer.HasFramesPerSecond()) _ChangeAndVerify({'fps': 24.0}, False, 24.0) _ChangeAndVerify({'fps': None}, False, 24.0) _ChangeAndVerify({'fps': 48.0}, True, 48.0) _ChangeAndVerify({'fps': 12.0}, True, 12.0) _ChangeAndVerify({'fps': None}, True, 24.0) # Change the layer to have an authored non-default framesPerSecond. # Verify various changes to timeCodesPerSecond. _ChangeAndVerify({'fps': 48.0}, True, 48.0) self.assertFalse(layer.HasTimeCodesPerSecond()) self.assertTrue(layer.HasFramesPerSecond()) self.assertEqual(layer.timeCodesPerSecond, 48.0) _ChangeAndVerify({'tcps': 48.0}, False, 48.0) _ChangeAndVerify({'tcps': None}, False, 48.0) _ChangeAndVerify({'tcps': 12.0}, True, 12.0) _ChangeAndVerify({'tcps': 24.0}, True, 24.0) _ChangeAndVerify({'tcps': None}, True, 48.0) # Change the layer to have an authored timeCodesPerSecond. # Verify that various changes to framesPerSecond have no effect. _ChangeAndVerify({'tcps': 24.0, 'fps': None}, True, 24.0) self.assertTrue(layer.HasTimeCodesPerSecond()) self.assertFalse(layer.HasFramesPerSecond()) self.assertEqual(layer.timeCodesPerSecond, 24.0) _ChangeAndVerify({'fps': 24.0}, False, 24.0) _ChangeAndVerify({'fps': None}, False, 24.0) _ChangeAndVerify({'fps': 48.0}, False, 24.0) _ChangeAndVerify({'fps': 12.0}, False, 24.0) _ChangeAndVerify({'fps': None}, False, 24.0) # Change the layer to start with an unauthored timeCodesPerSecond # and a non-default framesPerSecond # Verify various changes to timeCodesPerSecond and framesPerSecond # at the same time. _ChangeAndVerify({'tcps': None, 'fps': 48.0}, True, 48.0) self.assertFalse(layer.HasTimeCodesPerSecond()) self.assertTrue(layer.HasFramesPerSecond()) self.assertEqual(layer.timeCodesPerSecond, 48.0) _ChangeAndVerify({'tcps': 48.0, 'fps': None}, False, 48.0) _ChangeAndVerify({'tcps': None, 'fps': 48.0}, False, 48.0) _ChangeAndVerify({'tcps': 24.0, 'fps': None}, True, 24.0) _ChangeAndVerify({'tcps': None, 'fps': 48.0}, True, 48.0) _ChangeAndVerify({'tcps': 12.0, 'fps': None}, True, 12.0) _ChangeAndVerify({'tcps': 48.0, 'fps': 12.0}, True, 48.0) _ChangeAndVerify({'tcps': 12.0, 'fps': 48.0}, True, 12.0) _ChangeAndVerify({'tcps': None, 'fps': 12.0}, False, 12.0) _ChangeAndVerify({'tcps': 24.0, 'fps': 24.0}, True, 24.0) _ChangeAndVerify({'tcps': None, 'fps': None}, False, 24.0) @unittest.skipIf( Tf.GetEnvSetting('PCP_DISABLE_TIME_SCALING_BY_LAYER_TCPS'), "Test requires layer TCPS time scaling enabled") 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)) def test_DefaultReferenceTargetChanges(self): # create a layer, set DefaultPrim, then reference it. targLyr = Sdf.Layer.CreateAnonymous() def makePrim(name): primSpec = Sdf.CreatePrimInLayer(targLyr, name) primSpec.specifier = Sdf.SpecifierDef makePrim('target1') makePrim('target2') targLyr.defaultPrim = 'target1' 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' # Test external reference case where some other layer references # a layer with defaultPrim specified. srcLyr = Sdf.Layer.CreateAnonymous() srcPrimSpec = Sdf.CreatePrimInLayer(srcLyr, '/source') srcPrimSpec.referenceList.Add(Sdf.Reference(targLyr.identifier)) _Test(srcLyr) # Test internal reference case where a prim in the layer with defaultPrim # specified references the same layer. srcPrimSpec = Sdf.CreatePrimInLayer(targLyr, '/source') srcPrimSpec.referenceList.Add(Sdf.Reference()) _Test(targLyr) 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) 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(), []) # Instancing is disabled in Usd mode, so we don't test there. # TestInstancingChanges(usd = False) 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) 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'], [])) 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(), []) 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]) 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(), []) (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])
def test_Basic(self): l = Sdf.Layer.CreateAnonymous() stage = Usd.Stage.Open(l.identifier) world = stage.DefinePrim("/World", "Xform") assert world world.SetMetadata('kind', 'group') assert world.IsModel() assert world.IsGroup() group = stage.DefinePrim("/World/Group", "Xform") assert group group.SetMetadata('kind', 'group') assert group.IsModel() assert group.IsGroup() model = stage.DefinePrim("/World/Group/Model", "Xform") assert model model.SetMetadata('kind', 'component') assert model.IsModel() p = stage.DefinePrim("/World/Group/Model/Mesh", "Scope") assert p print("Test Material") material = UsdShade.Material.Define(stage, "/World/Group/Model/Material") assert material assert material.GetPrim() UsdShade.MaterialBindingAPI(p).Bind(material) print("Test shader") shader = UsdRi.RslShader.Define(stage, '/World/Group/Model/Shader') assert shader assert shader.GetPrim() assert not UsdRi.StatementsAPI.IsRiAttribute(shader.GetSloPathAttr()) shader.GetSloPathAttr().Set('foo') print("Test RiMaterialAPI") riMaterial = UsdRi.MaterialAPI.Apply(material.GetPrim()) assert riMaterial assert riMaterial.GetPrim() # Test surface output self._TestOutput(riMaterial, UsdRi.MaterialAPI.GetSurfaceOutput, UsdRi.MaterialAPI.SetSurfaceSource, UsdRi.MaterialAPI.GetSurface, shader.GetPath()) # Test displacement output self._TestOutput(riMaterial, UsdRi.MaterialAPI.GetDisplacementOutput, UsdRi.MaterialAPI.SetDisplacementSource, UsdRi.MaterialAPI.GetDisplacement, shader.GetPath()) # Test volume output self._TestOutput(riMaterial, UsdRi.MaterialAPI.GetVolumeOutput, UsdRi.MaterialAPI.SetVolumeSource, UsdRi.MaterialAPI.GetVolume, shader.GetPath()) print("Test pattern") pattern = UsdRi.RisPattern.Define(stage, '/World/Group/Model/Pattern') assert pattern assert pattern.GetPrim() pattern.GetFilePathAttr().Set('foo') self.assertEqual(pattern.GetFilePathAttr().Get(), 'foo') pattern.GetArgsPathAttr().Set('argspath') self.assertEqual(pattern.GetArgsPathAttr().Get(), 'argspath') print("Test oslPattern") oslPattern = UsdRi.RisOslPattern.Define( stage, '/World/Group/Model/OslPattern') assert oslPattern assert oslPattern.GetPrim() self.assertEqual(oslPattern.GetFilePathAttr().Get(), 'PxrOSL') print("Test bxdf") bxdf = UsdRi.RisBxdf.Define(stage, '/World/Group/Model/Bxdf') assert bxdf assert bxdf.GetPrim() bxdf.GetFilePathAttr().Set('foo') bxdf.GetArgsPathAttr().Set('argspath') print("Test RIS Material") risMaterial = UsdRi.MaterialAPI(material.GetPrim()) assert risMaterial assert risMaterial.GetPrim() print("Test riStatements") riStatements = UsdRi.StatementsAPI.Apply(shader.GetPrim()) assert riStatements assert riStatements.GetPrim() attr = riStatements.CreateRiAttribute("ModelName", "string").\ Set('someModelName') assert attr props = riStatements.GetRiAttributes() assert props # this is so convoluted attr = riStatements.GetPrim().GetAttribute(props[0].GetName()) assert attr prefix = ('primvars:' if Tf.GetEnvSetting('USDRI_STATEMENTS_WRITE_NEW_ATTR_ENCODING') else '') self.assertEqual(attr.GetName(), prefix + 'ri:attributes:user:ModelName') self.assertEqual(attr.Get(), 'someModelName') self.assertEqual(UsdRi.StatementsAPI.GetRiAttributeName(attr), 'ModelName') self.assertEqual(UsdRi.StatementsAPI.GetRiAttributeNameSpace(attr), 'user') assert UsdRi.StatementsAPI.IsRiAttribute(attr) self.assertEqual( UsdRi.StatementsAPI.MakeRiAttributePropertyName('myattr'), prefix + 'ri:attributes:user:myattr') self.assertEqual( UsdRi.StatementsAPI.MakeRiAttributePropertyName('dice:myattr'), prefix + 'ri:attributes:dice:myattr') self.assertEqual( UsdRi.StatementsAPI.MakeRiAttributePropertyName('dice.myattr'), prefix + 'ri:attributes:dice:myattr') self.assertEqual( UsdRi.StatementsAPI.MakeRiAttributePropertyName('dice_myattr'), prefix + 'ri:attributes:dice:myattr') # period is stronger separator than underscore, when both are present self.assertEqual( UsdRi.StatementsAPI.MakeRiAttributePropertyName('dice_my.attr'), prefix + 'ri:attributes:dice_my:attr') # multiple tokens concatted with underscores self.assertEqual( UsdRi.StatementsAPI.MakeRiAttributePropertyName( 'dice:my1:long:attr'), prefix + 'ri:attributes:dice:my1_long_attr') self.assertEqual( UsdRi.StatementsAPI.MakeRiAttributePropertyName( 'dice.my2.long.attr'), prefix + 'ri:attributes:dice:my2_long_attr') self.assertEqual( UsdRi.StatementsAPI.MakeRiAttributePropertyName( 'dice_my3_long_attr'), prefix + 'ri:attributes:dice:my3_long_attr') self.assertEqual(riStatements.GetCoordinateSystem(), '') self.assertEqual( UsdRi.StatementsAPI(model).GetModelCoordinateSystems(), []) self.assertEqual( UsdRi.StatementsAPI(model).GetModelScopedCoordinateSystems(), []) riStatements.SetCoordinateSystem('LEyeSpace') self.assertEqual(riStatements.GetCoordinateSystem(), 'LEyeSpace') self.assertEqual( UsdRi.StatementsAPI(model).GetModelCoordinateSystems(), [Sdf.Path('/World/Group/Model/Shader')]) riStatements.SetScopedCoordinateSystem('ScopedLEyeSpace') self.assertEqual(riStatements.GetScopedCoordinateSystem(), 'ScopedLEyeSpace') self.assertEqual( UsdRi.StatementsAPI(model).GetModelScopedCoordinateSystems(), [Sdf.Path('/World/Group/Model/Shader')]) self.assertEqual( UsdRi.StatementsAPI(group).GetModelCoordinateSystems(), []) self.assertEqual( UsdRi.StatementsAPI(group).GetModelScopedCoordinateSystems(), []) self.assertEqual( UsdRi.StatementsAPI(world).GetModelCoordinateSystems(), []) self.assertEqual( UsdRi.StatementsAPI(world).GetModelScopedCoordinateSystems(), []) # Test mixed old & new style encodings if (Tf.GetEnvSetting('USDRI_STATEMENTS_WRITE_NEW_ATTR_ENCODING') and Tf.GetEnvSetting('USDRI_STATEMENTS_READ_OLD_ATTR_ENCODING')): prim = stage.DefinePrim("/prim") riStatements = UsdRi.StatementsAPI.Apply(prim) self.assertEqual(len(riStatements.GetRiAttributes()), 0) # Add new-style newStyleAttr = riStatements.CreateRiAttribute('newStyle', 'string') newStyleAttr.Set('new') self.assertEqual(len(riStatements.GetRiAttributes()), 1) # Add old-style (note that we can't use UsdRi API for this, # since it doesn't let the caller choose the encoding) oldStyleAttr = prim.CreateAttribute('ri:attributes:user:oldStyle', Sdf.ValueTypeNames.String) oldStyleAttr.Set('old') self.assertEqual(len(riStatements.GetRiAttributes()), 2) # Exercise the case of an Ri attribute encoded in both # old and new styles. ignoredAttr = prim.CreateAttribute('ri:attributes:user:newStyle', Sdf.ValueTypeNames.String) self.assertEqual(len(riStatements.GetRiAttributes()), 2) self.assertFalse(ignoredAttr in riStatements.GetRiAttributes())
# registered. from mayaUsd import lib as mayaUsdLib from pxr import Tf from pxr import Usd from maya import cmds from maya import standalone import fixturesUtils import os import unittest @unittest.skipIf(not Tf.GetEnvSetting('MAYAUSD_DISABLE_VP2_RENDER_DELEGATE'), 'Not applicable when using the Viewport 2.0 render deleggate') class testHdImagingShape(unittest.TestCase): @classmethod def setUpClass(cls): inputPath = fixturesUtils.setUpClass(__file__) mayaSceneFilePath = os.path.join(inputPath, 'HdImagingShapeTest', 'HdImagingShapeTest.ma') cmds.file(mayaSceneFilePath, open=True, force=True) @classmethod def tearDownClass(cls): standalone.uninitialize()