def __init__(self, usd_filepath: str, cache_dir: str = '../data/USDMeshes'): usd_filepath = Path(usd_filepath) assert usd_filepath.suffix in ['.usd', '.usda'] assert usd_filepath.exists( ), f'USD file at {usd_filepath} was not found.' self.cache = helpers.Cache(get_mesh_attributes, cache_dir, cache_key=helpers._get_hash(usd_filepath)) self.names = self.cache.cached_ids stage = Usd.Stage.Open(str(usd_filepath)) mesh_prims = [x for x in stage.Traverse() if UsdGeom.Mesh(x)] uncached_mesh_prims = filter(lambda x: x.GetName() not in self.names, mesh_prims) for mesh_prim in uncached_mesh_prims: name = mesh_prim.GetName() mesh = UsdGeom.Mesh(mesh_prim) face_counts = torch.tensor(mesh.GetFaceVertexCountsAttr().Get()) if not torch.allclose(face_counts, face_counts[0]): log.warn(f'Skipping mesh {name}, not all faces have the same ' 'number of vertices.') else: self.cache(name, usd_mesh=mesh)
def testSidedness(self): for sidedness in ('single', 'double', 'derived'): for doubleSided in (False, True): output = os.path.join( self.temp_dir, 'sidedness_{}_{}.usda'.format(sidedness, doubleSided)) cmds.file(new=True, force=True) xform, _ = cmds.polyCube() shape = cmds.listRelatives(xform)[0] cmds.setAttr("{}.doubleSided".format(shape), doubleSided) cmds.mayaUSDExport(file=output, selection=True, geomSidedness=sidedness) stage = Usd.Stage.Open(output) prim = stage.GetPrimAtPath("/pCube1") value = UsdGeom.Mesh(prim).GetDoubleSidedAttr().Get() if sidedness == 'derived': self.assertEqual(value, doubleSided, "Incorrect derived sidedness value") elif sidedness == 'single': self.assertFalse(value, "Incorrect single sidedness value") elif sidedness == 'double': self.assertTrue(value, "Incorrect double sidedness value")
def test_ComputeFaceCount(self): stage = Usd.Stage.Open('mesh.usda') unset = UsdGeom.Mesh.Get(stage, '/UnsetVertexCounts') blocked = UsdGeom.Mesh.Get(stage, '/BlockedVertexCounts') empty = UsdGeom.Mesh.Get(stage, '/EmptyVertexCounts') timeSampled = UsdGeom.Mesh.Get(stage, '/TimeSampledVertexCounts') timeSampledAndDefault = UsdGeom.Mesh.Get(stage, '/TimeSampledAndDefaultVertexCounts') testTimeSamples = [ (unset, Usd.TimeCode.EarliestTime(), 0), (blocked, Usd.TimeCode.EarliestTime(), 0), (empty, Usd.TimeCode.EarliestTime(), 0), (timeSampled, Usd.TimeCode.EarliestTime(), 3), (timeSampledAndDefault, Usd.TimeCode.EarliestTime(), 5)] testDefaults = [ (unset, 0), (blocked, 0), (empty, 0), (timeSampled, 0), (timeSampledAndDefault, 4)] for (schema, timeCode, expected) in testTimeSamples: self.assertTrue(schema) self.assertEqual(schema.GetFaceCount(timeCode), expected) for (schema, expected) in testDefaults: self.assertTrue(schema) self.assertEqual(schema.GetFaceCount(), expected) invalid = UsdGeom.Mesh(Usd.Prim()) self.assertFalse(invalid) with self.assertRaises(RuntimeError): self.assertEqual(invalid.GetFaceCount(), 0) with self.assertRaises(RuntimeError): self.assertEqual(invalid.GetFaceCount( Usd.TimeCode.EarliestTime()), 0)
def _addModel(model, prototypesPrimPath, stage): # the name must be a full path without the . so just strip .usd from name name = model[0:model.find('.')] primPath = prototypesPrimPath.AppendChild(name) treeRefPrim = stage.DefinePrim(primPath) refs = treeRefPrim.GetReferences() refs.AddReference(model) path = treeRefPrim.GetPath() leaves = '/World/TreePointInstance/prototypes/{}/Leaves'.format(name) tree = UsdGeom.Mesh(stage.GetPrimAtPath(leaves)) tree.CreateDisplayColorAttr([(0.0, 0.8, 0.0)]) material = UsdShade.Material.Define(stage, '/World/Leaf{}Material'.format(name)) pbrShader = UsdShade.Shader.Define( stage, '/World/Leaf{}Material/LeafShader'.format(name)) pbrShader.CreateIdAttr("UsdPreviewSurface") pbrShader.CreateInput("diffuseColor", Sdf.ValueTypeNames.Color3f).Set( (0.0, 0.8, 0.0)) pbrShader.CreateInput("roughness", Sdf.ValueTypeNames.Float).Set(0.2) pbrShader.CreateInput("metallic", Sdf.ValueTypeNames.Float).Set(0.1) material.CreateSurfaceOutput().ConnectToSource(pbrShader, "surface") UsdShade.MaterialBindingAPI(tree).Bind(material) trunk = '/World/TreePointInstance/prototypes/{}/Trunk'.format(name) tree = UsdGeom.Mesh(stage.GetPrimAtPath(trunk)) tree.CreateDisplayColorAttr([(0.5, 0.2, 0.0)]) material = UsdShade.Material.Define(stage, '/World/Trunk{}Material'.format(name)) pbrShader = UsdShade.Shader.Define( stage, '/World/Trunk{}Material/TrunkShader'.format(name)) pbrShader.CreateIdAttr("UsdPreviewSurface") pbrShader.CreateInput("diffuseColor", Sdf.ValueTypeNames.Color3f).Set( (0.5, 0.2, 0.0)) pbrShader.CreateInput("roughness", Sdf.ValueTypeNames.Float).Set(0.2) pbrShader.CreateInput("metallic", Sdf.ValueTypeNames.Float).Set(0.1) material.CreateSurfaceOutput().ConnectToSource(pbrShader, "surface") UsdShade.MaterialBindingAPI(tree).Bind(material) # return the actual path to the model which will be added to the instancer return path
def _GetCubeMesh(self, cubeName): cubePrimPath = '/UsdExportDisplayColorTest/Geom/CubeMeshes/%s' % cubeName cubePrim = self._stage.GetPrimAtPath(cubePrimPath) self.assertTrue(cubePrim) usdMesh = UsdGeom.Mesh(cubePrim) self.assertTrue(usdMesh) return usdMesh
def _ValidateMeshPrim(self, stage, meshPrimPath, expectedTranslation=None): meshPrim = stage.GetPrimAtPath(meshPrimPath) self.assertTrue(meshPrim) meshSchema = UsdGeom.Mesh(meshPrim) self.assertTrue(meshSchema) self._ValidateXformOps(meshPrim, expectedTranslation) return meshSchema
def doTest(self, namespacedInstancer, namespacedPrototype, stripNamespaces): cmds.file(self.mayaFile, open=True, force=True) group = 'group1' namespace = 'mayaNamespace' instancer = baseInstancer = 'instancer1' cubeTrans = baseCubeTrans = 'pCube1' cubeShape = baseCubeShape = 'pCubeShape1' # Note: the scene already has the namespace defined, so we don't # need to do that if namespacedInstancer: instancer = '{}:{}'.format(namespace, baseInstancer) cmds.rename(baseInstancer, instancer) self.assertFalse(cmds.objExists(baseInstancer)) self.assertTrue(cmds.objExists(instancer)) if namespacedPrototype: cubeTrans = '{}:{}'.format(namespace, baseCubeTrans) cubeShape = '{}:{}'.format(namespace, baseCubeShape) # renaming trans should also rename shape cmds.rename(baseCubeTrans, cubeTrans) self.assertFalse(cmds.objExists(baseCubeTrans)) self.assertFalse(cmds.objExists(baseCubeShape)) self.assertTrue(cmds.objExists(cubeTrans)) self.assertTrue(cmds.objExists(cubeShape)) stage = self.doExport(stripNamespaces=stripNamespaces) self.assertTrue(stage) if namespacedInstancer and not stripNamespaces: instancerPrimPath = '/{}/{}_{}'.format(group, namespace, baseInstancer) else: instancerPrimPath = '/{}/{}'.format(group, baseInstancer) instancerPrim = stage.GetPrimAtPath(instancerPrimPath) self.assertTrue(instancerPrim) instancer = UsdGeom.PointInstancer(instancerPrim) self.assertTrue(instancer) if namespacedPrototype and not stripNamespaces: protoPrimPath = '{}/Prototypes/{}_{}_0'.format( instancerPrimPath, namespace, baseCubeTrans) else: protoPrimPath = '{}/Prototypes/{}_0'.format( instancerPrimPath, baseCubeTrans) protoPrim = stage.GetPrimAtPath(protoPrimPath) self.assertTrue(protoPrim) protoMesh = UsdGeom.Mesh(protoPrim) self.assertTrue(protoMesh) prototypes = instancer.GetPrototypesRel().GetTargets() self.assertEqual(prototypes, [protoPrim.GetPath()])
def test_import_st_no_indices_uniform(self, out_dir, mesh): out_path = os.path.join(out_dir, 'st_no_indices_face_uniform.usda') uvs = torch.rand((mesh.faces.size(0), 2)) scene_path = '/World/mesh_0' usd.export_mesh(out_path, scene_path=scene_path, vertices=mesh.vertices, faces=mesh.faces, uvs=uvs) # check that interpolation was set correctly to 'uniform' stage = Usd.Stage.Open(out_path) pv = UsdGeom.Mesh(stage.GetPrimAtPath(scene_path)).GetPrimvar('st') assert pv.GetInterpolation() == 'uniform'
def testExportUvVersusUvIndexFromIterator(self): """ Tests that UVs export properly on a mesh where the UV returned by MItMeshFaceVertex::getUV is known to be different from that returned by MItMeshFaceVertex::getUVIndex and indexed into the UV array. (The latter should return the desired result from the outMesh and is the method currently used by usdMaya.) """ brokenBoxMesh = UsdGeom.Mesh(self._stage.GetPrimAtPath( "/UsdExportUVSetsTest/Geom/BrokenUVs/box")) stPrimvar = brokenBoxMesh.GetPrimvar("st").ComputeFlattened() self.assertEqual(stPrimvar[0], Gf.Vec2f(1.0, 1.0))
def test_import_st_no_indices_facevarying(self, out_dir, mesh): out_path = os.path.join(out_dir, 'st_no_indices_face_varying.usda') uvs = torch.rand((mesh.faces.size(0) * mesh.faces.size(1), 2)) scene_path = '/World/mesh_0' usd.export_mesh(out_path, scene_path=scene_path, vertices=mesh.vertices, faces=mesh.faces, uvs=uvs) # check that interpolation was set correctly to 'faceVarying' stage = Usd.Stage.Open(out_path) pv = UsdGeom.Mesh(stage.GetPrimAtPath(scene_path)).GetPrimvar('st') assert pv.GetInterpolation() == 'faceVarying' mesh_in = usd.import_mesh(out_path) assert torch.allclose(mesh_in.uvs, uvs)
def parse_encode_mesh(self, category, id, target_time, current_time=None): fpath = self.parser.get_file_path("mesh", category, id) if fpath is None: return None, 0 scene_path = self._pick_one_scene_path( fpath, kaolin.io.usd.get_scene_paths(fpath, prim_types=['Mesh']), "mesh") if scene_path is None: return None, 0 # TODO: modify io.usd API to be usable here instead once we add support for textures stage = Usd.Stage.Open(fpath) mesh_prim = stage.GetPrimAtPath(scene_path) mesh = UsdGeom.Mesh(mesh_prim) if mesh is None: return None, 0 # May only need to update vertices, not faces vertices = None triangles = None time_brackets_verts = mesh.GetPointsAttr().GetBracketingTimeSamples( target_time) time_brackets_faces = mesh.GetFaceVertexIndicesAttr( ).GetBracketingTimeSamples(target_time) snap_time_verts = StreamingGeometryHelper._find_snap_time( time_brackets_verts, target_time) snap_time_faces = StreamingGeometryHelper._find_snap_time( time_brackets_faces, target_time) if StreamingGeometryHelper._does_snap_time_require_update( snap_time_verts, current_time): snap_time = snap_time_verts vertices = np.array(mesh.GetPointsAttr().Get(time=snap_time_verts), dtype=np.float32) # TODO: support streaming update to only one of values # if StreamingGeometryHelper._does_snap_time_require_update(snap_time_faces, current_time): if vertices is not None: triangles = np.array( mesh.GetFaceVertexIndicesAttr().Get(time=snap_time_faces), dtype=np.int32) if triangles is None and vertices is None: return None, current_time return meshes_to_binary([vertices], [triangles]), snap_time
def test_import_st_indices_facevarying(self, out_dir, mesh): out_path = os.path.join(out_dir, 'st_indices.usda') uvs = torch.rand((100, 2)) scene_path = '/World/mesh_0' face_uvs_idx = (torch.rand(mesh.faces.shape[:2]) * 99).long() usd.export_mesh(out_path, scene_path=scene_path, vertices=mesh.vertices, faces=mesh.faces, uvs=uvs, face_uvs_idx=face_uvs_idx) # check that interpolation was set correctly to 'vertex' stage = Usd.Stage.Open(out_path) pv = UsdGeom.Mesh(stage.GetPrimAtPath(scene_path)).GetPrimvar('st') assert pv.GetInterpolation() == 'faceVarying' mesh_in = usd.import_mesh(out_path) assert torch.allclose(mesh_in.uvs, uvs) assert torch.equal(mesh_in.face_uvs_idx, face_uvs_idx)
def encodeStage(self, stage, dracoDir): """Encodes meshes in a given stage and writes them to a given directory.""" if not os.path.exists(dracoDir): os.makedirs(dracoDir) # Compress all meshes in the scene with Draco. if self.options.verbose: print('Meshes:') self.usedFileNames.clear() for prim in stage.TraverseAll(): mesh = UsdGeom.Mesh(prim) if mesh: # Create a unique file name for the compressed mesh. fileName = dracoDir + self.getFileName(mesh) + '.drc' # Compress mesh and write to file. self.encodeMesh(stage, mesh, fileName) if self.options.verbose: print(' saved ' + fileName)
def testPayloadExpansion(self): # Create a new stage. stage = Usd.Stage.CreateInMemory() # Define a un-typed prim, with side length metadatum value of 5. prim = stage.DefinePrim("/triangle") prim.SetMetadata("Usd_Triangle_SideLength", 5) # Set payload path to ../scenes/empty.triangle. payloadPath = os.path.join(os.path.dirname(__file__), "..", "scenes", "empty.triangle") prim.SetPayload(Sdf.Payload(payloadPath)) # Should be expanded into a mesh! mesh = UsdGeom.Mesh(prim) self.assertTrue(mesh) # Validate mesh attribute values. self.assertEqual(mesh.GetFaceVertexCountsAttr().Get(), Vt.IntArray((3, ))) self.assertEqual(mesh.GetFaceVertexIndicesAttr().Get(), Vt.IntArray(( 0, 1, 2, ))) actualPoints = mesh.GetPointsAttr().Get() expectedPoints = Vt.Vec3fArray(( Gf.Vec3f(0.0, 2.88675, 0.0), Gf.Vec3f(-2.5, -1.44337, 0.0), Gf.Vec3f(2.5, -1.44337, 0.0), )) self.assertEqual(len(actualPoints), len(expectedPoints)) for actualPoint, expectedPoint in zip(actualPoints, expectedPoints): self.assertTrue(Gf.IsClose(actualPoint, expectedPoint, 1e-5))
def _addModel(model, prototypesPrimPath, stage): # the name must be a full path without the . so just strip .usd from name name = model[0:model.find('.')] primPath = prototypesPrimPath.AppendChild(name) treeRefPrim = stage.DefinePrim(primPath) refs = treeRefPrim.GetReferences() refs.AddReference(model) path = treeRefPrim.GetPath() leaves = '/World/TreePointInstance/prototypes/{}/Leaves'.format(name) tree = UsdGeom.Mesh(stage.GetPrimAtPath(leaves)) tree.CreateDisplayColorAttr([(0.0, 0.8, 0.0)]) materialRoot = '/World/Leaf{}Material'.format(name) material = UsdShade.Material.Define(stage, materialRoot) pbrShader = UsdShade.Shader.Define(stage, materialRoot + '/LeafShader') pbrShader.CreateIdAttr("UsdPreviewSurface") pbrShader.CreateInput("roughness", Sdf.ValueTypeNames.Float).Set(0.2) pbrShader.CreateInput("metallic", Sdf.ValueTypeNames.Float).Set(0.1) #material.CreateSurfaceOutput().ConnectToSource(pbrShader, "surface") stReader = UsdShade.Shader.Define(stage, materialRoot + '/stReader') stReader.CreateIdAttr('UsdPrimvarReader_float2') # add texture diffuseTextureSampler = UsdShade.Shader.Define( stage, materialRoot + '/diffuseTexture') diffuseTextureSampler.CreateIdAttr('UsdUVTexture') diffuseTextureSampler.CreateInput( 'file', Sdf.ValueTypeNames.Asset).Set(name + 'Leaves.png') #diffuseTextureSampler.CreateInput("st", Sdf.ValueTypeNames.Float2).ConnectToSource(stReader, 'result') diffuseTextureSampler.CreateOutput('rgb', Sdf.ValueTypeNames.Float3) diffuseTextureSampler.CreateOutput('a', Sdf.ValueTypeNames.Float) #pbrShader.CreateInput("diffuseColor", Sdf.ValueTypeNames.Color3f).ConnectToSource(diffuseTextureSampler, 'rgb') #pbrShader.CreateInput("opacityThreshold", Sdf.ValueTypeNames.Float).ConnectToSource(diffuseTextureSampler, 'a') stInput = material.CreateInput('frame:stPrimvarName', Sdf.ValueTypeNames.Token) stInput.Set('st') #stReader.CreateInput('varname',Sdf.ValueTypeNames.Token).ConnectToSource(stInput) UsdShade.MaterialBindingAPI(tree).Bind(material) trunk = '/World/TreePointInstance/prototypes/{}/Trunk'.format(name) tree = UsdGeom.Mesh(stage.GetPrimAtPath(trunk)) tree.CreateDisplayColorAttr([(0.5, 0.2, 0.0)]) materialRoot = '/World/Trunk{}Material'.format(name) material = UsdShade.Material.Define(stage, materialRoot) pbrShader = UsdShade.Shader.Define(stage, materialRoot + 'TrunkShader') pbrShader.CreateIdAttr("UsdPreviewSurface") pbrShader.CreateInput("diffuseColor", Sdf.ValueTypeNames.Color3f).Set( (0.5, 0.2, 0.0)) pbrShader.CreateInput("roughness", Sdf.ValueTypeNames.Float).Set(0.2) pbrShader.CreateInput("metallic", Sdf.ValueTypeNames.Float).Set(0.1) #material.CreateSurfaceOutput().ConnectToSource(pbrShader, "surface") # add texture diffuseTextureSampler = UsdShade.Shader.Define( stage, materialRoot + '/diffuseTexture') diffuseTextureSampler.CreateIdAttr('UsdUVTexture') diffuseTextureSampler.CreateInput( 'file', Sdf.ValueTypeNames.Asset).Set(name + 'Trunk.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') stInput = material.CreateInput('frame:stPrimvarName', Sdf.ValueTypeNames.Token) stInput.Set('st') stReader.CreateInput('varname', Sdf.ValueTypeNames.Token).ConnectToSource(stInput) UsdShade.MaterialBindingAPI(tree).Bind(material) # return the actual path to the model which will be added to the instancer return path
def testExportDisplayColorShading(self): """ Tests that exporting a Maya mesh with a simple Maya shading setup results in the correct shading on the USD mesh. """ # Validate the displayColor on the mesh prim. cubePrim = self._stage.GetPrimAtPath('/RedCube/Geom/Cube') self.assertTrue(cubePrim) cubeMesh = UsdGeom.Mesh(cubePrim) self.assertTrue(cubeMesh) meshDisplayColors = cubeMesh.GetDisplayColorPrimvar().Get() self.assertEqual(len(meshDisplayColors), 1) self.assertTrue(Gf.IsClose(meshDisplayColors[0], self.RED_COLOR, 1e-6)) # Validate the Material prim bound to the Mesh prim. material = UsdShade.Material.GetBoundMaterial(cubePrim) self.assertTrue(material) materialPath = material.GetPath().pathString self.assertEqual(materialPath, '/RedCube/Looks/RedLambertSG') materialInputs = material.GetInputs() self.assertEqual(len(materialInputs), 3) materialInput = material.GetInput('displayColor') matDisplayColor = materialInput.Get() self.assertTrue(Gf.IsClose(matDisplayColor, self.RED_COLOR, 1e-6)) # Just verify that displayOpacity and transparency exist. materialInput = material.GetInput('displayOpacity') self.assertTrue(materialInput) materialInput = material.GetInput('transparency') self.assertTrue(materialInput) # Validate the surface shader that is connected to the material. materialOutputs = material.GetOutputs() self.assertEqual(len(materialOutputs), 4) print(self._stage.ExportToString()) materialOutput = material.GetOutput('ri:surface') (connectableAPI, outputName, outputType) = materialOutput.GetConnectedSource() self.assertEqual(outputName, 'out') shader = UsdShade.Shader(connectableAPI) self.assertTrue(shader) self.assertEqual(shader.GetPrim().GetName(), 'RedLambertSG_lambert') shaderId = shader.GetIdAttr().Get() self.assertEqual(shaderId, 'PxrDiffuse') shaderInputs = shader.GetInputs() self.assertEqual(len(shaderInputs), 2) diffuseInput = shader.GetInput('diffuseColor') self.assertTrue(diffuseInput) (connectableAPI, outputName, outputType) = diffuseInput.GetConnectedSource() self.assertEqual(outputName, 'displayColor') self.assertTrue(connectableAPI) self.assertEqual(connectableAPI.GetPath().pathString, materialPath) transmissionInput = shader.GetInput('transmissionColor') self.assertTrue(transmissionInput) (connectableAPI, outputName, outputType) = transmissionInput.GetConnectedSource() self.assertEqual(outputName, 'transparency') self.assertTrue(connectableAPI) self.assertEqual(connectableAPI.GetPath().pathString, materialPath)
train_iters = 200 train_rate = 0.01 # 1.0/(sim_dt*sim_dt) phase_count = 8 phase_step = math.pi / phase_count * 2.0 phase_freq = 2.5 r = df.quat_multiply( df.quat_from_axis_angle((0.0, 0.0, 1.0), math.pi * 0.0), df.quat_from_axis_angle((1.0, 0.0, 0.0), -math.pi * 0.5), ) builder = df.sim.ModelBuilder() mesh = Usd.Stage.Open("cache/usdassets/jellyfish.usda") geom = UsdGeom.Mesh(mesh.GetPrimAtPath("/Icosphere/Icosphere")) points = geom.GetPointsAttr().Get() indices = geom.GetFaceVertexIndicesAttr().Get() counts = geom.GetFaceVertexCountsAttr().Get() face_materials = [-1] * len(counts) face_subsets = UsdGeom.Subset.GetAllGeomSubsets(geom) for i, s in enumerate(face_subsets): face_subset_indices = s.GetIndicesAttr().Get() for f in face_subset_indices: face_materials[f] = i active_material = 0
sim_time = 0.0 # sim_duration = 5.0 # seconds # sim_substeps = 32 # sim_dt = (1.0 / 60.0) / sim_substeps # sim_steps = int(sim_duration / sim_dt) # sim_time = 0.0 train_rate = 0.001 # 0.0001 phase_count = 4 builder = df.sim.ModelBuilder() walker = Usd.Stage.Open(args.mesh) mesh = UsdGeom.Mesh(walker.GetPrimAtPath("/Grid/Grid")) points = mesh.GetPointsAttr().Get() indices = mesh.GetFaceVertexIndicesAttr().Get() for p in points: builder.add_particle(tuple(p), (0.0, 0.0, 0.0), 1.0) for t in range(0, len(indices), 3): i = indices[t + 0] j = indices[t + 1] k = indices[t + 2] builder.add_triangle(i, j, k) model = builder.finalize("cpu")
def test_Basic(self): l = Sdf.Layer.CreateAnonymous() stage = Usd.Stage.Open(l.identifier) p = stage.DefinePrim("/Mesh", "Mesh") self.assertTrue(p) mesh = UsdGeom.Mesh(p) self.assertTrue(mesh) self.assertTrue(mesh.GetPrim()) self.assertTrue(not mesh.GetPointsAttr().Get(1)) self.assertEqual(p.GetTypeName(), mesh.GetSchemaClassPrimDefinition().typeName) # # Make sure uniform access behaves as expected. # ori = p.GetAttribute("orientation") # The generic orientation attribute should be automatically defined because # it is a registered attribute of a well known schema. However, it's not # yet authored at the current edit target. self.assertTrue(ori.IsDefined()) self.assertTrue(not ori.IsAuthoredAt(ori.GetStage().GetEditTarget())) # Author a value, and check that it's still defined, and now is in fact # authored at the current edit target. ori.Set(UsdGeom.Tokens.leftHanded) self.assertTrue(ori.IsDefined()) self.assertTrue(ori.IsAuthoredAt(ori.GetStage().GetEditTarget())) mesh.GetOrientationAttr().Set(UsdGeom.Tokens.rightHanded, 10) # "leftHanded" should have been authored at Usd.TimeCode.Default, so reading the # attribute at Default should return lh, not rh. self.assertEqual(ori.Get(), UsdGeom.Tokens.leftHanded) # The value "rightHanded" was set at t=10, so reading *any* time should # return "rightHanded" self.assertEqual(ori.Get(9.9), UsdGeom.Tokens.rightHanded) self.assertEqual(ori.Get(10), UsdGeom.Tokens.rightHanded) self.assertEqual(ori.Get(10.1), UsdGeom.Tokens.rightHanded) self.assertEqual(ori.Get(11), UsdGeom.Tokens.rightHanded) # # Attribute name sanity check. We expect the names returned by the schema # to match the names returned via the generic API. # self.assertTrue(len(mesh.GetSchemaAttributeNames()) > 0) self.assertNotEqual(mesh.GetSchemaAttributeNames(True), mesh.GetSchemaAttributeNames(False)) for n in mesh.GetSchemaAttributeNames(): # apiName overrides if n == "primvars:displayColor": n = "displayColor" elif n == "primvars:displayOpacity": n = "displayOpacity" name = n[0].upper() + n[1:] self.assertTrue( ("Get" + name + "Attr") in dir(mesh), ("Get" + name + "Attr() not found in: " + str(dir(mesh))))
def test_Fallbacks(self): # Author Scene and Compose Stage stage = Usd.Stage.CreateInMemory() # Xformable Tests identity = Gf.Matrix4d(1) origin = Gf.Vec3f(0, 0, 0) xform = UsdGeom.Xform.Define(stage, "/Xform") # direct subclass xformOpOrder = xform.GetXformOpOrderAttr() self.assertFalse(xformOpOrder.HasAuthoredValueOpinion()) # xformOpOrder has no fallback value self.assertEqual(xformOpOrder.Get(), None) self.assertFalse(xformOpOrder.HasFallbackValue()) # Try authoring and reverting... xformOpOrderAttr = xform.GetPrim().GetAttribute( UsdGeom.Tokens.xformOpOrder) self.assertTrue(xformOpOrderAttr) self.assertEqual(xformOpOrderAttr.Get(), None) opOrderVal = ["xformOp:transform"] self.assertTrue(xformOpOrderAttr.Set(opOrderVal)) self.assertTrue(xformOpOrderAttr.HasAuthoredValueOpinion()) self.assertNotEqual(xformOpOrderAttr.Get(), None) self.assertTrue(xformOpOrderAttr.Clear()) self.assertFalse(xformOpOrderAttr.HasAuthoredValueOpinion()) self.assertEqual(xformOpOrderAttr.Get(), None) self.assertFalse(xformOpOrder.HasFallbackValue()) mesh = UsdGeom.Mesh.Define(stage, "/Mesh") # multiple ancestor hops # PointBased and Curves curves = UsdGeom.BasisCurves.Define(stage, "/Curves") self.assertEqual(curves.GetNormalsInterpolation(), UsdGeom.Tokens.varying) self.assertEqual(curves.GetWidthsInterpolation(), UsdGeom.Tokens.varying) # Before we go, test that CreateXXXAttr performs as we expect in various # scenarios # Number 1: Sparse and non-sparse authoring on def'd prim mesh.CreateDoubleSidedAttr(False, True) self.assertFalse(mesh.GetDoubleSidedAttr().HasAuthoredValueOpinion()) mesh.CreateDoubleSidedAttr(False, False) self.assertTrue(mesh.GetDoubleSidedAttr().HasAuthoredValueOpinion()) # Number 2: Sparse authoring demotes to dense for non-defed prim overMesh = UsdGeom.Mesh(stage.OverridePrim('/overMesh')) overMesh.CreateDoubleSidedAttr(False, True) self.assertTrue( overMesh.GetDoubleSidedAttr().HasAuthoredValueOpinion()) self.assertEqual(overMesh.GetDoubleSidedAttr().Get(), False) overMesh.CreateDoubleSidedAttr(True, True) self.assertEqual(overMesh.GetDoubleSidedAttr().Get(), True) # make it a defined mesh, and sanity check it still evals the same mesh2 = UsdGeom.Mesh.Define(stage, "/overMesh") self.assertEqual(overMesh.GetDoubleSidedAttr().Get(), True) # Check querying of fallback values. sphere = UsdGeom.Sphere.Define(stage, "/Sphere") radius = sphere.GetRadiusAttr() self.assertTrue(radius.HasFallbackValue()) radiusQuery = Usd.AttributeQuery(radius) self.assertTrue(radiusQuery.HasFallbackValue())
def _get_flattened_mesh_attributes(stage, scene_path, time): """Return mesh attributes flattened into a single mesh.""" prim = stage.GetPrimAtPath(scene_path) if not prim: raise ValueError(f'No prim found at "{scene_path}".') mesh_prims = [x for x in Usd.PrimRange(prim).AllPrims(prim) if UsdGeom.Mesh(x)] cur_first_idx_faces = 0 cur_first_idx_uvs = 0 vertices, vertex_indices, face_vertex_counts, uvs, face_uvs_idx, face_normals, materials = [], [], [], [], [], [], [] for mesh_prim in mesh_prims: mesh = UsdGeom.Mesh(mesh_prim) mesh_vertices = mesh.GetPointsAttr().Get(time=time) mesh_vertex_indices = mesh.GetFaceVertexIndicesAttr().Get(time=time) mesh_st = mesh.GetPrimvar('st') if mesh_st: mesh_uvs = mesh_st.Get(time=time) mesh_uv_indices = mesh_st.GetIndices(time=time) mesh_uv_interpolation = mesh_st.GetInterpolation() mesh_face_normals = mesh.GetNormalsAttr().Get(time=time) if mesh_vertices: vertices.append(torch.tensor(mesh_vertices)) if mesh_vertex_indices: face_vertex_counts.append(torch.tensor(mesh.GetFaceVertexCountsAttr().Get(time=time))) vertex_indices.append(torch.tensor(mesh_vertex_indices) + cur_first_idx_faces) if vertices: cur_first_idx_faces += len(vertices[-1]) if mesh_face_normals: face_normals.append(torch.tensor(mesh_face_normals)) if mesh_st and mesh_uvs: uvs.append(torch.tensor(mesh_uvs)) if mesh_uv_interpolation in ['vertex', 'varying']: if not mesh_uv_indices: # for vertex and varying interpolation, length of mesh_uv_indices should match # length of mesh_vertex_indices mesh_uv_indices = list(range(len(mesh_uvs))) mesh_uv_indices = torch.tensor(mesh_uv_indices) + cur_first_idx_uvs face_uvs_idx.append(mesh_uv_indices[torch.tensor(mesh_vertex_indices)]) elif mesh_uv_interpolation == 'faceVarying': if not mesh_uv_indices: # for faceVarying interpolation, length of mesh_uv_indices should match # num_faces * face_size mesh_uv_indices = list(range(len(mesh_uvs))) face_uvs_idx.append(torch.tensor(mesh_uv_indices) + cur_first_idx_uvs) else: raise NotImplementedError(f'Interpolation type {mesh_uv_interpolation} is ' 'not currently supported') cur_first_idx_uvs += len(mesh_uvs) if not vertices: warnings.warn(f'Scene object at {scene_path} contains no vertices.', UserWarning) # Only import vertices if they are defined for the entire mesh if all([v is not None for v in vertices]) and len(vertices) > 0: vertices = torch.cat(vertices) else: vertices = None # Only import vertex index and counts if they are defined for the entire mesh if all([vi is not None for vi in vertex_indices]) and len(vertex_indices) > 0: face_vertex_counts = torch.cat(face_vertex_counts) vertex_indices = torch.cat(vertex_indices) else: face_vertex_counts = None vertex_indices = None # Only import UVs if they are defined for the entire mesh if not all([uv is not None for uv in uvs]) or len(uvs) == 0: if len(uvs) > 0: warnings.warn('UVs are missing for some child meshes for prim at ' f'{scene_path}. As a result, no UVs were imported.') uvs = None face_uvs_idx = None else: uvs = torch.cat(uvs) face_uvs_idx = torch.cat(face_uvs_idx) # Only import face_normals if they are defined for the entire mesh if not all([n is not None for n in face_normals]) or len(face_normals) == 0: if len(face_normals) > 0: warnings.warn('Face normals are missing for some child meshes for ' f'prim at {scene_path}. As a result, no Face Normals were imported.') face_normals = None else: face_normals = torch.cat(face_normals) return vertices, face_vertex_counts, vertex_indices, uvs, face_uvs_idx, face_normals, materials
json.dump(args.__dict__, f, indent=2) sim_dt = (1.0 / args.physics_engine_rate) / args.sim_substeps sim_steps = int(args.sim_duration / sim_dt) sim_time = 0.0 phase_count = 8 phase_step = math.pi / phase_count * 2.0 phase_freq = 2.5 builder = df.sim.ModelBuilder() if args.mesh[-4:] == "usda": mesh = Usd.Stage.Open(args.mesh) geom = UsdGeom.Mesh(mesh.GetPrimAtPath("/mesh")) points = geom.GetPointsAttr().Get() tet_indices = geom.GetPrim().GetAttribute("tetraIndices").Get() # tri_indices = geom.GetFaceVertexIndicesAttr().Get() # tri_counts = geom.GetFaceVertexCountsAttr().Get() elif args.mesh[-3:] == "tet": points, tet_indices = read_tet_mesh(args.mesh) r = df.quat_multiply( df.quat_from_axis_angle((0.0, 0.0, 1.0), math.pi * 0.0), df.quat_from_axis_angle((1.0, 0.0, 0.0), math.pi * 0.0), ) builder.add_soft_mesh( pos=(-4.0, 2.0, 0.0),
def testExportDisplayColorShading(self): """ Tests that exporting a Maya mesh with a simple Maya shading setup results in the correct shading on the USD mesh. """ # Validate the displayColor on the mesh prim. cubePrim = self._stage.GetPrimAtPath('/RedCube/Geom/Cube') self.assertTrue(cubePrim) cubeMesh = UsdGeom.Mesh(cubePrim) self.assertTrue(cubeMesh) meshDisplayColors = cubeMesh.GetDisplayColorPrimvar().Get() self.assertEqual(len(meshDisplayColors), 1) self.assertTrue(Gf.IsClose(meshDisplayColors[0], self.RED_COLOR, 1e-6)) # Validate the Material prim bound to the Mesh prim. material = UsdShade.Material.GetBoundMaterial(cubePrim) self.assertTrue(material) materialPath = material.GetPath().pathString self.assertEqual(materialPath, '/RedCube/Looks/RedLambertSG') materialInputs = material.GetInputs() self.assertEqual(len(materialInputs), 3) materialInput = material.GetInput('displayColor') matDisplayColor = materialInput.Get() self.assertTrue(Gf.IsClose(matDisplayColor, self.RED_COLOR, 1e-6)) # Just verify that displayOpacity and transparency exist. materialInput = material.GetInput('displayOpacity') self.assertTrue(materialInput) materialInput = material.GetInput('transparency') self.assertTrue(materialInput) # Validate the surface shader that is connected to the material. # XXX: Note that the expected number of outputs here is two rather than # one, since we are still authoring the UsdRi Bxdf source in addition # to the surface terminal for backwards compatibility. When consumers # are updated to use the surface terminal instead, this test will have # to be updated. materialOutputs = material.GetOutputs() self.assertEqual(len(materialOutputs), 2) materialOutput = material.GetOutput('surface') (connectableAPI, outputName, outputType) = materialOutput.GetConnectedSource() self.assertEqual(outputName, 'out') shader = UsdShade.Shader(connectableAPI) self.assertTrue(shader) self.assertEqual(shader.GetPrim().GetName(), 'RedLambertSG_lambert') # XXX: Validate the UsdRi Bxdf. This must also be removed when we no # longer author it. from pxr import UsdRi usdRiMaterialAPI = UsdRi.MaterialAPI(material.GetPrim()) self.assertTrue(usdRiMaterialAPI) bxdf = usdRiMaterialAPI.GetBxdf() self.assertEqual(bxdf.GetPrim(), shader.GetPrim()) shaderId = shader.GetIdAttr().Get() self.assertEqual(shaderId, 'PxrDiffuse') shaderInputs = shader.GetInputs() self.assertEqual(len(shaderInputs), 2) diffuseInput = shader.GetInput('diffuseColor') self.assertTrue(diffuseInput) (connectableAPI, outputName, outputType) = diffuseInput.GetConnectedSource() self.assertEqual(outputName, 'displayColor') self.assertTrue(connectableAPI) self.assertEqual(connectableAPI.GetPath().pathString, materialPath) transmissionInput = shader.GetInput('transmissionColor') self.assertTrue(transmissionInput) (connectableAPI, outputName, outputType) = transmissionInput.GetConnectedSource() self.assertEqual(outputName, 'transparency') self.assertTrue(connectableAPI) self.assertEqual(connectableAPI.GetPath().pathString, materialPath)