def exportDynamicAssmblyRefUSD(self, location, destination, rangeTimeCode, motionSample): scenegraph_path = self.fetchNameSceneGraphPrim(dagnode_path) scenegraph_tree = self.fetchListUSDPrim(dagnode_path) scenegraph_data = self.fetchDataDynamicMayaXform(dagnode_path,rangeTimeCode,motionSample) # create a UsdStage if os.path.isfile(destination): stage = Usd.Stage.Open(destination) else: stage = Usd.Stage.CreateNew(destination) for prim_node in scenegraph_tree: gprim = Usd.ModelAPI(UsdGeom.Xform.Define(stage, prim_node)) prim = stage.GetPrimAtPath( scenegraph_path ) root_prim = stage.GetPrimAtPath( self.fetchNameUsdRoot(scenegraph_path)) # set USD default setting stage.SetStartTimeCode(rangeTimeCode[0]) stage.SetEndTimeCode(rangeTimeCode[1]) stage.SetDefaultPrim(root_prim) UsdGeom.SetStageUpAxis(stage, UsdGeom.Tokens.y) # set visibility rotateXYZ scale translate sampleTime data into specific prim for frameData in sorted(scenegraph_data.keys()): if scenegraph_data[frameData]["visibility"]: UsdGeom.Imageable(prim).MakeVisible(frameData) else: UsdGeom.Imageable(prim).MakeInvisible(frameData) rotateXYZ = scenegraph_data[frameData]["rotateXYZ"] UsdGeom.XformCommonAPI(prim).SetRotate(tuple(rotateXYZ),UsdGeom.XformCommonAPI.RotationOrderXYZ,frameData) scale = scenegraph_data[frameData]["scale"] UsdGeom.XformCommonAPI(prim).SetScale(tuple(scale),frameData) translate = scenegraph_data[frameData]["translate"] UsdGeom.XformCommonAPI(prim).SetTranslate(tuple(translate), frameData) # save UsdStage stage.GetRootLayer().Save()
def test_MatrixDecomposition(self): s = Usd.Stage.CreateInMemory() x = UsdGeom.Xform.Define(s, "/X") xXformAPI = UsdGeom.XformCommonAPI(x) self.assertTrue(xXformAPI) self.assertTrue( xXformAPI.SetXformVectors( translation=Gf.Vec3d(10., 20., 30.), rotation=Gf.Vec3f(30, 45, 60), scale=Gf.Vec3f(1., 2., 3.), pivot=Gf.Vec3f( 0, 0, 0), # pivot has to be 0 for proper decomposition. rotationOrder=UsdGeom.XformCommonAPI.RotationOrderYXZ, time=Usd.TimeCode.Default())) y = UsdGeom.Xform.Define(s, "/Y") y.MakeMatrixXform().Set( x.GetLocalTransformation(Usd.TimeCode.Default())) yXformAPI = UsdGeom.XformCommonAPI(y) self.assertFalse(yXformAPI) # none of the operations will work on an incompatible xformable. self.assertFalse(yXformAPI.SetTranslate(Gf.Vec3d(10, 20, 30))) self.assertFalse(yXformAPI.SetRotate(Gf.Vec3f(10, 20, 30))) self.assertFalse(yXformAPI.SetScale(Gf.Vec3f(1, 2, 3))) self.assertFalse(yXformAPI.SetPivot(Gf.Vec3f(10, 10, 10))) # GetXformVectors will work on an incompatible xformable. # It does a full on decomposition in this case of the composed # transformation. # # The decomposition may not yield the exact set of input vectors, but the # computed local transformation must match, as verified by the last # AssetClose call below. xformVectors = yXformAPI.GetXformVectors(Usd.TimeCode.Default()) z = UsdGeom.Xform.Define(s, "/Z") zXformAPI = UsdGeom.XformCommonAPI(z) self.assertTrue(zXformAPI) self.assertTrue(zXformAPI.SetTranslate(xformVectors[0])) self.assertTrue(zXformAPI.SetRotate(xformVectors[1])) self.assertTrue(zXformAPI.SetScale(xformVectors[2])) self.assertTrue(zXformAPI.SetPivot(xformVectors[3])) # Verify that the final transform value matches, although the individual # component values *may* not. xtrans = x.GetLocalTransformation(Usd.TimeCode.Default()) ztrans = z.GetLocalTransformation(Usd.TimeCode.Default()) for a, b in zip([xtrans.GetRow(i) for i in range(4)], [ztrans.GetRow(i) for i in range(4)]): if any(map(math.isnan, a)) or any(map(math.isnan, b)): continue self._AssertGfIsClose(a, b, 1e-5)
def test_EmptyXformable(self): s = Usd.Stage.CreateInMemory() x = UsdGeom.Xform.Define(s, "/X") xXformAPI = UsdGeom.XformCommonAPI(x) self.assertTrue(xXformAPI) self.assertEqual( xXformAPI.GetXformVectors(Usd.TimeCode.Default()), (Gf.Vec3d(0, 0, 0), Gf.Vec3f(0, 0, 0), Gf.Vec3f(1, 1, 1), Gf.Vec3f(0, 0, 0), UsdGeom.XformCommonAPI.RotationOrderXYZ)) self.assertTrue( xXformAPI.SetXformVectors( translation=Gf.Vec3d(10., 20., 30.), rotation=Gf.Vec3f(30, 45, 60), scale=Gf.Vec3f(1., 2., 3.), pivot=Gf.Vec3f(0, 10, 0), rotationOrder=UsdGeom.XformCommonAPI.RotationOrderYXZ, time=Usd.TimeCode.Default())) self.assertEqual( x.GetXformOpOrderAttr().Get(), Vt.TokenArray(('xformOp:translate', 'xformOp:translate:pivot', 'xformOp:rotateYXZ', 'xformOp:scale', '!invert!xformOp:translate:pivot'))) self.assertTrue(xXformAPI) self.assertEqual(xXformAPI.GetXformVectors(Usd.TimeCode.Default()), (Gf.Vec3d(10., 20., 30.), Gf.Vec3f(30, 45, 60), Gf.Vec3f(1., 2., 3.), Gf.Vec3f(0, 10, 0), UsdGeom.XformCommonAPI.RotationOrderYXZ)) # Call SetXformVectors with a different rotation order. This should fail # and no values should get authored. with self.assertRaises(RuntimeError): xXformAPI.SetXformVectors( translation=Gf.Vec3d(100., 200., 300.), rotation=Gf.Vec3f(3, 4, 6), scale=Gf.Vec3f(3., 2., 1.), pivot=Gf.Vec3f(10, 0, 10), rotationOrder=UsdGeom.XformCommonAPI.RotationOrderZYX, time=Usd.TimeCode(10.0)) # Verify that the second SetXformVectors did not author any values. self.assertEqual(xXformAPI.GetXformVectors(Usd.TimeCode(10.0)), (Gf.Vec3d(10., 20., 30.), Gf.Vec3f(30, 45, 60), Gf.Vec3f(1., 2., 3.), Gf.Vec3f(0, 10, 0), UsdGeom.XformCommonAPI.RotationOrderYXZ)) # Adding an extra op, causes X to become incompatible. x.AddTranslateOp(opSuffix="extraTranslate") self.assertFalse(UsdGeom.XformCommonAPI(x))
def createAnimatedHierarchy(stage): """ Create simple hierarchy in the stage: /ParentA /Sphere /Cube /ParenB Entire ParentA hierarchy will receive time samples on translate for time 1 and 100 """ parentA = "/ParentA" parentB = "/ParentB" childSphere = "/ParentA/Sphere" childCube = "/ParentA/Cube" parentPrimA = stage.DefinePrim(parentA, 'Xform') parentPrimB = stage.DefinePrim(parentB, 'Xform') childPrimSphere = stage.DefinePrim(childSphere, 'Sphere') childPrimCube = stage.DefinePrim(childCube, 'Cube') UsdGeom.XformCommonAPI(parentPrimA).SetRotate((0,0,0)) UsdGeom.XformCommonAPI(parentPrimB).SetTranslate((1,10,0)) time1 = Usd.TimeCode(1.) UsdGeom.XformCommonAPI(parentPrimA).SetTranslate((0,0,0),time1) UsdGeom.XformCommonAPI(childPrimSphere).SetTranslate((5,0,0),time1) UsdGeom.XformCommonAPI(childPrimCube).SetTranslate((0,0,5),time1) time2 = Usd.TimeCode(100.) UsdGeom.XformCommonAPI(parentPrimA).SetTranslate((0,5,0),time2) UsdGeom.XformCommonAPI(childPrimSphere).SetTranslate((-5,0,0),time2) UsdGeom.XformCommonAPI(childPrimCube).SetTranslate((0,0,-5),time2)
def testExportOrthographicViewCheckCamera(self): """ Tests exporting a specifically positioned orthographic camera. Looking through this camera in the Maya scene and in usdview should show a cube in each of the four corners of the frame. """ usdCamera = self._GetUsdCamera('ViewCheck/OrthographicCamera') # There should be no animation on any of the camera attributes. expectedPropertyTuples = [ ('clippingRange', Gf.Vec2f(0.1, 10000.0), False), ('focalLength', 35.0, False), ('focusDistance', 5.0, False), ('fStop', 5.6, False), ('horizontalAperture', 500, False), ('horizontalApertureOffset', None, False), ('projection', UsdGeom.Tokens.orthographic, False), ('verticalAperture', 500, False), ('verticalApertureOffset', None, False), ('xformOpOrder', Vt.TokenArray(['xformOp:translate', 'xformOp:rotateXYZ']), False), ] # There should be no animation on the transform either. self._ValidateUsdCamera(usdCamera, expectedPropertyTuples, False) # Validate the camera's xformOps at the default time. (translateOp, rotateOp) = usdCamera.GetOrderedXformOps() self.assertEqual(translateOp.GetOpType(), UsdGeom.XformOp.TypeTranslate) self.assertEqual(rotateOp.GetOpType(), UsdGeom.XformOp.TypeRotateXYZ) self.assertTrue(UsdGeom.XformCommonAPI(usdCamera)) self.assertTrue(Gf.IsClose(translateOp.Get(), Gf.Vec3d(0.0, -20.0, 0.0), 1e-6)) self.assertTrue( Gf.IsClose(rotateOp.Get(), Gf.Vec3f(90.0, 0.0, 0.0), 1e-6))
def _ValidateDistantLight(self): lightPrimPath = '/directionalLight1' lightPrim = self._stage.GetPrimAtPath(lightPrimPath) self.assertTrue(lightPrim) distantLight = UsdLux.DistantLight(lightPrim) self.assertTrue(distantLight) self.assertTrue(Gf.IsClose(distantLight.GetIntensityAttr().Get(1), 2, 1e-6)) self.assertTrue(Gf.IsClose(distantLight.GetColorAttr().Get(1), Gf.Vec3f(1, 0.9, 0.8), 1e-6)) self.assertTrue(Gf.IsClose(distantLight.GetAngleAttr().Get(1), 1.5, 1e-6)) self.assertTrue(Gf.IsClose(distantLight.GetAngleAttr().Get(5), 2, 1e-6)) rotateOp = distantLight.GetOrderedXformOps() self.assertEqual(rotateOp[0].GetOpType(), UsdGeom.XformOp.TypeRotateXYZ) self.assertTrue(UsdGeom.XformCommonAPI(distantLight)) self.assertTrue(Gf.IsClose(rotateOp[0].Get(1), Gf.Vec3f(-20, -40, 0.0), 1e-6)) self.assertTrue(lightPrim.HasAPI(UsdLux.ShadowAPI)) shadowAPI = UsdLux.ShadowAPI(lightPrim) self.assertTrue(shadowAPI) self.assertTrue(shadowAPI.GetShadowEnableAttr().Get(1)) self.assertTrue(Gf.IsClose(shadowAPI.GetShadowColorAttr().Get(1), Gf.Vec3f(0.1, 0.2, 0.3), 1e-6)) return
def _ValidateAreaLight(self): lightPrimPath = '/areaLight1' lightPrim = self._stage.GetPrimAtPath(lightPrimPath) self.assertTrue(lightPrim) rectLight = UsdLux.RectLight(lightPrim) self.assertTrue(rectLight) self.assertTrue(Gf.IsClose(rectLight.GetColorAttr().Get(), Gf.Vec3f(0.8, 0.7, 0.6), 1e-6)) self.assertTrue(Gf.IsClose(rectLight.GetIntensityAttr().Get(), 1.2, 1e-6)) # normalize didn't exist before Maya 2020 if getMayaAPIVersion() > 2019: self.assertTrue(rectLight.GetNormalizeAttr().Get()) self.assertTrue(lightPrim.HasAPI(UsdLux.ShadowAPI)) shadowAPI = UsdLux.ShadowAPI(lightPrim) self.assertTrue(shadowAPI) (translateOp,rotateOp,scaleOp) = rectLight.GetOrderedXformOps() self.assertEqual(translateOp.GetOpType(), UsdGeom.XformOp.TypeTranslate) self.assertEqual(rotateOp.GetOpType(), UsdGeom.XformOp.TypeRotateXYZ) self.assertEqual(scaleOp.GetOpType(), UsdGeom.XformOp.TypeScale) self.assertTrue(UsdGeom.XformCommonAPI(rectLight)) self.assertTrue(Gf.IsClose(translateOp.Get(1), Gf.Vec3d(8, 0, 10), 1e-6)) self.assertTrue(Gf.IsClose(scaleOp.Get(1), Gf.Vec3f(4,3,2), 1e-6)) self.assertTrue(Gf.IsClose(rotateOp.Get(1), Gf.Vec3f(0,23,0), 1e-6))
def _ValidateSpotLight(self): lightPrimPath = '/spotLight1' lightPrim = self._stage.GetPrimAtPath(lightPrimPath) self.assertTrue(lightPrim) sphereLight = UsdLux.SphereLight(lightPrim) self.assertTrue(sphereLight) self.assertTrue(Gf.IsClose(sphereLight.GetColorAttr().Get(1), Gf.Vec3f(0.3, 1, 0.2), 1e-6)) self.assertTrue(Gf.IsClose(sphereLight.GetColorAttr().Get(5), Gf.Vec3f(0, 0.2, 0.1), 1e-6)) self.assertTrue(Gf.IsClose(sphereLight.GetIntensityAttr().Get(1), 0.8, 1e-6)) self.assertTrue(Gf.IsClose(sphereLight.GetDiffuseAttr().Get(1), 0, 1e-6)) self.assertTrue(Gf.IsClose(sphereLight.GetTreatAsPointAttr().Get(1), 1, 1e-6)) self.assertTrue(Gf.IsClose(sphereLight.GetRadiusAttr().Get(1), 0, 1e-6)) (translateOp,rotateOp) = sphereLight.GetOrderedXformOps() self.assertEqual(translateOp.GetOpType(), UsdGeom.XformOp.TypeTranslate) self.assertEqual(rotateOp.GetOpType(), UsdGeom.XformOp.TypeRotateXYZ) self.assertTrue(UsdGeom.XformCommonAPI(sphereLight)) self.assertTrue(Gf.IsClose(translateOp.Get(1), Gf.Vec3d(10, 7, -8), 1e-6)) self.assertTrue(Gf.IsClose(translateOp.Get(5), Gf.Vec3d(5, 3, 8), 1e-6)) self.assertTrue(Gf.IsClose(rotateOp.Get(1), Gf.Vec3f(-45, 90, -5), 1e-6)) self.assertTrue(lightPrim.HasAPI(UsdLux.ShadowAPI)) shadowAPI = UsdLux.ShadowAPI(lightPrim) self.assertTrue(shadowAPI) self.assertTrue(lightPrim.HasAPI(UsdLux.ShapingAPI)) shapingAPI = UsdLux.ShapingAPI(lightPrim) self.assertTrue(shapingAPI) self.assertTrue(Gf.IsClose(shapingAPI.GetShapingConeAngleAttr().Get(1), 25, 1e-6)) self.assertTrue(Gf.IsClose(shapingAPI.GetShapingConeSoftnessAttr().Get(1), 0.4, 1e-6)) self.assertTrue(Gf.IsClose(shapingAPI.GetShapingFocusAttr().Get(1), 8, 1e-6))
def test_GetRotationTransform(self): """ Asserts that computing the rotation matrix via XformCommonAPI is the same as computing directly from ops. """ s = Usd.Stage.CreateInMemory() count = 0 for opType in [ UsdGeom.XformOp.TypeRotateXYZ, UsdGeom.XformOp.TypeRotateXZY, UsdGeom.XformOp.TypeRotateYXZ, UsdGeom.XformOp.TypeRotateYZX, UsdGeom.XformOp.TypeRotateZXY, UsdGeom.XformOp.TypeRotateZYX, ]: count += 1 x = UsdGeom.Xform.Define(s, '/X%s' % count) x.AddXformOp(opType, UsdGeom.XformOp.PrecisionFloat).Set( Gf.Vec3f(10, 20, 30)) _, rotation, _, _, rotOrder = UsdGeom.XformCommonAPI(x)\ .GetXformVectorsByAccumulation(Usd.TimeCode.Default()) transform = UsdGeom.XformCommonAPI.GetRotationTransform( rotation, rotOrder) self.assertTrue( Gf.IsClose(x.GetLocalTransformation(), transform, 1e-5))
def testExportStaticPerspectiveCamera(self): usdCamera = self._GetUsdCamera('PerspCamStatic') # There should be no animation on any of the camera attributes. expectedPropertyTuples = [ ('clippingRange', Gf.Vec2f(0.1, 10000.0), False), ('focalLength', 35.0, False), ('focusDistance', 5.0, False), ('fStop', 11.0, False), ('horizontalAperture', 36.0, False), ('horizontalApertureOffset', 0.0, False), ('projection', UsdGeom.Tokens.perspective, False), ('verticalAperture', 24.0, False), ('verticalApertureOffset', 0.0, False), ('xformOpOrder', Vt.TokenArray(['xformOp:translate', 'xformOp:rotateXYZ']), False), ] # There should be no animation on the transform either. self._ValidateUsdCamera(usdCamera, expectedPropertyTuples, False) # Validate the camera's xformOps at the default time. (translateOp, rotateOp) = usdCamera.GetOrderedXformOps() self.assertEqual(translateOp.GetOpType(), UsdGeom.XformOp.TypeTranslate) self.assertEqual(rotateOp.GetOpType(), UsdGeom.XformOp.TypeRotateXYZ) self.assertTrue(UsdGeom.XformCommonAPI(usdCamera)) self.assertTrue( Gf.IsClose(translateOp.Get(), Gf.Vec3d(0.0, -5.0, 5.0), 1e-6)) self.assertTrue( Gf.IsClose(rotateOp.Get(), Gf.Vec3f(45.0, 0.0, 0.0), 1e-6))
def _visualize_mesh(self, mesh: Union[Dict[str, torch.Tensor], Mesh], object_path: str, translation: Tuple[float, float, float] = (0., 0., 0.), **kwargs): r""" Visualize mesh in USD. """ if isinstance(mesh, Mesh): vertices, faces = mesh.vertices, mesh.faces else: vertices, faces = mesh['vertices'], mesh['faces'] usd_mesh = UsdGeom.Mesh.Define(self.stage, object_path) num_faces = faces.size(0) is_tri = (faces.size(1) == 3) face_vertex_counts = [faces.size(1)] * num_faces vertices, _, _ = self._fit_to_stage(vertices, **kwargs) vertices = vertices.detach().cpu().numpy().astype(float) points = [Gf.Vec3f(*v) for v in vertices] faces = faces.detach().cpu().view(-1).numpy().astype(int) usd_mesh.GetFaceVertexCountsAttr().Set(face_vertex_counts) usd_mesh.GetPointsAttr().Set(Vt.Vec3fArray(points)) usd_mesh.GetFaceVertexIndicesAttr().Set(faces) if is_tri: usd_mesh.GetPrim().GetAttribute('subdivisionScheme').Set('none') UsdGeom.XformCommonAPI(usd_mesh.GetPrim()).SetTranslate(translation) self.save()
def test_PreserveResetXformStack(self): s = Usd.Stage.CreateInMemory() x = UsdGeom.Xform.Define(s, "/World") api = UsdGeom.XformCommonAPI(x) self.assertTrue(api) self.assertTrue(api.SetResetXformStack(True)) self.assertTrue(api.SetTranslate(Gf.Vec3d(10, 20, 30))) self.assertTrue(api.GetResetXformStack()) self.assertEqual( x.GetXformOpOrderAttr().Get(), Vt.TokenArray(('!resetXformStack!', 'xformOp:translate'))) self.assertTrue(api.SetRotate(Gf.Vec3f(10, 20, 30))) self.assertTrue(api.GetResetXformStack()) self.assertTrue(api.SetScale(Gf.Vec3f(10, 20, 30))) self.assertTrue(api.GetResetXformStack()) self.assertTrue(api.SetPivot(Gf.Vec3f(10, 20, 30))) self.assertTrue(api.GetResetXformStack()) self.assertEqual( x.GetXformOpOrderAttr().Get(), Vt.TokenArray( ('!resetXformStack!', 'xformOp:translate', 'xformOp:translate:pivot', 'xformOp:rotateXYZ', 'xformOp:scale', '!invert!xformOp:translate:pivot')))
def handle_transform_camera(usd_prim, actor): global unit_scale global stage_up_axis if actor.root_component == None: return unreal_transform = actor.root_component.get_relative_transform() unreal_location = unreal_transform.translation unreal_rotation = unreal_transform.rotation.rotator() rotz = unreal.Rotator(90,0,0) additional_rotation = unreal.Rotator(0,90,0) if stage_up_axis == 'z': additional_rotation = additional_rotation.combine(rotz) unreal_rotation = additional_rotation.combine(unreal_rotation) location = convert_location_from_unreal(unreal_location.to_tuple(),unit_scale) rotation = convert_rotation_from_unreal(unreal_rotation.to_tuple(), unit_scale) scale = convert_scale_from_unreal(unreal_transform.scale3d.to_tuple(), unit_scale) usd_transform = (location, rotation, scale) #usd_transform = usd_transform_from_unreal_transform(unreal_transform, unit_scale, stage_up_axis) xform_api = UsdGeom.XformCommonAPI(usd_prim) xform_api.SetTranslate(usd_transform[0]) xform_api.SetRotate(usd_transform[1], UsdGeom.XformCommonAPI.RotationOrderXYZ) xform_api.SetScale(usd_transform[2])
def testMayaShapeBBoxCacheClearing(self): ''' Verify that the bounding box cache gets cleared''' cmds.file(new=True, force=True) # create a Capsule via contextOps menu import mayaUsd_createStageWithNewLayer proxyShape = mayaUsd_createStageWithNewLayer.createStageWithNewLayer() proxyShapePath = ufe.PathString.path(proxyShape) proxyShapeItem = ufe.Hierarchy.createItem(proxyShapePath) proxyShapeContextOps = ufe.ContextOps.contextOps(proxyShapeItem) proxyShapeContextOps.doOp(['Add New Prim', 'Xform']) xformPath = ufe.PathString.path('%s,/Xform1' % proxyShape) xformItem = ufe.Hierarchy.createItem(xformPath) xformObject3d = ufe.Object3d.object3d(xformItem) proxyShapeContextOps = ufe.ContextOps.contextOps(xformItem) proxyShapeContextOps.doOp(['Add New Prim', 'Sphere']) proxyShapeContextOps.doOp(['Add New Prim', 'Sphere']) selectionList = OpenMaya.MSelectionList() selectionList.add(proxyShape) shapeNode = OpenMaya.MFnDagNode(selectionList.getDependNode(0)) # Two spheres at origin, the bounding box is the unit cube: expectedBBox = ((-1.0, -1.0, -1.0), (1.0, 1.0, 1.0)) self.assertTrue( almostEqualBBox(xformObject3d.boundingBox(), expectedBBox)) # Shape BBox should be the same (and will be cached): self.assertTrue(almostEqualBBox(shapeNode.boundingBox, expectedBBox)) sphere1Path = ufe.PathString.path('%s,/Xform1/Sphere1' % proxyShape) sphere1Item = ufe.Hierarchy.createItem(sphere1Path) sphere1Prim = mayaUsd.ufe.ufePathToPrim( ufe.PathString.string(sphere1Path)) UsdGeom.XformCommonAPI(sphere1Prim).SetTranslate((-5, 0, 0)) sphere2Path = ufe.PathString.path('%s,/Xform1/Sphere2' % proxyShape) sphere2Item = ufe.Hierarchy.createItem(sphere2Path) sphere2Prim = mayaUsd.ufe.ufePathToPrim( ufe.PathString.string(sphere2Path)) UsdGeom.XformCommonAPI(sphere2Prim).SetTranslate((0, 5, 0)) expectedBBox = ((-6.0, -1.0, -1.0), (1.0, 6.0, 1.0)) self.assertTrue( almostEqualBBox(xformObject3d.boundingBox(), expectedBBox)) # The next test will only work if the cache was cleared when translating # the spheres: self.assertTrue(almostEqualBBox(shapeNode.boundingBox, expectedBBox))
def main(): from pxr import Kind, Usd, UsdGeom setFilePath = os.path.join(ASSET_BASE, 'Room_set/Room_set.usd') # Create the model stage, the model prim, and also make the modelPrim the # default prim so that the layer can be referenced without specifying a # root path. stage = Usd.Stage.CreateNew(setFilePath) setModelPrim = UsdGeom.Xform.Define(stage, '/Room_set').GetPrim() stage.SetDefaultPrim(setModelPrim) # Lets viewing applications know how to orient a free camera properly UsdGeom.SetStageUpAxis(stage, UsdGeom.Tokens.y) # Models can have a "kind" which can be used to categorize models into # different types. This is useful for other applications to reason about # the model hierarchy. Usd.ModelAPI(setModelPrim).SetKind(Kind.Tokens.assembly) # add child models to our set. _AddModel(stage, '/Room_set/Furniture/Table', 'Table/Table.usd') ballNumber = 0 import math for row in range(5): tableX = 10 + row * 2 * BALL_RADIUS * math.cos(math.pi / 6) tableRowZ = -row * BALL_RADIUS numBallsInRow = row + 1 for i in range(numBallsInRow): ballNumber += 1 b = _AddModel(stage, '/Room_set/Props/Ball_%d' % ballNumber, 'Ball/Ball.usd') # tableX and tableZ will arrange the balls into a triangle. tableZ = tableRowZ + i * 2 * BALL_RADIUS ballXlate = (tableX, TABLE_HEIGHT + BALL_RADIUS, tableZ) # Apply the UsdGeom.Xformable schema to the model, and then set the # transformation. # We are only going to translate the balls, but we still use # the helper XformCommonAPI schema to instantiate a translate op. # XformCommonAPI helps ensure transform ops are interchangeable # between applications, when you can make do with SRT + pivot UsdGeom.XformCommonAPI(b).SetTranslate(ballXlate) # we conveniently named the shadingVariant the same as the name of # the ball. shadingVariantName = b.GetName() # get the variantSet "shadingVariant" and then set it accordingly. vs = b.GetVariantSets().GetVariantSet('shadingVariant') vs.SetVariantSelection(shadingVariantName) stage.GetRootLayer().Save()
def _MoveBall(ballPrim, offset): translation = (offset[0] * BALL_RADIUS, TABLE_HEIGHT + BALL_RADIUS, offset[1] * BALL_RADIUS) # Apply the UsdGeom.Xformable schema to the model, and then set the # transformation. Note we can use ordinary python tuples from pxr import UsdGeom UsdGeom.XformCommonAPI(ballPrim).SetTranslate(translation)
def __defineStaticUSDPrimTransform__(self,dagnode_path): ''' Try to define static prim xform information. ''' scenegraph_path = self.fetchNameSceneGraphPrim(dagnode_path) scenegraph_data = self.fetchDataStaticMayaXform(dagnode_path) prim = self.__stage__.GetPrimAtPath( scenegraph_path ) if scenegraph_data["visibility"]: UsdGeom.Imageable(prim).MakeVisible() else: UsdGeom.Imageable(prim).MakeInvisible() rotateXYZ = scenegraph_data["rotateXYZ"] UsdGeom.XformCommonAPI(prim).SetRotate(tuple(rotateXYZ),UsdGeom.XformCommonAPI.RotationOrderXYZ) scale = scenegraph_data["scale"] UsdGeom.XformCommonAPI(prim).SetScale(tuple(scale)) translate = scenegraph_data["translate"] UsdGeom.XformCommonAPI(prim).SetTranslate(tuple(translate))
def generate_ticker_cube(index, stage, stock_name): stage.SetStartTimeCode(0) stage.SetEndTimeCode(192) TextureRoot = UsdGeom.Xform.Define(stage, '/TexModel' + stock_name) Usd.ModelAPI(TextureRoot).SetKind(Kind.Tokens.component) billboard = UsdGeom.Mesh.Define( stage, "/TexModel" + stock_name + "/card" + stock_name) billboard.CreatePointsAttr([(-5, -5, 5), (5, -5, 5), (5, 5, 5), (-5, 5, 5)]) billboard.CreateFaceVertexCountsAttr([4]) billboard.CreateFaceVertexIndicesAttr([0, 1, 2, 3]) billboard.CreateExtentAttr([(-5, -5, 5), (5, 5, 5)]) texCoords = billboard.CreatePrimvar("st", Sdf.ValueTypeNames.TexCoord2fArray, UsdGeom.Tokens.varying) texCoords.Set([(0, 0), (1, 0), (1, 1), (0, 1)]) material = UsdShade.Material.Define( stage, '/TexModel' + stock_name + '/boardMat' + stock_name) stInput = material.CreateInput('frame:stPrimvarName', Sdf.ValueTypeNames.Token) stInput.Set('st') pbrShader = UsdShade.Shader.Define( stage, '/TexModel' + stock_name + '/boardMat/PBRShader' + stock_name) pbrShader.CreateIdAttr("UsdPreviewSurface") pbrShader.CreateInput("roughness", Sdf.ValueTypeNames.Float).Set(0.4) pbrShader.CreateInput("metallic", Sdf.ValueTypeNames.Float).Set(0.0) material.CreateSurfaceOutput().ConnectToSource(pbrShader, "surface") stReader = UsdShade.Shader.Define( stage, '/TexModel' + stock_name + '/boardMat/stReader' + stock_name) stReader.CreateIdAttr('UsdPrimvarReader_float2') stReader.CreateInput('varname', Sdf.ValueTypeNames.Token).ConnectToSource(stInput) print(stock_name) diffuseTextureSampler = UsdShade.Shader.Define( stage, '/TexModel' + stock_name + '/boardMat/diffuseTexture' + stock_name) diffuseTextureSampler.CreateIdAttr('UsdUVTexture') diffuseTextureSampler.CreateInput('file', Sdf.ValueTypeNames.Asset).Set( '/Users/Abhinav/Documents/USDZ/CNBC/textures/' + stock_name + '.png') diffuseTextureSampler.CreateInput( "st", Sdf.ValueTypeNames.Float2).ConnectToSource(stReader, 'result') diffuseTextureSampler.CreateOutput('rgb', Sdf.ValueTypeNames.Float3) pbrShader.CreateInput("diffuseColor", Sdf.ValueTypeNames.Color3f).ConnectToSource( diffuseTextureSampler, 'rgb') UsdShade.MaterialBindingAPI(billboard.GetPrim()).Bind(material) UsdGeom.XformCommonAPI(billboard).SetTranslate( (-20, 20 * index, -index * 20)) spin = billboard.AddRotateYOp(opSuffix='spin') spin.Set(time=0, value=0) spin.Set(time=192, value=1440) return stage
def _addCamera(stage): cam = UsdGeom.Camera.Define(stage, '/World/main_cam') # the camera derives from UsdGeom.Xformable so we can # use the XformCommonAPI on it, too, and see how rotations are handled xformAPI = UsdGeom.XformCommonAPI(cam) xformAPI.SetTranslate((8, 1.8, 8)) # -86 degree rotation around X axis. Can specify rotation order as # optional parameter xformAPI.SetRotate((-10, 0, 0))
def _set_xform(self,node,prim): translate = cmds.xform(node,q=1,t=1) rotate = cmds.xform(node,q=1,ro=1) scale = cmds.xform(node,q=1,s=1) xformAPI = UsdGeom.XformCommonAPI(prim) xformAPI.SetTranslate(translate) xformAPI.SetRotate(rotate) xformAPI.SetScale(scale)
def generate_price_cube(price, stock_name, stage, position, index): path = create_image(price, stock_name, position) TextureRoot = UsdGeom.Xform.Define( stage, '/priceModel' + stock_name + str(position)) Usd.ModelAPI(TextureRoot).SetKind(Kind.Tokens.component) billboard = UsdGeom.Mesh.Define( stage, "/priceModel" + stock_name + str(position) + "/card" + stock_name + str(position)) billboard.CreatePointsAttr([(-5, -5, 5), (5, -5, 5), (5, 5, 5), (-5, 5, 5)]) billboard.CreateFaceVertexCountsAttr([4]) billboard.CreateFaceVertexIndicesAttr([0, 1, 2, 3]) billboard.CreateExtentAttr([(-5, -5, 5), (5, 5, 5)]) texCoords = billboard.CreatePrimvar("st", Sdf.ValueTypeNames.TexCoord2fArray, UsdGeom.Tokens.varying) texCoords.Set([(0, 0), (1, 0), (1, 1), (0, 1)]) material = UsdShade.Material.Define( stage, '/priceModel' + stock_name + str(position) + '/boardMat' + stock_name + str(position)) stInput = material.CreateInput('frame:stPrimvarName', Sdf.ValueTypeNames.Token) stInput.Set('st') pbrShader = UsdShade.Shader.Define( stage, '/priceModel' + stock_name + str(position) + '/boardMat/PBRShader' + stock_name + str(position)) pbrShader.CreateIdAttr("UsdPreviewSurface") pbrShader.CreateInput("roughness", Sdf.ValueTypeNames.Float).Set(0.4) pbrShader.CreateInput("metallic", Sdf.ValueTypeNames.Float).Set(0.0) material.CreateSurfaceOutput().ConnectToSource(pbrShader, "surface") stReader = UsdShade.Shader.Define( stage, '/priceModel' + stock_name + str(position) + '/boardMat/stReader' + stock_name + str(position)) stReader.CreateIdAttr('UsdPrimvarReader_float2') stReader.CreateInput('varname', Sdf.ValueTypeNames.Token).ConnectToSource(stInput) diffuseTextureSampler = UsdShade.Shader.Define( stage, '/priceModel' + stock_name + str(position) + '/boardMat/diffuseTexture' + stock_name + str(position)) diffuseTextureSampler.CreateIdAttr('UsdUVTexture') diffuseTextureSampler.CreateInput('file', Sdf.ValueTypeNames.Asset).Set(path) diffuseTextureSampler.CreateInput( "st", Sdf.ValueTypeNames.Float2).ConnectToSource(stReader, 'result') diffuseTextureSampler.CreateOutput('rgb', Sdf.ValueTypeNames.Float3) pbrShader.CreateInput("diffuseColor", Sdf.ValueTypeNames.Color3f).ConnectToSource( diffuseTextureSampler, 'rgb') UsdShade.MaterialBindingAPI(billboard.GetPrim()).Bind(material) UsdGeom.XformCommonAPI(billboard).SetTranslate( (10 * position, (20 * index) + (price + 5), -index * 20))
def testBoundingBox(self): '''Test the Object3d bounding box interface.''' # Create a simple USD scene. Default sphere radius is 1, so extents # are from (-1, -1, -1) to (1, 1, 1). usdFilePath = cmds.internalVar(utd=1) + '/testObject3d.usda' stage = Usd.Stage.CreateNew(usdFilePath) xform = stage.DefinePrim('/parent', 'Xform') sphere = stage.DefinePrim('/parent/sphere', 'Sphere') extentAttr = sphere.GetAttribute('extent') extent = extentAttr.Get() assertVectorAlmostEqual(self, extent[0], [-1] * 3) assertVectorAlmostEqual(self, extent[1], [1] * 3) # Move the sphere. Its UFE bounding box should not be affected by # transformation hierarchy. UsdGeom.XformCommonAPI(xform).SetTranslate((7, 8, 9)) # Save out the file, and bring it back into Maya under a proxy shape. stage.GetRootLayer().Save() proxyShape = cmds.createNode('mayaUsdProxyShape') cmds.setAttr('mayaUsdProxyShape1.filePath', usdFilePath, type='string') # MAYA-101766: loading a stage is done by the proxy shape compute. # Because we're a script, no redraw is done, so need to pull explicitly # on the outStageData (and simply discard the returned data), to get # the proxy shape compute to run, and thus the stage to load. This # should be improved. Without a loaded stage, UFE item creation # fails. PPT, 31-10-2019. outStageData = nameToPlug('mayaUsdProxyShape1.outStageData') outStageData.asMDataHandle() proxyShapeMayaPath = cmds.ls(proxyShape, long=True)[0] proxyShapePathSegment = mayaUtils.createUfePathSegment( proxyShapeMayaPath) # Create a UFE scene item from the sphere prim. spherePathSegment = usdUtils.createUfePathSegment('/parent/sphere') spherePath = ufe.Path([proxyShapePathSegment, spherePathSegment]) sphereItem = ufe.Hierarchy.createItem(spherePath) # Get its Object3d interface. object3d = ufe.Object3d.object3d(sphereItem) # Get its bounding box. ufeBBox = object3d.boundingBox() # Compare it to known extents. assertVectorAlmostEqual(self, ufeBBox.min.vector, [-1] * 3) assertVectorAlmostEqual(self, ufeBBox.max.vector, [1] * 3) # Remove the test file. os.remove(usdFilePath)
def createCommonAPI(testCase, sphereXformable): sphereXformable.AddTranslateOp(UsdGeom.XformOp.PrecisionFloat, "pivot") sphereXformable.AddTranslateOp(UsdGeom.XformOp.PrecisionFloat, "pivot", True) self.assertEqual( sphereXformable.GetXformOpOrderAttr().Get(), Vt.TokenArray(("xformOp:translate:pivot", "!invert!xformOp:translate:pivot"))) self.assertTrue(UsdGeom.XformCommonAPI(sphereXformable))
def testFallbackCases(self): '''Fallback handler test cases.''' cmds.file(new=True, force=True) import mayaUsd_createStageWithNewLayer proxyShape = mayaUsd_createStageWithNewLayer.createStageWithNewLayer() proxyShapePath = ufe.PathString.path(proxyShape) proxyShapeItem = ufe.Hierarchy.createItem(proxyShapePath) proxyShapeContextOps = ufe.ContextOps.contextOps(proxyShapeItem) proxyShapeContextOps.doOp(['Add New Prim', 'Sphere']) spherePath = ufe.PathString.path('%s,/Sphere1' % proxyShape) sphereItem = ufe.Hierarchy.createItem(spherePath) sphereT3d = ufe.Transform3d.transform3d(sphereItem) spherePrim = mayaUsd.ufe.ufePathToPrim( ufe.PathString.string(spherePath)) sphereXformable = UsdGeom.Xformable(spherePrim) # Add transform ops that do not match either the Maya transform stack, # the USD common API transform stack, or a matrix stack. sphereXformable.AddTranslateOp() sphereXformable.AddTranslateOp(UsdGeom.XformOp.PrecisionFloat, "pivot") sphereXformable.AddRotateZOp() sphereXformable.AddTranslateOp(UsdGeom.XformOp.PrecisionFloat, "pivot", True) self.assertEqual( sphereXformable.GetXformOpOrderAttr().Get(), Vt.TokenArray( ("xformOp:translate", "xformOp:translate:pivot", "xformOp:rotateZ", "!invert!xformOp:translate:pivot"))) self.assertFalse(UsdGeom.XformCommonAPI(sphereXformable)) self.assertFalse(mayaUsd.lib.XformStack.MayaStack().MatchingSubstack( sphereXformable.GetOrderedXformOps())) # Select sphere. sn = ufe.GlobalSelection.get() sn.clear() sn.append(sphereItem) # Rotate sphere around X. cmds.rotate(30, 0, 0, r=True, os=True, fo=True) # Fallback interface will have added a RotXYZ transform op. self.assertEqual( sphereXformable.GetXformOpOrderAttr().Get(), Vt.TokenArray( ("xformOp:translate", "xformOp:translate:pivot", "xformOp:rotateZ", "!invert!xformOp:translate:pivot", "xformOp:rotateXYZ:maya_fallback")))
def _MoveCamera(stage): from pxr import UsdGeom, Gf cam = UsdGeom.Camera.Get(stage, '/World/main_cam') # the camera derives from UsdGeom.Xformable so we can # use the XformCommonAPI on it, too, and see how rotations are handled xformAPI = UsdGeom.XformCommonAPI(cam) xformAPI.SetTranslate( (8, 120, 8) ) # -86 degree rotation around X axis. Can specify rotation order as # optional parameter xformAPI.SetRotate( (-86, 0, 0 ) )
def relocateWorldCenter(self,in_dagnode_path="|assets", out_dagnode_path="|assets|scn"): ''' Try to define static prim xform information. ''' if not cmds.objExists(in_dagnode_path) or not cmds.objExists(out_dagnode_path): return if not self.isDAGNodeBeMoved(in_dagnode_path): return scenegraph_path = self.fetchNameSceneGraphPrim(out_dagnode_path) scenegraph_data = self.fetchDataStaticMayaXform(in_dagnode_path) prim = self.__stage__.GetPrimAtPath( scenegraph_path ) if scenegraph_data["visibility"]: UsdGeom.Imageable(prim).MakeVisible() else: UsdGeom.Imageable(prim).MakeInvisible() rotateXYZ = scenegraph_data["rotateXYZ"] UsdGeom.XformCommonAPI(prim).SetRotate(tuple(rotateXYZ),UsdGeom.XformCommonAPI.RotationOrderXYZ) scale = scenegraph_data["scale"] UsdGeom.XformCommonAPI(prim).SetScale(tuple(scale)) translate = scenegraph_data["translate"] UsdGeom.XformCommonAPI(prim).SetTranslate(tuple(translate))
def createXformOps(ufeObject): selDag, selPrim = getDagAndPrimFromUfe(ufeObject) stage = mayaUsdLib.GetPrim(selDag).GetStage() primPath = Sdf.Path(selPrim) prim = stage.GetPrimAtPath(primPath) xformAPI = UsdGeom.XformCommonAPI(prim) xformAPI.CreateXformOps( UsdGeom.XformCommonAPI.OpTranslate, UsdGeom.XformCommonAPI.OpRotate, UsdGeom.XformCommonAPI.OpScale)
def handle_transform_component(usd_prim, component): global unit_scale global stage_up_axis unreal_transform = component.get_relative_transform() usd_transform = usd_transform_from_unreal_transform(unreal_transform, unit_scale, stage_up_axis) xform_api = UsdGeom.XformCommonAPI(usd_prim) xform_api.SetTranslate(usd_transform[0]) xform_api.SetRotate(usd_transform[1], UsdGeom.XformCommonAPI.RotationOrderXYZ) xform_api.SetScale(usd_transform[2])
def _ValidateXformVectorsByAccumulation(self, xformable, expectedTranslation, expectedRotation, expectedScale, expectedPivot, expectedRotOrder, time=None): if not time: time = Usd.TimeCode.Default() (translation, rotation, scale, pivot, rotOrder) = UsdGeom.XformCommonAPI( xformable).GetXformVectorsByAccumulation(time) self.assertTrue(Gf.IsClose(expectedTranslation, translation, 1e-5)) self.assertTrue(Gf.IsClose(expectedRotation, rotation, 1e-5)) self.assertTrue(Gf.IsClose(expectedScale, scale, 1e-5)) self.assertTrue(Gf.IsClose(expectedPivot, pivot, 1e-5)) self.assertEqual(expectedRotOrder, rotOrder)
def testExportPerspectiveCameraAnimatedTransform(self): usdCamera = self._GetUsdCamera('PerspCamAnimTransform') # There should be no animation on any of the camera attributes. expectedPropertyTuples = [ ('clippingRange', Gf.Vec2f(0.1, 10000.0), False), ('focalLength', 35.0, False), ('focusDistance', 5.0, False), ('fStop', 5.6, False), ('horizontalAperture', 36.0, False), ('horizontalApertureOffset', 0.0, False), ('projection', UsdGeom.Tokens.perspective, False), ('verticalAperture', 24.0, False), ('verticalApertureOffset', 0.0, False), ('xformOpOrder', Vt.TokenArray(['xformOp:translate', 'xformOp:rotateXYZ']), False), ] # There SHOULD be animation on the transform. self._ValidateUsdCamera(usdCamera, expectedPropertyTuples, True) # Get the camera's xformOps. (translateOp, rotateOp) = usdCamera.GetOrderedXformOps() self.assertEqual(translateOp.GetOpType(), UsdGeom.XformOp.TypeTranslate) self.assertEqual(rotateOp.GetOpType(), UsdGeom.XformOp.TypeRotateXYZ) self.assertTrue(UsdGeom.XformCommonAPI(usdCamera)) # The xformOps should NOT have values at the default time. self.assertEqual(translateOp.Get(), None) self.assertEqual(rotateOp.Get(), None) # Validate the camera's xformOps at a few non-default timecodes. self.assertTrue( Gf.IsClose(translateOp.Get(1), Gf.Vec3d(0.0, -5.0, 5.0), 1e-6)) self.assertTrue( Gf.IsClose(translateOp.Get(25), Gf.Vec3d(5.0, 0.0, 5.0), 1e-6)) self.assertTrue( Gf.IsClose(translateOp.Get(49), Gf.Vec3d(0.0, 5.0, 5.0), 1e-6)) self.assertTrue( Gf.IsClose(translateOp.Get(73), Gf.Vec3d(-5.0, 0.0, 5.0), 1e-6)) self.assertTrue( Gf.IsClose(rotateOp.Get(1), Gf.Vec3f(45.0, 0.0, 0.0), 1e-6)) self.assertTrue( Gf.IsClose(rotateOp.Get(25), Gf.Vec3f(45.0, 0.0, 90.0), 1e-6)) self.assertTrue( Gf.IsClose(rotateOp.Get(49), Gf.Vec3f(45.0, 0.0, 180.0), 1e-6)) self.assertTrue( Gf.IsClose(rotateOp.Get(73), Gf.Vec3f(45.0, 0.0, 270.0), 1e-6))