def test_SkelImport(self): cmds.file(new=True, force=True) path = os.path.join(self.inputPath, "UsdImportSkeleton", "skelCube.usda") cmds.usdImport(file=path, readAnimData=True, primPath="/Root", shadingMode=[ ["none", "default"], ]) stage = Usd.Stage.Open(path) skelCache = UsdSkel.Cache() bindingSitePrim = stage.GetPrimAtPath("/Root") self.assertTrue(bindingSitePrim.IsA(UsdSkel.Root)) if Usd.GetVersion() > (0, 20, 8): skelCache.Populate(UsdSkel.Root(bindingSitePrim), Usd.PrimDefaultPredicate) else: skelCache.Populate(UsdSkel.Root(bindingSitePrim)) skel = UsdSkel.Skeleton.Get(stage, "/Root/Skeleton") self.assertTrue(skel) skelQuery = skelCache.GetSkelQuery(skel) self.assertTrue(skelQuery) meshPrim = stage.GetPrimAtPath("/Root/Cube") self.assertTrue(meshPrim) skinningQuery = skelCache.GetSkinningQuery(meshPrim) self.assertTrue(skinningQuery) jointNames = [ name.split("/")[-1] for name in skelQuery.GetJointOrder() ] joints = [_GetDepNode(n) for n in jointNames] self.assertTrue(all(joints)) self._ValidateJointTransforms(skelQuery, joints) self._ValidateJointBindPoses(skelQuery, joints) self._ValidateBindPose("Skeleton_bindPose", skelQuery, joints) self._ValidateMeshTransform(meshPrim.GetName(), skinningQuery) self._ValidateSkinClusterRig(joints=joints, skinClusterName="skinCluster_{}".format( meshPrim.GetName()), groupPartsName="skinClusterGroupParts", groupIdName="skinClusterGroupId", bindPoseName="Skeleton_bindPose", meshName=meshPrim.GetName(), usdSkelQuery=skelQuery, usdSkinningQuery=skinningQuery)
def test_InstancedBlendShape(self): """Tests for correctness in the interpretation of instanced blend shapes.""" testFile = "populate.usda" stage = Usd.Stage.Open(testFile) cache = UsdSkel.Cache() skelRoot = UsdSkel.Root(stage.GetPrimAtPath("/SkelBinding")) self.assertTrue(cache.Populate(skelRoot, Usd.TraverseInstanceProxies())) # instance proxy mesh mesh = stage.GetPrimAtPath("/SkelBinding/Instance/Override") skelBinding = UsdSkel.BindingAPI(mesh) self.assertEqual(list(skelBinding.GetBlendShapesAttr().Get()), ["override"]) skel = skelBinding.GetSkeleton() skelq = cache.GetSkelQuery(skel) animq = skelq.GetAnimQuery() self.assertEqual(list(animq.GetBlendShapeOrder()), ["override", "shape"]) skinq = cache.GetSkinningQuery(mesh) self.assertTrue(skinq.HasBlendShapes()) self.assertEqual(skelBinding.GetInheritedAnimationSource(), stage.GetPrimAtPath("/Anim1")) # bug PRES-77530 # because skelBinding.GetBlendShapesAttr().Get() and # animq.GetBlendShapeOrder() have different order, # the mapper should not be null. mapper = skinq.GetBlendShapeMapper() self.assertFalse(mapper.IsNull())
def testSkelTransforms(self): """ Tests that the computed joint transforms in USD, when tarnsformed into world space, match the world space transforms of the Maya joints. """ mayaFile = os.path.join(self.inputPath, "UsdExportSkeletonTest", "UsdExportSkeleton.ma") cmds.file(mayaFile, force=True, open=True) # frameRange = [1, 30] frameRange = [1, 3] # TODO: The joint hierarchy intentionally includes non-joint nodes, # which are expected to be ignored. However, when we try to extract # restTransforms from the dagPose, the intermediate transforms cause # problems, since they are not members of the dagPose. As a result, # no dag pose is exported. Need to come up with a way to handle this # correctly in export. print("Expect warnings about invalid restTransforms") usdFile = os.path.abspath('UsdExportSkeleton.usda') cmds.usdExport(mergeTransformAndShape=True, file=usdFile, shadingMode='none', frameRange=frameRange, exportSkels='auto') stage = Usd.Stage.Open(usdFile) root = UsdSkel.Root.Get(stage, '/SkelChar') self.assertTrue(root) skelCache = UsdSkel.Cache() skelCache.Populate(root) skel = UsdSkel.Skeleton.Get(stage, '/SkelChar/Hips') self.assertTrue(skel) skelQuery = skelCache.GetSkelQuery(skel) self.assertTrue(skelQuery) xfCache = UsdGeom.XformCache() for frame in range(*frameRange): cmds.currentTime(frame, edit=True) xfCache.SetTime(frame) skelLocalToWorld = xfCache.GetLocalToWorldTransform(skelQuery.GetPrim()) usdJointXforms = skelQuery.ComputeJointSkelTransforms(frame) for joint,usdJointXf in zip(skelQuery.GetJointOrder(), usdJointXforms): usdJointWorldXf = usdJointXf * skelLocalToWorld selList = OM.MSelectionList() selList.add(Sdf.Path(joint).name) dagPath = selList.getDagPath(0) mayaJointWorldXf = Gf.Matrix4d(*dagPath.inclusiveMatrix()) self.assertTrue(Gf.IsClose(mayaJointWorldXf, usdJointWorldXf, 1e-5))
def _test_InheritedSkeletonBinding(self): """Tests for correctness in the interpretation of the inherited skel:skeleton binding.""" testFile = "populate.usda" stage = Usd.Stage.Open(testFile) rootPath = "/Skeleton" # TODO: To correctly test this, we need either a different kind of mapping, # or we need the skinning query to keep a record of the bound prim. cache = UsdSkel.Cache() root = UsdSkel.Root(stage.GetPrimAtPath(rootPath)) self.assertTrue(cache.Populate(root)) queryA = cache.GetSkinningQuery( UsdSkel.Animation.Get(stage, rootPath + "/Scope/A")) self.assertTrue(queryA) self.assertEqual(queryA.GetSkelQuery().GetPrim().GetPath(), Sdf.Path("/Anim1")) queryB = cache.GetSkinningQuery( UsdSkel.Animation.Get(stage, rootPath + "/Scope/B")) self.assertTrue(queryB) self.assertEqual(queryB.GetAnimQuery().GetPrim().GetPath(), Sdf.Path("/Anim2")) queryC = cache.GetSkinningQuery( UsdSkel.Animation.Get(stage, rootPath + "/Scope/C")) self.assertFalse(queryC) queryD = cache.GetSkinningQuery( UsdSkel.Animation.Get(stage, rootPath + "/Scope/C")) self.assertFalse(queryD)
def main(): print("UsdSkelAppleFixup Begin.") # Create a new out usd file that sublayers the in usd file. All edits # will go to the out usd file. Start and end time is copied over. inFile = args.inusd outFile = args.outusd from pxr import Usd, UsdGeom, UsdSkel, Sdf dstLyr = Sdf.Layer.CreateNew(outFile) srcLyr = Sdf.Layer.FindOrOpen(inFile) stage = Usd.Stage.Open(dstLyr) stage.SetEditTarget(dstLyr) layerStack = dstLyr.subLayerPaths layerStack.insert(len(layerStack), inFile) start = int(srcLyr.startTimeCode) end = int(srcLyr.endTimeCode) stage.SetStartTimeCode(start) stage.SetEndTimeCode(end) # Find all the skinned meshes and copy over the animation source to them # The the skel, anim, and mesh prims. skelPrims = [ prim for prim in Usd.PrimRange(stage.GetPseudoRoot()) if prim.IsA(UsdSkel.Skeleton) ] meshPrims = [ prim for prim in Usd.PrimRange(stage.GetPseudoRoot()) if prim.IsA(UsdGeom.Mesh) ] for skelPrim in skelPrims: skelCache = UsdSkel.Cache() skel = UsdSkel.Skeleton(skelPrim) skelQuery = skelCache.GetSkelQuery(skel) skelAnimQuery = skelQuery.GetAnimQuery() skelAnim = UsdSkel.Animation(skelAnimQuery.GetPrim()) for mesh in meshPrims: rel = FindSkelBindingRel(stage, mesh) if rel: for target in rel.GetTargets(): if target == skelPrim.GetPath(): print("Copying the animationSource relationship to " + mesh.GetName()) # wire up the skeleton and animation source rels for temporary compatbility with Apple's expectations mesh.CreateRelationship( UsdSkel.Tokens.skelAnimationSource).AddTarget( skelAnim.GetPrim().GetPath()) mesh.CreateRelationship( UsdSkel.Tokens.skelSkeleton).AddTarget( skelPrim.GetPath()) dstLyr.Save()
def _TestSkelAnimation(self, animSchema): numFrames = 10 random.seed(0) stage = Usd.Stage.CreateInMemory() anim = animSchema.Define(stage, "/Anim") joints = Vt.TokenArray(["/A", "/B", "/C"]) blendshapes = Vt.TokenArray(["shapeA", "shapeB", "shapeC"]) anim.GetJointsAttr().Set(joints) anim.GetBlendShapesAttr().Set(blendshapes) xformsPerFrame = [[_RandomXf() for _ in range(len(joints))] for _ in range(numFrames)] for frame, xforms in enumerate(xformsPerFrame): anim.SetTransforms(Vt.Matrix4dArray(xforms), frame) weightsPerFrame = [[random.random() for _ in range(len(blendshapes))] for _ in range(numFrames)] for frame, weights in enumerate(weightsPerFrame): anim.GetBlendShapeWeightsAttr().Set(Vt.FloatArray(weights), frame) # Now try reading that all back via computations... cache = UsdSkel.Cache() query = cache.GetAnimQuery(anim) self.assertEqual(query.GetPrim(), anim.GetPrim()) self.assertEqual(query.GetJointOrder(), joints) self.assertEqual(query.GetBlendShapeOrder(), blendshapes) self.assertTrue(query.JointTransformsMightBeTimeVarying()) self.assertEqual(query.GetJointTransformTimeSamples(), list(range(numFrames))) for frame, xforms in enumerate(xformsPerFrame): computedXforms = query.ComputeJointLocalTransforms(frame) self.assertArrayIsClose(computedXforms, xforms) computedXforms = anim.GetTransforms(frame) self.assertArrayIsClose(computedXforms, xforms) for frame, weights in enumerate(weightsPerFrame): computedWeights = query.ComputeBlendShapeWeights(frame) self.assertArrayIsClose(computedWeights, weights)
def test_InheritedAnimBinding(self): """Tests for correctness in the interpretation of the inherited skel:animationSource binding.""" testFile = "populate.usda" stage = Usd.Stage.Open(testFile) cache = UsdSkel.Cache() root = UsdSkel.Root(stage.GetPrimAtPath("/AnimBinding")) self.assertTrue(cache.Populate(root)) query = cache.GetSkelQuery( UsdSkel.Skeleton.Get(stage, "/AnimBinding/Scope/Inherit")) self.assertTrue(query) self.assertEqual(query.GetAnimQuery().GetPrim().GetPath(), Sdf.Path("/Anim1")) query = cache.GetSkelQuery( UsdSkel.Skeleton.Get(stage, "/AnimBinding/Scope/Override")) self.assertTrue(query) self.assertEqual(query.GetAnimQuery().GetPrim().GetPath(), Sdf.Path("/Anim2")) query = cache.GetSkelQuery( UsdSkel.Skeleton.Get(stage, "/AnimBinding/Scope/Block")) self.assertTrue(query) self.assertFalse(query.GetAnimQuery()) query = cache.GetSkelQuery( UsdSkel.Skeleton.Get(stage, "/AnimBinding/Unbound")) self.assertTrue(query) self.assertFalse(query.GetAnimQuery()) query = cache.GetSkelQuery( UsdSkel.Skeleton.Get(stage, "/AnimBinding/BoundToInactiveAnim")) self.assertTrue(query) self.assertFalse(query.GetAnimQuery()) # Ensure that the animationSource binding crosses instancing arcs. query = cache.GetSkelQuery( UsdSkel.Skeleton.Get(stage, "/AnimBinding/Instance/Inherit")) self.assertTrue(query) self.assertEqual(query.GetAnimQuery().GetPrim().GetPath(), Sdf.Path("/Anim1")) # TODO: This test case is failing: query = cache.GetSkelQuery( UsdSkel.Skeleton.Get(stage, "/AnimBinding/Instance/Override")) self.assertTrue(query) self.assertTrue(query.GetAnimQuery().GetPrim().IsInMaster())
def test_AnimQuery(self): """Tests anim query retrieval.""" cache = UsdSkel.Cache() stage = Usd.Stage.CreateInMemory() anim = UsdSkel.Animation.Define(stage, "/Anim") self.assertTrue(cache.GetAnimQuery(anim)) # Backwards-compatibility. self.assertTrue(cache.GetAnimQuery(prim=anim.GetPrim())) self.assertFalse(cache.GetAnimQuery(UsdSkel.Animation()))
def test_SkelImport(self): cmds.file(new=True, force=True) path = os.path.abspath("skelCube.usda") cmds.usdImport(file=path, readAnimData=True, primPath="/Root", assemblyRep="Import", shadingMode="none") stage = Usd.Stage.Open(path) skelCache = UsdSkel.Cache() bindingSitePrim = stage.GetPrimAtPath("/Root") self.assertTrue(bindingSitePrim.IsA(UsdSkel.Root)) skelCache.Populate(UsdSkel.Root(bindingSitePrim)) skelQuery = skelCache.GetSkelQuery(bindingSitePrim) self.assertTrue(skelQuery) meshPrim = stage.GetPrimAtPath("/Root/Cube") self.assertTrue(meshPrim) skinningQuery = skelCache.GetSkinningQuery(meshPrim) self.assertTrue(skinningQuery) jointNames = [ name.split("/")[-1] for name in skelQuery.GetJointOrder() ] joints = [_GetDepNode(n) for n in jointNames] self.assertTrue(all(joints)) self._ValidateJointTransforms(skelQuery, joints) self._ValidateJointBindPoses(skelQuery, joints) self._ValidateBindPose("bindPose", skelQuery, joints) self._ValidateMeshTransform(meshPrim.GetName(), skinningQuery) self._ValidateSkinClusterRig(joints=joints, skinClusterName="skinCluster1", groupPartsName="skinClusterGroupParts", groupIdName="skinClusterGroupId", bindPoseName="bindPose", meshName=meshPrim.GetName(), usdSkelQuery=skelQuery, usdSkinningQuery=skinningQuery)
def test_AnimQuery(self): """Tests anim query retrieval.""" cache = UsdSkel.Cache() stage = Usd.Stage.CreateInMemory() anim = UsdSkel.Animation.Define(stage, "/Anim") assert cache.GetAnimQuery(anim.GetPrim()) assert not cache.GetAnimQuery(stage.DefinePrim("/Foo")) assert not cache.GetAnimQuery( UsdGeom.Xform.Define(stage, "/Bar").GetPrim())
def test_InheritedAnimationSource(self): """Tests for correctness in the interpretation of the inherited skel:animationSource binding.""" testFile = "populate.usda" stage = Usd.Stage.Open(testFile) rootPath = "/AnimationSource" cache = UsdSkel.Cache() root = UsdSkel.Root(stage.GetPrimAtPath(rootPath)) self.assertTrue(cache.Populate(root)) queryA = cache.GetSkelQuery( UsdSkel.Skeleton.Get(stage, rootPath + "/Scope/A")) self.assertTrue(queryA) self.assertEqual(queryA.GetAnimQuery().GetPrim().GetPath(), Sdf.Path("/Anim1")) queryB = cache.GetSkelQuery( UsdSkel.Skeleton.Get(stage, rootPath + "/Scope/B")) self.assertTrue(queryB) self.assertEqual(queryB.GetAnimQuery().GetPrim().GetPath(), Sdf.Path("/Anim2")) queryC = cache.GetSkelQuery( UsdSkel.Skeleton.Get(stage, rootPath + "/Scope/C")) self.assertFalse(queryC) queryD = cache.GetSkelQuery( UsdSkel.Skeleton.Get(stage, rootPath + "/Scope/C")) self.assertFalse(queryD) # Ensure that the animationSource binding crosses instancing arcs. queryInstA = cache.GetSkelQuery( UsdSkel.Skeleton.Get(stage, rootPath + "/Instance/A")) self.assertTrue(queryInstA) self.assertEqual(queryInstA.GetAnimQuery().GetPrim().GetPath(), Sdf.Path("/Anim1")) queryInstB = cache.GetSkelQuery( UsdSkel.Skeleton.Get(stage, rootPath + "/Instance/B")) self.assertTrue(queryInstB) self.assertTrue(queryInstB.GetAnimQuery().GetPrim().IsInMaster())
def test_InheritedSkeletonBinding(self): """Tests for correctness in the interpretation of the inherited skel:skeleton binding.""" testFile = "populate.usda" stage = Usd.Stage.Open(testFile) cache = UsdSkel.Cache() root = UsdSkel.Root(stage.GetPrimAtPath("/SkelBinding")) self.assertTrue(cache.Populate(root)) skel1 = UsdSkel.Skeleton.Get(stage, "/Skel1") skel2 = UsdSkel.Skeleton.Get(stage, "/Skel2") # TODO: Skel population does not currently traverse instance proxies, # so the resolved bindings below will not include skinned meshes within # instances. binding1 = cache.ComputeSkelBinding(root, skel1) self.assertEqual(binding1.GetSkeleton().GetPrim(), skel1.GetPrim()) self.assertEqual([t.GetPrim() for t in binding1.GetSkinningTargets()], [stage.GetPrimAtPath(("/SkelBinding/Scope/Inherit"))]) binding2 = cache.ComputeSkelBinding(root, skel2) self.assertEqual(binding2.GetSkeleton().GetPrim(), skel2.GetPrim()) self.assertEqual([t.GetPrim() for t in binding2.GetSkinningTargets()], [stage.GetPrimAtPath(("/SkelBinding/Scope/Override"))]) allBindings = cache.ComputeSkelBindings(root) # Expecting two resolved bindings. This should *not* include bindings # for any inactive skels. self.assertEqual(len(allBindings), 2) self.assertEqual(binding1.GetSkeleton().GetPrim(), allBindings[0].GetSkeleton().GetPrim()) self.assertEqual([t.GetPrim() for t in binding1.GetSkinningTargets()], [t.GetPrim() for t in allBindings[0].GetSkinningTargets()]) self.assertEqual(binding2.GetSkeleton().GetPrim(), allBindings[1].GetSkeleton().GetPrim()) self.assertEqual([t.GetPrim() for t in binding2.GetSkinningTargets()], [t.GetPrim() for t in allBindings[1].GetSkinningTargets()])
def test_JointInfluences(self): """Tests interpretation of joint influences.""" testFile = "jointInfluences.usda" stage = Usd.Stage.Open(testFile) rootPath = "/JointInfluences" cache = UsdSkel.Cache() root = UsdSkel.Root(stage.GetPrimAtPath(rootPath)) self.assertTrue(cache.Populate(root, Usd.PrimDefaultPredicate)) def _GetSkinningQuery(path): return cache.GetSkinningQuery(stage.GetPrimAtPath(path)) self.assertFalse( _GetSkinningQuery( rootPath + "/ErrorCases/MismatchedInterpolation").HasJointInfluences()) self.assertFalse( _GetSkinningQuery( rootPath + "/ErrorCases/InvalidInterpolation1").HasJointInfluences()) self.assertFalse( _GetSkinningQuery( rootPath + "/ErrorCases/InvalidInterpolation2").HasJointInfluences()) self.assertFalse( _GetSkinningQuery( rootPath + "/ErrorCases/MismatchedElementSize").HasJointInfluences()) self.assertFalse( _GetSkinningQuery( rootPath + "/ErrorCases/InvalidElementSize").HasJointInfluences()) # # Validate error cases during ComputeJointInfluences() # query = _GetSkinningQuery(rootPath + "/ErrorCases/InvalidArraySize1") assert query.GetPrim() assert query assert not query.ComputeJointInfluences() assert not query.ComputeVaryingJointInfluences(10) query = _GetSkinningQuery(rootPath + "/ErrorCases/InvalidArraySize2") assert query assert not query.ComputeJointInfluences() assert not query.ComputeVaryingJointInfluences(10) # # The remaining cases should all be valid. # query = _GetSkinningQuery(rootPath + "/RigidWeights") assert query assert query.IsRigidlyDeformed() assert query.GetNumInfluencesPerComponent() == 3 influences = query.ComputeJointInfluences() assert influences indices, weights = influences assert indices == Vt.IntArray([1, 2, 3]) assert weights == Vt.FloatArray([5, 6, 7]) influences = query.ComputeVaryingJointInfluences(3) assert influences indices, weights = influences assert indices == Vt.IntArray([1, 2, 3, 1, 2, 3, 1, 2, 3]) assert weights == Vt.FloatArray([5, 6, 7, 5, 6, 7, 5, 6, 7]) query = _GetSkinningQuery(rootPath + "/NonRigidWeights") assert query assert not query.IsRigidlyDeformed() assert query.GetNumInfluencesPerComponent() == 2 influences = query.ComputeJointInfluences() assert influences indices, weights = influences assert indices == Vt.IntArray([1, 2, 3, 4]) assert weights == Vt.FloatArray([5, 6, 7, 8]) varyingInfluences = query.ComputeVaryingJointInfluences(2) assert influences == varyingInfluences
def _test_Populate(self): """Tests for correctness in interpretation of inherited bindings, as computed through Populate().""" testFile = "populate.usda" stage = Usd.Stage.Open(testFile) rootPath = "/InheritedBindings" cache = UsdSkel.Cache() root = UsdSkel.Root(stage.GetPrimAtPath(rootPath)) print "Expect warnings about invalid skel:skeletonInstance targets" self.assertTrue(cache.Populate(root)) def _GetSkelQuery(path): return cache.GetSkelQuery(stage.GetPrimAtPath(path)) def _GetInheritedSkelQuery(path): return cache.GetInheritedSkelQuery(stage.GetPrimAtPath(path)) def _GetSkelPath(skelQuery): return skelQuery.GetSkeleton().GetPrim().GetPath() def _GetAnimPath(skelQuery): return skelQuery.GetAnimQuery().GetPrim().GetPath() skel = _GetSkelQuery(rootPath + "/Model1") self.assertEqual(_GetSkelPath(skel), Sdf.Path("/Skel1")) assert not skel.GetAnimQuery() # an animationSource does not itself define a skel binding. # bindings are associated with skel:skeleton rels only! skel = _GetSkelQuery(rootPath + "/Model1/A") assert not skel skel = _GetSkelQuery(rootPath + "/Model1/A/B") self.assertEqual(_GetSkelPath(skel), Sdf.Path("/Skel2")) self.assertEqual(_GetAnimPath(skel), Sdf.Path("/Anim1")) skel = _GetSkelQuery(rootPath + "/Model1/C") self.assertEqual(_GetSkelPath(skel), Sdf.Path("/Skel3")) self.assertEqual(_GetAnimPath(skel), Sdf.Path("/Anim2")) # Inherited skel queries? self.assertEqual( _GetSkelPath(_GetInheritedSkelQuery(rootPath + "/Model1/A/B/Gprim")), _GetSkelPath(_GetSkelQuery(rootPath + "/Model1/A/B"))) self.assertEqual( _GetSkelPath(_GetInheritedSkelQuery(rootPath + "/Model1/A/B")), _GetSkelPath(_GetSkelQuery(rootPath + "/Model1/A/B"))) # Scope with no bound skel. assert not _GetSkelQuery(rootPath + "/Model2") assert not cache.GetSkelQuery(Usd.Prim()) # Scope with a bound skel, but whose animation source is inactive. skel = _GetSkelQuery(rootPath + "/Model3/SkelWithInactiveAnim") self.assertEqual(_GetSkelPath(skel), Sdf.Path("/Skel1")) assert not skel.GetAnimQuery() # Inheritance of skel:xform? skel = _GetSkelQuery(rootPath + "/IndirectBindings/Instance") self.assertEqual(skel.GetPrim().GetPath(), Sdf.Path(rootPath + "/IndirectBindings/Instance")) indirectSkel = _GetSkelQuery(rootPath + "/IndirectBindings/Indirect") self.assertEqual(indirectSkel.GetPrim().GetPath(), Sdf.Path(rootPath + "/IndirectBindings/Instance")) self.assertEqual(_GetSkelPath(indirectSkel), Sdf.Path("/Skel1")) nestedSkel = _GetSkelQuery(rootPath + "/IndirectBindings/Indirect/Instance") self.assertEqual( nestedSkel.GetPrim().GetPath(), Sdf.Path(rootPath + "/IndirectBindings/Indirect/Instance")) self.assertEqual(_GetSkelPath(nestedSkel), Sdf.Path("/Skel2")) self.assertFalse(_GetSkelQuery(rootPath + "/IndirectBindings/Illegal")) def _GetSkinningQuery(path): return cache.GetSkinningQuery(stage.GetPrimAtPath(path)) # Make sure some scopes are not being treated as skinning targets. nonSkinnablePaths = (rootPath + "/Model1/NonRigidScope1", rootPath + "/Model1/NonRigidScope2", rootPath + "/Model1/RigidScopeParent") for path in nonSkinnablePaths: assert not _GetSkinningQuery(path) query = _GetSkinningQuery(rootPath + "/Model1/NonRigidScope1/A") assert query assert query.IsRigidlyDeformed() assert query.GetMapper() self.assertEquals(query.GetJointOrder(), Vt.TokenArray(["A", "B", "C"])) query = _GetSkinningQuery(rootPath + "/Model1/NonRigidScope1/B") assert query assert not query.IsRigidlyDeformed() assert not query.GetMapper() query = _GetSkinningQuery(rootPath + "/Model1/NonRigidScope2/A") assert query assert query.IsRigidlyDeformed() assert query.GetMapper() self.assertEquals(query.GetJointOrder(), Vt.TokenArray(["A", "B", "C"])) query = _GetSkinningQuery(rootPath + "/Model1/NonRigidScope2/B") assert query assert query.IsRigidlyDeformed() assert not query.GetMapper() # TODO: When adding support for rigid deformation of intermediate # xformables, Model1/RigidScopeParent/RigidScope should be treated # as being skinnable. assert _GetSkinningQuery(rootPath + "/Model1/RigidScopeParent/RigidScope/A") assert _GetSkinningQuery(rootPath + "/Model1/RigidScopeParent/RigidScope/B")
def test_InheritedSkeletonBinding(self): """Tests for correctness in the interpretation of the inherited skel:skeleton binding.""" testFile = "populate.usda" stage = Usd.Stage.Open(testFile) cache = UsdSkel.Cache() root = UsdSkel.Root(stage.GetPrimAtPath("/SkelBinding")) self.assertTrue(cache.Populate(root, Usd.PrimDefaultPredicate)) skel1 = UsdSkel.Skeleton.Get(stage, "/Skel1") skel2 = UsdSkel.Skeleton.Get(stage, "/Skel2") binding1 = cache.ComputeSkelBinding(root, skel1, Usd.PrimDefaultPredicate) self.assertEqual(binding1.GetSkeleton().GetPrim(), skel1.GetPrim()) self.assertEqual(len(binding1.GetSkinningTargets()), 1) skinningQuery1 = binding1.GetSkinningTargets()[0] self.assertEqual(skinningQuery1.GetPrim().GetPath(), Sdf.Path("/SkelBinding/Scope/Inherit")) # Inherited skinning properties. self.assertEqual( skinningQuery1.GetJointIndicesPrimvar().GetAttr().GetPath(). GetPrimPath(), Sdf.Path("/SkelBinding/Scope")) self.assertEqual( skinningQuery1.GetJointWeightsPrimvar().GetAttr().GetPath(). GetPrimPath(), Sdf.Path("/SkelBinding/Scope")) self.assertEqual(skinningQuery1.GetJointOrder(), Vt.TokenArray(["scope"])) # Non-inherited skinning properties. self.assertFalse(skinningQuery1.GetBlendShapesAttr()) self.assertFalse(skinningQuery1.GetBlendShapeTargetsRel()) binding2 = cache.ComputeSkelBinding(root, skel2, Usd.PrimDefaultPredicate) self.assertEqual(binding2.GetSkeleton().GetPrim(), skel2.GetPrim()) self.assertEqual(len(binding2.GetSkinningTargets()), 1) skinningQuery2 = binding2.GetSkinningTargets()[0] self.assertEqual(skinningQuery2.GetPrim().GetPath(), Sdf.Path("/SkelBinding/Scope/Override")) # Inherited skinning properties. self.assertEqual(skinningQuery2.GetPrim().GetPath(), Sdf.Path("/SkelBinding/Scope/Override")) self.assertEqual( skinningQuery2.GetJointIndicesPrimvar().GetAttr().GetPath(). GetPrimPath(), Sdf.Path("/SkelBinding/Scope/Override")) self.assertEqual( skinningQuery2.GetJointWeightsPrimvar().GetAttr().GetPath(). GetPrimPath(), Sdf.Path("/SkelBinding/Scope/Override")) self.assertEqual(skinningQuery2.GetJointOrder(), Vt.TokenArray(["override"])) self.assertEqual(skinningQuery2.GetBlendShapeOrder(), Vt.TokenArray(["shape"])) # Non-inherited skinning properties. self.assertEqual( skinningQuery2.GetBlendShapesAttr().GetPath().GetPrimPath(), Sdf.Path("/SkelBinding/Scope/Override")) self.assertEqual( skinningQuery2.GetBlendShapeTargetsRel().GetPath().GetPrimPath(), Sdf.Path("/SkelBinding/Scope/Override")) allBindings = cache.ComputeSkelBindings(root, Usd.PrimDefaultPredicate) # Expecting two resolved bindings. This should *not* include bindings # for any inactive skels or instances self.assertEqual(len(allBindings), 2) self.assertEqual(binding1.GetSkeleton().GetPrim(), allBindings[0].GetSkeleton().GetPrim()) self.assertEqual( [t.GetPrim() for t in binding1.GetSkinningTargets()], [t.GetPrim() for t in allBindings[0].GetSkinningTargets()]) self.assertEqual(binding2.GetSkeleton().GetPrim(), allBindings[1].GetSkeleton().GetPrim()) self.assertEqual( [t.GetPrim() for t in binding2.GetSkinningTargets()], [t.GetPrim() for t in allBindings[1].GetSkinningTargets()])
def test_SkeletonQuery(self): random.seed(0) numFrames = 10 stage = Usd.Stage.CreateInMemory() skelRoot = UsdSkel.Root.Define(stage, "/SkelRoot") anim = UsdSkel.Animation.Define(stage, "/SkelRoot/Anim") skel = UsdSkel.Skeleton.Define(stage, "/SkelRoot/Skel") binding = UsdSkel.BindingAPI.Apply(skelRoot.GetPrim()) binding.CreateSkeletonRel().SetTargets([skel.GetPrim().GetPath()]) binding.CreateAnimationSourceRel().SetTargets( [anim.GetPrim().GetPath()]) skelOrder = Vt.TokenArray(["/A", "/A/B", "/A/B/C", "/D", "/D/E/F"]) A, AB, ABC, D, DEF = list(range(len(skelOrder))) # Configure the skel. skel.GetJointsAttr().Set(skelOrder) restXforms = [_RandomXf() for _ in skelOrder] topology = UsdSkel.Topology(skelOrder) bindWorldXforms = UsdSkel.ConcatJointTransforms( topology, Vt.Matrix4dArray(restXforms)) skel.GetBindTransformsAttr().Set(bindWorldXforms) skel.GetRestTransformsAttr().Set(restXforms) # Configure root xforms. rootXforms = [_RandomXf() for _ in range(numFrames)] rootXfAttr = skelRoot.MakeMatrixXform() for frame, xf in enumerate(rootXforms): rootXfAttr.Set(xf, frame) # Configure anim. # Leave last element off of anim (tests remapping) animOrder = skelOrder[:-1] anim.GetJointsAttr().Set(animOrder) # Apply joint animations. animXforms = { i: [_RandomXf() for _ in range(len(animOrder))] for i in range(numFrames) } for frame, xforms in animXforms.items(): anim.SetTransforms(Vt.Matrix4dArray(xforms), frame) # # Constuct query and start testing # skelCache = UsdSkel.Cache() skelCache.Populate(skelRoot) query = skelCache.GetSkelQuery(skel) self.assertTrue(query) # Validate joint rest xform computations. xforms = query.ComputeJointLocalTransforms(0, atRest=True) expectedXforms = restXforms self.assertArrayIsClose(xforms, expectedXforms) xfCache = UsdGeom.XformCache() # Validate joint xforms computations. for t in range(numFrames): xforms = animXforms[t] xfCache.SetTime(t) # Joint local xforms. expectedLocalXforms = list(xforms) + [restXforms[-1]] computedLocalXforms = query.ComputeJointLocalTransforms(t) self.assertArrayIsClose(computedLocalXforms, expectedLocalXforms) # Joint skel-space xforms. expectedSkelXforms = Vt.Matrix4dArray([ xforms[A], xforms[AB] * xforms[A], xforms[ABC] * xforms[AB] * xforms[A], xforms[D], restXforms[DEF] * xforms[D] ]) computedSkelXforms = query.ComputeJointSkelTransforms(t) self.assertArrayIsClose(computedSkelXforms, expectedSkelXforms) # Joint world space xforms. expectedWorldXforms = Vt.Matrix4dArray([ expectedSkelXform * rootXforms[t] for i, expectedSkelXform in enumerate(expectedSkelXforms) ]) computedWorldXforms = query.ComputeJointWorldTransforms(xfCache) self.assertArrayIsClose(computedWorldXforms, expectedWorldXforms) # Joint rest-relative xforms. expectedRestRelXforms = Vt.Matrix4dArray([ localXf * restXf.GetInverse() for localXf, restXf in zip(expectedLocalXforms, restXforms) ]) computedRestRelXforms = query.ComputeJointRestRelativeTransforms(t) self.assertArrayIsClose(computedRestRelXforms, expectedRestRelXforms) # # Rest xforms # # Joint local rest xforms. expectedLocalXforms = restXforms computedLocalXforms = query.ComputeJointLocalTransforms( t, atRest=True) self.assertArrayIsClose(computedLocalXforms, expectedLocalXforms) # Joint skel-space rest xforms. expectedSkelXforms = Vt.Matrix4dArray([ restXforms[A], restXforms[AB] * restXforms[A], restXforms[ABC] * restXforms[AB] * restXforms[A], restXforms[D], restXforms[DEF] * restXforms[D] ]) computedSkelXforms = query.ComputeJointSkelTransforms(0, atRest=True) self.assertArrayIsClose(computedSkelXforms, expectedSkelXforms) # Joint world space rest xforms. expectedWorldXforms = Vt.Matrix4dArray([ expectedSkelXform * rootXforms[t] for i, expectedSkelXform in enumerate(expectedSkelXforms) ]) computedWorldXforms = query.ComputeJointWorldTransforms( xfCache, atRest=True) self.assertArrayIsClose(computedWorldXforms, expectedWorldXforms) # Validate skel instance transforms. for frame, expectedXf in enumerate(rootXforms): rootXf = skelRoot.GetLocalTransformation(frame) self.assertTrue(Gf.IsClose(rootXf, expectedXf, 1e-5)) # # Test that inactivate animation sources have no effect. # anim.GetPrim().SetActive(False) skelCache.Clear() skelCache.Populate(skelRoot) query = skelCache.GetSkelQuery(skel) expectedXforms = restXforms computedXforms = query.ComputeJointLocalTransforms(10) self.assertArrayIsClose(computedXforms, expectedXforms) anim.GetPrim().SetActive(True) # # Test that blocking transform components of the animation source # causes the animation source to be ignored. # anim.GetTranslationsAttr().Block() skelCache.Clear() skelCache.Populate(skelRoot) query = skelCache.GetSkelQuery(skel) expectedXforms = restXforms computedXforms = query.ComputeJointLocalTransforms(5) self.assertArrayIsClose(computedXforms, expectedXforms)
def test_InstancedSkeletonBinding(self): """Tests for correctness in the interpretation of the inherited skel:skeleton binding with instancing.""" testFile = "populate.usda" stage = Usd.Stage.Open(testFile) cache = UsdSkel.Cache() root = UsdSkel.Root(stage.GetPrimAtPath("/SkelBinding")) self.assertTrue(cache.Populate(root, Usd.TraverseInstanceProxies())) skel1 = UsdSkel.Skeleton.Get(stage, "/Skel1") binding1 = cache.ComputeSkelBinding(root, skel1, Usd.TraverseInstanceProxies()) self.assertEqual(binding1.GetSkeleton().GetPrim(), skel1.GetPrim()) self.assertEqual(len(binding1.GetSkinningTargets()), 2) skinningQuery1 = binding1.GetSkinningTargets()[1] self.assertEqual(skinningQuery1.GetPrim().GetPath(), Sdf.Path("/SkelBinding/Instance/Inherit")) # Inherited skinning properties. self.assertEqual( skinningQuery1.GetJointIndicesPrimvar().GetAttr().GetPath(). GetPrimPath(), Sdf.Path("/SkelBinding/Instance")) self.assertEqual( skinningQuery1.GetJointWeightsPrimvar().GetAttr().GetPath(). GetPrimPath(), Sdf.Path("/SkelBinding/Instance")) self.assertEqual(skinningQuery1.GetJointOrder(), Vt.TokenArray(["instance"])) # Non-inherited skinning properties. self.assertFalse(skinningQuery1.GetBlendShapesAttr()) self.assertFalse(skinningQuery1.GetBlendShapeTargetsRel()) allBindings = cache.ComputeSkelBindings(root, Usd.TraverseInstanceProxies()) # Expecting three resolved bindings. This should *not* include bindings # for any inactive skels, but does include instances self.assertEqual(len(allBindings), 3) skel2 = UsdSkel.Skeleton.Get(stage, "/SkelBinding/Instance/Skel") binding2 = cache.ComputeSkelBinding(root, skel2, Usd.TraverseInstanceProxies()) self.assertEqual(binding2.GetSkeleton().GetPrim(), allBindings[2].GetSkeleton().GetPrim()) self.assertEqual( [t.GetPrim() for t in binding2.GetSkinningTargets()], [t.GetPrim() for t in allBindings[2].GetSkinningTargets()]) inheritBindingMesh = stage.GetPrimAtPath( "/SkelBinding/Instance/Inherit") overrideBindingMesh = stage.GetPrimAtPath( "/SkelBinding/Instance/Override") # Instances should not be discoverable with a default predicate. cache = UsdSkel.Cache() cache.Populate(root, Usd.PrimDefaultPredicate) self.assertFalse(cache.GetSkinningQuery(inheritBindingMesh)) self.assertFalse(cache.GetSkinningQuery(overrideBindingMesh)) # Need to explicitly traverse instance prototypes to see these bindings. cache.Populate(root, Usd.TraverseInstanceProxies()) query = cache.GetSkinningQuery(inheritBindingMesh) self.assertTrue(query) self.assertEqual(list(query.GetJointOrder()), ["instance"]) query = cache.GetSkinningQuery(overrideBindingMesh) self.assertTrue(query) self.assertEqual(list(query.GetJointOrder()), ["override"]) self.assertEqual(list(query.GetBlendShapeOrder()), ["override"])