def testPivot(self): """ Tests that pivotPosition attribute doesn't interfere with the matrix that we get in maya when importing a usd file. """ def _usdToMayaPath(usdPath): return str(usdPath).replace('/', '|') from maya import cmds usdFile = os.path.join(self.inputPath, "UsdImportXformsTest", "pivotTests.usda") from pxr import Usd, UsdGeom stage = Usd.Stage.Open(usdFile) xformCache = UsdGeom.XformCache() cmds.usdImport(file=os.path.abspath(usdFile), primPath='/World') usdPaths = [ '/World/anim/chars/SomeCharacter/Geom/Face/Eyes/LEye', '/World/anim/chars/SomeCharacter/Geom/Face/Eyes/LEye/Sclera_sbdv', '/World/anim/chars/SomeCharacter/Geom/Face/Eyes/REye/Sclera_sbdv', '/World/anim/chars/SomeCharacter/Geom/Hair/HairStandin/Hair/Hair_sbdv', '/World/anim/chars/SomeCharacter/Geom/Hair/HairStandin/Hair/HairFrontPiece_sbdv', ] for usdPath in usdPaths: usdMatrix = xformCache.GetLocalToWorldTransform(stage.GetPrimAtPath(usdPath)) mayaPath = _usdToMayaPath(usdPath) mayaMatrix = Gf.Matrix4d(*cmds.xform(mayaPath, query=True, matrix=True, worldSpace=True)) print('testing matrix at', usdPath) self.assertTrue(Gf.IsClose( usdMatrix.ExtractTranslation(), mayaMatrix.ExtractTranslation(), self.EPSILON))
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_ResetXformStack(self): s = Usd.Stage.CreateInMemory() x = UsdGeom.Xform.Define(s, '/World') x.AddTranslateOp().Set(Gf.Vec3d(20, 30, 40)) x.SetResetXformStack(True) self.assertEqual(x.GetXformOpOrderAttr().Get(), Vt.TokenArray(('!resetXformStack!', 'xformOp:translate'))) # Calling it twice should have no effect the second time. x.SetResetXformStack(True) self.assertEqual(x.GetXformOpOrderAttr().Get(), Vt.TokenArray(('!resetXformStack!', 'xformOp:translate'))) x.SetResetXformStack(False) self.assertEqual(x.GetXformOpOrderAttr().Get(), Vt.TokenArray(('xformOp:translate', ))) # Again, calling this twice shouldn't make a difference. x.SetResetXformStack(False) self.assertEqual(x.GetXformOpOrderAttr().Get(), Vt.TokenArray(('xformOp:translate', ))) x.AddTransformOp().Set(Gf.Matrix4d(1.0)) x.SetResetXformStack(True) self.assertEqual(x.GetXformOpOrderAttr().Get(), Vt.TokenArray(('!resetXformStack!', 'xformOp:translate', 'xformOp:transform'))) x.SetResetXformStack(False) self.assertEqual(x.GetXformOpOrderAttr().Get(), Vt.TokenArray(('xformOp:translate', 'xformOp:transform'))) cx = UsdGeom.Xform.Define(s, '/World/Model') cx.AddTranslateOp().Set(Gf.Vec3d(10, 10, 10)) cache = UsdGeom.XformCache() cxCtm = cache.GetLocalToWorldTransform(cx.GetPrim()) self._AssertCloseXf(cxCtm, Gf.Matrix4d(1.0).SetTranslate(Gf.Vec3d(30.0, 40.0, 50.0))) cx.SetResetXformStack(True) self.assertEqual(cx.GetXformOpOrderAttr().Get(), Vt.TokenArray(('!resetXformStack!', 'xformOp:translate'))) # Clear the xform cache and recompute local-to-world xform. cache.Clear() newCxCtm = cache.GetLocalToWorldTransform(cx.GetPrim()) localCxXform = cx.GetLocalTransformation(Usd.TimeCode.Default()) self._AssertCloseXf(newCxCtm, Gf.Matrix4d(1.0).SetTranslate(Gf.Vec3d(10.0, 10.0, 10.0))) self._AssertCloseXf(newCxCtm, localCxXform) # Test resetXformStack when it's not at the beginning of xformOpOrder. cx.SetResetXformStack(False) newXformOpOrder = list(cx.GetXformOpOrderAttr().Get()) newXformOpOrder.append(UsdGeom.XformOpTypes.resetXformStack) cx.GetXformOpOrderAttr().Set(newXformOpOrder) cx.AddTransformOp().Set(Gf.Matrix4d(2.0)) self.assertTrue(cx.GetResetXformStack())
def test_Layers(self): layeredFile = 'testUsdAbcSDFArguments.usda' topologyFile = 'testUsdAbcSDFArgumentsMesh.abc' flatFile = 'testUsdAbcSDFArgumentsFlat.abc' time = Usd.TimeCode() xformCache = UsdGeom.XformCache(time) stage = Usd.Stage.Open(layeredFile) self.assertTrue(stage) pCubeShape1 = UsdGeom.Mesh.Get(stage, '/AlembicRoot/pCubeShape1') pCubeShape2 = UsdGeom.Mesh.Get(stage, '/AlembicRoot/pCubeShape2') self.assertTrue(pCubeShape1) self.assertTrue(pCubeShape2) topoABC = Usd.Stage.Open(topologyFile) self.assertTrue(topoABC) pCubeShape1ABCPure = UsdGeom.Mesh.Get(topoABC, '/pCubeShape1') pCubeShape2ABCPure = UsdGeom.Mesh.Get(topoABC, '/pCubeShape2') self.assertTrue(pCubeShape1ABCPure) self.assertTrue(pCubeShape2ABCPure) # Test the Xforms got layered in properly # self.assertEqual(xformCache.GetLocalToWorldTransform(pCubeShape1.GetPrim()), xformCache.GetLocalToWorldTransform(pCubeShape1ABCPure.GetPrim())) self.assertEqual(xformCache.GetLocalToWorldTransform(pCubeShape2.GetPrim()), xformCache.GetLocalToWorldTransform(pCubeShape2ABCPure.GetPrim())) # Test various attributes & primavars came through # self.assertEqual(len(pCubeShape1.GetPointsAttr().Get(time)), len(pCubeShape2.GetPointsAttr().Get(time))) self.assertEqual(len(pCubeShape1.GetNormalsAttr().Get(time)), 8) self.assertEqual(len(pCubeShape2.GetNormalsAttr().Get(time)), 24) pCubeShape1UV = pCubeShape1.GetPrimvar('uv') pCubeShape2UV = pCubeShape2.GetPrimvar('uv') self.assertEqual(pCubeShape1UV.GetTypeName(), 'float2[]') self.assertEqual(pCubeShape2UV.GetTypeName(), 'float2[]') self.assertEqual(pCubeShape1UV.GetInterpolation() , 'varying') self.assertEqual(len(pCubeShape1UV.Get(time)), 8) self.assertEqual(pCubeShape2UV.GetInterpolation(), 'faceVarying') self.assertEqual(len(pCubeShape2UV.Get(time)), 14) self.assertEqual(len(pCubeShape2UV.GetIndices(time)), 24) # Test against the known flattened version # flatABC = Usd.Stage.Open(flatFile) self.assertTrue(flatABC) self.assertEqual(UsdGeom.Mesh.Get(flatABC, '/pCubeShape1').GetPrimvar('uv').Get(time), pCubeShape1UV.Get(time)) self.assertEqual(UsdGeom.Mesh.Get(flatABC, '/pCubeShape2').GetPrimvar('uv').Get(time), pCubeShape2UV.Get(time))
def spawn_actors(self): self.read_stage_up_axis(self.stage) self.current_frame = Usd.TimeCode.Default() self.xform_cache = UsdGeom.XformCache(self.current_frame) prim = self.stage.GetPseudoRoot() if prim.IsA(UsdGeom.Xformable): self.spawn_actors_recursive(prim, None) else: for child in prim.GetChildren(): self.spawn_actors_recursive(child, None)
def run(self): # Convert sub layer paths to relative has_sub_layer_paths = False if getattr(self, 'sub_layer_paths', None) != None: for i in xrange(len(self.sub_layer_paths)): self.sub_layer_paths[i] = self.to_relative_path( self.sub_layer_paths[i]) has_sub_layer_paths = True # List actors in Unreal self.unreal_prims = {} actors = unreal.EditorLevelLibrary.get_all_level_actors() for actor in actors: print("actor: " + str(actor)) prim_path = self.get_usd_path_from_actor_labels(actor) self.unreal_prims[prim_path] = actor # Write USD file with usd_unreal.utils.USDStageWrapper( self, Usd.Stage.CreateNew(self.filename)) as stage_wrapper: stage = self.stage if has_sub_layer_paths: for path in self.sub_layer_paths: stage.GetRootLayer().subLayerPaths.append(path) if self.stage_up_axis == 'y': UsdGeom.SetStageUpAxis(stage, UsdGeom.Tokens.y) elif self.stage_up_axis == 'z': UsdGeom.SetStageUpAxis(stage, UsdGeom.Tokens.z) self.current_frame = Usd.TimeCode.Default() self.xform_cache = UsdGeom.XformCache(self.current_frame) # Modify and add new objects for prim_path, actor in self.unreal_prims.iteritems(): # Detect changes vs parent scenes usd_node = None original_prim = None if has_sub_layer_paths: original_prim = stage.GetPrimAtPath(prim_path) if not original_prim.IsValid(): original_prim = None usd_node = self.handle_object(original_prim, prim_path, actor) # Delete level objects that do not exist in Unreal self.detect_deleted(stage.GetPseudoRoot()) # Commit to disk stage.Save()
def __init__(self, printTiming=False): QtCore.QObject.__init__(self) self._stage = None self._printTiming = printTiming self._currentFrame = Usd.TimeCode.Default() self._playing = False self._bboxCache = UsdGeom.BBoxCache( self._currentFrame, [IncludedPurposes.DEFAULT, IncludedPurposes.PROXY], True) self._xformCache = UsdGeom.XformCache(self._currentFrame)
def init_from_usd_camera(prim): data = CameraData() stage = prim.GetStage() xform_camera = stage.DefinePrim(prim.GetPath().pathString, prim.GetTypeName()) usd_camera = UsdGeom.Camera.Get(stage, prim.GetPath()) data.transform = UsdGeom.XformCache(bpy.context.scene.frame_current).GetLocalToWorldTransform(xform_camera) data.mode = usd_camera.GetProjectionAttr().Get() data.focal_length = usd_camera.GetFocalLengthAttr().Get() aperture = (usd_camera.GetHorizontalApertureAttr().Get(), usd_camera.GetVerticalApertureAttr().Get()) if data.mode == 'perspective': data.sensor_size = aperture elif data.mode == 'orthographic': # Use tenths of a world unit accorging to USD docs https://graphics.pixar.com/usd/docs/api/class_gf_camera.html data.ortho_size = tuple(i / 10 for i in aperture) return data
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)