def test_OnePointNoVelocities(self): stage = Usd.Stage.Open("test.usda") pb = UsdGeom.PointBased(stage.GetPrimAtPath("/OnePointNoVelocities")) # Test directly on sample. baseTime = 0 tr = timeRange(baseTime) pointsArray = self.computePoints(pb, tr, baseTime) compares = [] for time, delta in tr: if time < 0: # Samples at times less than 0 should clamp to first sample. compare = [Gf.Vec3f(0, 0, 0)] else: compare = [Gf.Vec3f(time * 5, time * 10, time * 20)] compares.append(compare) self.assertAllVectorListsEqual(pointsArray, compares) # Test in-between samples. baseTime = 2 tr = timeRange(baseTime) pointsArray = self.computePoints(pb, tr, baseTime) compares = [[Gf.Vec3f(time * 5, time * 10, time * 20)] for time, delta in tr] self.assertAllVectorListsEqual(pointsArray, compares) # Test with basetime before and after natural sample. Since we are # interpolating, these should always be the same. baseTime = 5 tr = timeRange(baseTime) pointsArrayBefore = self.computePoints(pb, tr, baseTime - 1) pointsArrayAfter = self.computePoints(pb, tr, baseTime) self.assertAllVectorListsEqual(pointsArrayBefore, pointsArrayAfter)
def test_OnePointNoSamples(self): stage = Usd.Stage.Open("test.usda") pb = UsdGeom.PointBased(stage.GetPrimAtPath("/OnePointNoSamples")) baseTime = 1 tr = timeRange(baseTime) pointsArray = self.computePoints(pb, tr, baseTime) compares = [[Gf.Vec3f(0, 0, 0)] for time, delta in tr] self.assertAllVectorListsEqual(pointsArray, compares)
def test_NoPoints(self): stage = Usd.Stage.Open("test.usda") pb = UsdGeom.PointBased(stage.GetPrimAtPath("/NoPoints")) for baseTime, _ in timeRange(0): tr = timeRange(baseTime) pointsArray = self.computePoints(pb, tr, baseTime) for points in pointsArray: self.assertEqual(len(points), 0)
def test_MultiPoints(self): stage = Usd.Stage.Open("test.usda") pb = UsdGeom.PointBased(stage.GetPrimAtPath("/MultiPoints")) # Test with 3 points. baseTime = 0 tr = timeRange(baseTime) pointsArray = self.computePoints(pb, tr, baseTime) compares = [[ Gf.Vec3f(time * 5, time * 10, time * 20), Gf.Vec3f(time * 5, time * 10, 1 + time * 20), Gf.Vec3f(time * 5, time * 10, 2 + time * 20) ] for time, delta in tr] self.assertAllMatrixListsEqual(pointsArray, compares)
def test_OnePointAcceleration(self): stage = Usd.Stage.Open("test.usda") pb = UsdGeom.PointBased(stage.GetPrimAtPath("/OnePointAcceleration")) # Test directly on sample. baseTime = 0 tr = timeRange(baseTime) pointsArray = self.computePoints(pb, tr, baseTime) compares = [[ Gf.Vec3f((time / 24.0) * (120 + (time * 1 * 0.5)), (time / 24.0) * (120 + (time * 1 * 0.5)), (time / 24.0) * (120 + (time * 1 * 0.5))) ] for time, delta in tr] self.assertAllVectorListsEqual(pointsArray, compares) # Test in-between samples. baseTime = 2 tr = timeRange(baseTime) pointsArray = self.computePoints(pb, tr, baseTime) compares = [[ Gf.Vec3f((time / 24.0) * (120 + (time * 1 * 0.5)), (time / 24.0) * (120 + (time * 1 * 0.5)), (time / 24.0) * (120 + (time * 1 * 0.5))) ] for time, delta in tr] self.assertAllVectorListsEqual(pointsArray, compares) # Test with basetime before natural sample. baseTime = 5 tr = timeRange(baseTime) pointsArray = self.computePoints(pb, tr, baseTime - 1) compares = [[ Gf.Vec3f((time / 24.0) * (120 + (time * 1 * 0.5)), (time / 24.0) * (120 + (time * 1 * 0.5)), (time / 24.0) * (120 + (time * 1 * 0.5))) ] for time, delta in tr] self.assertAllVectorListsEqual(pointsArray, compares) # Test with basetime on natural sample. baseTime = 5 tr = timeRange(baseTime) pointsArray = self.computePoints(pb, tr, baseTime) compares = [[ Gf.Vec3f(25 + (delta / 24.0) * (120 + (delta * 1 * 0.5)), 50 + (delta / 24.0) * (240 + (delta * 2 * 0.5)), 100 + (delta / 24.0) * (480 + (delta * 3 * 0.5))) ] for time, delta in tr] self.assertAllVectorListsEqual(pointsArray, compares)
def generate_chart_model(stage, index, stock_name, prices, percentage_change): stage = generate_ticker_cube(index, stage, stock_name) for i in range(0, len(prices)): mesh = UsdGeom.Mesh.Define(stage, '/cube' + str(i) + stock_name) mesh.CreateSubdivisionSchemeAttr().Set(UsdGeom.Tokens.none) mesh.CreatePointsAttr([(-5, -5, 5), (5, -5, 5), (-5, prices[i], 5), (5, prices[i], 5), (-5, prices[i], -5), (5, prices[i], -5), (-5, -5, -5), (5, -5, -5)]) mesh.CreateExtentAttr( UsdGeom.PointBased(mesh).ComputeExtent(mesh.GetPointsAttr().Get())) mesh.CreateNormalsAttr([(0, 0, 1), (0, 1, 0), (0, 0, -1), (0, -1, 0), (1, 0, 0), (-1, 0, 0)]) mesh.SetNormalsInterpolation(UsdGeom.Tokens.uniform) mesh.CreateFaceVertexCountsAttr([4, 4, 4, 4, 4, 4]) mesh.CreateFaceVertexIndicesAttr([ 0, 1, 3, 2, 2, 3, 5, 4, 4, 5, 7, 6, 6, 7, 1, 0, 1, 7, 5, 3, 6, 0, 2, 4 ]) material = UsdShade.Material.Define( stage, '/cubeMaterial' + str(i) + stock_name) pbrShader = UsdShade.Shader.Define( stage, '/cubeMaterial' + str(i) + stock_name + '/PBRShader') pbrShader.CreateIdAttr('UsdPreviewSurface') if percentage_change[i] >= 0: pbrShader.CreateInput('diffuseColor', Sdf.ValueTypeNames.Color3f).Set( Gf.Vec3f(0, 1, 0)) else: pbrShader.CreateInput('diffuseColor', Sdf.ValueTypeNames.Color3f).Set( Gf.Vec3f(1, 0, 0)) pbrShader.CreateInput('metallic', Sdf.ValueTypeNames.Float).Set(0.9) pbrShader.CreateInput('roughness', Sdf.ValueTypeNames.Float).Set(0.2) material.CreateSurfaceOutput().ConnectToSource(pbrShader, 'surface') UsdShade.MaterialBindingAPI(mesh.GetPrim()).Bind(material) UsdGeom.XformCommonAPI(mesh).SetTranslate( (10 * i, 20 * index, -index * 20)) generate_price_cube(prices[i], stock_name, stage, i, index)
def test_OnePoint(self): stage = Usd.Stage.Open("test.usda") pb = UsdGeom.PointBased(stage.GetPrimAtPath("/OnePoint")) # Test directly on sample. baseTime = 0 tr = timeRange(baseTime) pointsArray = self.computePoints(pb, tr, baseTime) compares = [[Gf.Vec3f(time * 5, time * 10, time * 20)] for time, delta in tr] self.assertAllVectorListsEqual(pointsArray, compares) # Test in-between samples. baseTime = 2 tr = timeRange(baseTime) pointsArray = self.computePoints(pb, tr, baseTime) compares = [[Gf.Vec3f(time * 5, time * 10, time * 20)] for time, delta in tr] self.assertAllVectorListsEqual(pointsArray, compares) # Test with basetime before natural sample. baseTime = 5 tr = timeRange(baseTime) pointsArray = self.computePoints(pb, tr, baseTime - 1) compares = [[Gf.Vec3f(time * 5, time * 10, time * 20)] for time, delta in tr] self.assertAllVectorListsEqual(pointsArray, compares) # Test with basetime on natural sample. baseTime = 5 tr = timeRange(baseTime) pointsArray = self.computePoints(pb, tr, baseTime) compares = [[ Gf.Vec3f(25 - delta * 5, 50 - delta * 10, 100 - delta * 20) ] for time, delta in tr] self.assertAllVectorListsEqual(pointsArray, compares)
def test_PointBased(self): stage = Usd.Stage.Open("testPointBased.usda") pointBased = UsdGeom.PointBased(stage.GetPrimAtPath("/Points")) # Verify the extent computation when no transform matrix is given. self.verifyExtent(pointBased, [(0, 0, 0), (3.0, 2.0, 2.0)]) # Verify the extent computation when no transform matrix is given. self.verifyExtent(pointBased, [(0, 0, 0), (3.0, 2.0, 2.0)], Gf.Matrix4d(1.0)) # Apply an arbitrary transform matrix. Note that this is different from # the extent displayed in Usdview. If you open testPoints.usda and # select /StrangePoints, you will see the box is larger than it needs to # be (it transforms the bounding box around the points, not the points # themselves like ComputeExtentFromPlugins). If you select # /StrangePointsComputedExtent, it will display the (much tighter) # computed extent used below. self.verifyExtent( pointBased, [(0.3787655532360077, 2.0, 1.5), (4.4259724617004395, 3.609475612640381, 2.0058794021606445)], STRANGE_TRANSFORM)
def usd_mesh_from_json(data): positions = [tuple(p) for p in data["positions"]] normals = [tuple(n) for n in data["normals"]] creases = flatten([[int(idx) for idx in c] for c in data["creases"]]) crease_sharpnesess = [d * 10 for d in data["creaseSharpnesess"]] crease_lengths = [len(c) for c in data["creases"]] polygons = data["polygons"] face_vertex_counts = [len(v) for v in polygons] face_vertex_indices = [ vertex_id for polygon in polygons for vertex_id in polygon] # create mesh name = usd_escape_path_component(data["name"]) mesh = UsdGeom.Mesh.Define(stage, '/' + name) # Encode material. Todo: submeshes, etc. material_name = usd_escape_path_component(data["material"]) if material_name: # This might not be the supported way to do this mesh.GetPrim().CreateRelationship("material:binding", custom=False).AddTarget('/Materials/' + material_name) # Encode transformation usd_xform_from_json(data, mesh) mesh.CreatePointsAttr(positions) # TODO: we should export the BB after subdivision, right? # set (static) bounding box for framing and frustum culling mesh.CreateExtentAttr(UsdGeom.PointBased( mesh).ComputeExtent(mesh.GetPointsAttr().Get())) mesh.CreateNormalsAttr(normals) # mesh.SetNormalsInterpolation(UsdGeom.Tokens.faceVarying) # normals are stored per-face # This currently only supports one texture coordinate, "st" if data["textureCoordinates"]: # dict of str -> array of TCs in [U,V] pairs ie [[u0, v0], [u1, v1], ...] # interpolation ref https://graphics.pixar.com/usd/docs/api/class_usd_geom_primvar.html#Usd_InterpolationVals for primvarKey, coords in data["textureCoordinates"].iteritems(): # Just in case we passed in a key that has a weird name, don't use it raw primvarKey = usd_escape_path_component(primvarKey) texCoords = mesh.CreatePrimvar(primvarKey, Sdf.ValueTypeNames.TexCoord2fArray, UsdGeom.Tokens.faceVarying) # face_data = [[tuple(uv) for uv in polygon] for polygon in coords] # Mush all of the TCs together. wat. import itertools face_data = [tuple(uv) for uv in itertools.chain.from_iterable(coords)] print("face data is: ", face_data) texCoords.Set(face_data) if data["hasSubdivision"]: # Technically redundant, since this is the default mesh.CreateSubdivisionSchemeAttr().Set(UsdGeom.Tokens.catmullClark) mesh.CreateCreaseIndicesAttr(creases, True) mesh.CreateCreaseLengthsAttr(crease_lengths, True) mesh.CreateCreaseSharpnessesAttr(crease_sharpnesess, True) else: mesh.CreateSubdivisionSchemeAttr().Set(UsdGeom.Tokens.none) # per-face vertex count: cube consists of 6 faces with 4 vertices each mesh.CreateFaceVertexCountsAttr(face_vertex_counts) mesh.CreateFaceVertexIndicesAttr( face_vertex_indices) # per-face vertex indices
def test_OnePointTimeSampleCorrespondenceValidation(self): stage = Usd.Stage.Open("test.usda") pbDiffNumberPositionsAndVelocities = UsdGeom.PointBased( stage.GetPrimAtPath( "/OnePointDifferingNumberPositionsAndVelocities")) pbUnalignedPositionsAndVelocities = UsdGeom.PointBased( stage.GetPrimAtPath("/OnePointUnalignedPositionsAndVelocities")) pbPositionsOnly = UsdGeom.PointBased( stage.GetPrimAtPath("/OnePointUnalignedPositionsOnly")) baseTime = 2 tr = timeRange(baseTime) pointsArrayDiffNumberPositionsAndVelocities = self.computePoints( pbDiffNumberPositionsAndVelocities, tr, baseTime) pointsArrayUnalignedPositionsAndVelocities = self.computePoints( pbUnalignedPositionsAndVelocities, tr, baseTime) pointsArrayPositionsOnly = self.computePoints(pbPositionsOnly, tr, baseTime) # Test that time sample correspondence validation works for positions # and velocities by comparing the position of the point # with invalid time sample correspondence with the positions of the point # that only has time samples for positions self.assertAllVectorListsEqual( pointsArrayDiffNumberPositionsAndVelocities, pointsArrayPositionsOnly) self.assertAllVectorListsEqual( pointsArrayUnalignedPositionsAndVelocities, pointsArrayPositionsOnly) pbDiffNumberVelocitiesAndAccelerations = UsdGeom.PointBased( stage.GetPrimAtPath( "/OnePointDiffNumberVelocitiesAndAccelerations")) pbUnalignedVelocitiesAndAccelerations = UsdGeom.PointBased( stage.GetPrimAtPath( "/OnePointUnalignedVelocitiesAndAccelerations")) pbDiffNumberPositionsAndVelocitiesAndAccelerations = UsdGeom.PointBased( stage.GetPrimAtPath( "/OnePointDiffNumberPositionsAndVelocitiesAndAccelerations")) pbPositionsAndVelocitiesOnly = UsdGeom.PointBased( stage.GetPrimAtPath("/OnePointPositionsAndVelocitiesOnly")) baseTime = 2 tr = timeRange(baseTime) pointsArrayDiffNumberVelocitiesAndAccelerations = self.computePoints( pbDiffNumberVelocitiesAndAccelerations, tr, baseTime) pointsArrayUnalignedVelocitiesAndAccelerations = self.computePoints( pbUnalignedVelocitiesAndAccelerations, tr, baseTime) pointsArrayDiffNumberPositionsAndVelocitiesAndAccelerations = self.computePoints( pbDiffNumberPositionsAndVelocitiesAndAccelerations, tr, baseTime) pointsArrayPositionsAndVelocitiesOnly = self.computePoints( pbPositionsAndVelocitiesOnly, tr, baseTime) # Test that time sample correspondence validation works for velocities # and accelerations by comparing the positions of points # with invalid time sample correspondence with the positions of the point # that only has time samples for positions and velocities self.assertAllVectorListsEqual( pointsArrayDiffNumberVelocitiesAndAccelerations, pointsArrayPositionsAndVelocitiesOnly) self.assertAllVectorListsEqual( pointsArrayUnalignedVelocitiesAndAccelerations, pointsArrayPositionsAndVelocitiesOnly) self.assertAllVectorListsEqual( pointsArrayDiffNumberPositionsAndVelocitiesAndAccelerations, pointsArrayPositionsOnly)
def add_mesh(stage, scene_path, vertices=None, faces=None, uvs=None, face_uvs_idx=None, face_normals=None, time=None): r"""Add a mesh to an existing USD stage. Add a mesh to the USD stage. The stage is modified but not saved to disk. Args: stage (Usd.Stage): Stage onto which to add the mesh. scene_path (str): Absolute path of mesh within the USD file scene. Must be a valid ``Sdf.Path``. vertices (torch.FloatTensor, optional): Vertices with shape ``(num_vertices, 3)``. faces (torch.LongTensor, optional): Vertex indices for each face with shape ``(num_faces, face_size)``. Mesh must be homogenous (consistent number of vertices per face). uvs (torch.FloatTensor, optional): of shape ``(num_uvs, 2)``. face_uvs_idx (torch.LongTensor, optional): of shape ``(num_faces, face_size)``. If provided, `uvs` must also be specified. face_normals (torch.Tensor, optional): of shape ``(num_vertices, num_faces, 3)``. time (int, optional): Positive integer defining the time at which the supplied parameters correspond to. Returns: (Usd.Stage) Example: >>> vertices = torch.rand(3, 3) >>> faces = torch.tensor([[0, 1, 2]]) >>> stage = create_stage('./new_stage.usd') >>> mesh = add_mesh(stage, '/World/mesh', vertices, faces) >>> stage.Save() """ if time is None: time = Usd.TimeCode.Default() usd_mesh = UsdGeom.Mesh.Define(stage, scene_path) if faces is not None: num_faces = faces.size(0) face_vertex_counts = [faces.size(1)] * num_faces faces_list = faces.view(-1).cpu().long().tolist() usd_mesh.GetFaceVertexCountsAttr().Set(face_vertex_counts, time=time) usd_mesh.GetFaceVertexIndicesAttr().Set(faces_list, time=time) if vertices is not None: vertices_list = vertices.cpu().float().tolist() usd_mesh.GetPointsAttr().Set(Vt.Vec3fArray(vertices_list), time=time) if uvs is not None: interpolation = None uvs_list = uvs.view(-1, 2).cpu().float().tolist() pv = UsdGeom.PrimvarsAPI(usd_mesh.GetPrim()).CreatePrimvar( "st", Sdf.ValueTypeNames.Float2Array) pv.Set(uvs_list, time=time) if face_uvs_idx is not None: pv.SetIndices(Vt.IntArray(face_uvs_idx.view(-1).cpu().long().tolist()), time=time) interpolation = 'faceVarying' else: if vertices is not None and uvs.size(0) == vertices.size(0): interpolation = 'vertex' elif uvs.size(0) == faces.size(0): interpolation = 'uniform' elif uvs.size(0) == len(faces_list): interpolation = 'faceVarying' if interpolation is not None: pv.SetInterpolation(interpolation) if face_uvs_idx is not None and uvs is None: raise ValueError('If providing "face_uvs_idx", "uvs" must also be provided.') if face_normals is not None: face_normals = face_normals.view(-1, 3).cpu().float().tolist() usd_mesh.GetNormalsAttr().Set(face_normals, time=time) UsdGeom.PointBased(usd_mesh).SetNormalsInterpolation('faceVarying') return usd_mesh.GetPrim()