def preprocess_spiral(face, seq_length, vertices=None, dilation=1): from generate_spiral_seq import extract_spirals assert face.shape[1] == 3 if vertices is not None: mesh = om.TriMesh(np.array(vertices), np.array(face)) else: n_vertices = face.max() + 1 mesh = om.TriMesh(np.ones([n_vertices, 3]), np.array(face)) spirals = torch.tensor( extract_spirals(mesh, seq_length=seq_length, dilation=dilation)) return spirals
def setUp(self): self.mesh = openmesh.TriMesh() # Add some vertices self.vhandle = [] self.vhandle.append(self.mesh.add_vertex(np.array([0, 1, 0]))) self.vhandle.append(self.mesh.add_vertex(np.array([1, 0, 0]))) self.vhandle.append(self.mesh.add_vertex(np.array([2, 1, 0]))) self.vhandle.append(self.mesh.add_vertex(np.array([0, -1, 0]))) self.vhandle.append(self.mesh.add_vertex(np.array([2, -1, 0]))) # Add four faces using Python lists vertex_list = [self.vhandle[0], self.vhandle[1], self.vhandle[2]] self.mesh.add_face(vertex_list) vertex_list = [self.vhandle[1], self.vhandle[3], self.vhandle[4]] self.mesh.add_face(vertex_list) vertex_list = [self.vhandle[0], self.vhandle[3], self.vhandle[1]] self.mesh.add_face(vertex_list) vertex_list = [self.vhandle[2], self.vhandle[1], self.vhandle[4]] self.mesh.add_face(vertex_list) # Test setup: # 0 ==== 2 # |\ 0 /| # | \ / | # |2 1 3| # | / \ | # |/ 1 \| # 3 ==== 4 self.assertEqual(self.mesh.n_faces(), 4)
def test_decimate(): mesh = openmesh.TriMesh() # Test setup: # 1------2\ # |\ B | \ # | \ |C 4 # | A \ | / # 0------3/ # Add vertices vhandle = [] vhandle.append(mesh.add_vertex(np.array([0, 0, 0]))) vhandle.append(mesh.add_vertex(np.array([0, 1, 0]))) vhandle.append(mesh.add_vertex(np.array([1, 1, 0]))) vhandle.append(mesh.add_vertex(np.array([1, 0, 0]))) vhandle.append(mesh.add_vertex(np.array([1.5, 0.5, 0]))) # Add faces faces = [[0, 1, 3], [1, 2, 3], [2, 4, 3]] for v in faces: face_vhandles = [] face_vhandles.append(vhandle[v[0]]) face_vhandles.append(vhandle[v[1]]) face_vhandles.append(vhandle[v[2]]) mesh.add_face(face_vhandles) decimated = decimate(mesh, 3) print(decimated.n_vertices()) print(mesh.n_vertices()) assert decimated.n_vertices() == 3
def test_split_copy_triangle_mesh(self): self.mesh = openmesh.TriMesh() self.vhandle = [] # Add some vertices self.vhandle.append(self.mesh.add_vertex(np.array([0, 0, 0]))) self.vhandle.append(self.mesh.add_vertex(np.array([0, 1, 0]))) self.vhandle.append(self.mesh.add_vertex(np.array([1, 1, 0]))) self.vhandle.append(self.mesh.add_vertex(np.array([0.25, 0.25, 0]))) # Add one face face_vhandles = [] face_vhandles.append(self.vhandle[2]) face_vhandles.append(self.vhandle[1]) face_vhandles.append(self.vhandle[0]) fh = self.mesh.add_face(face_vhandles) # Test setup: # 1 === 2 # | / # | / # | / # 0 # Set property self.mesh.set_face_property("fprop_int", fh, 999) # Split face with new vertex self.mesh.split_copy(fh, self.vhandle[3]) # Check setup for fh in self.mesh.faces(): self.assertEqual(self.mesh.face_property("fprop_int", fh), 999)
def sphere(): # tetrahedron pts = np.array([[1, -1, -1], [0, 1, -1], [-1, -1, -1], [0, 0, 1]]) faces = np.array([[2, 1, 0], [0, 1, 3], [1, 2, 3], [2, 0, 3]], 'i') # remesh to sphere remesher = mu.pyremesh.remesher() remesher.init_mesh(pts, faces) targetEdgeLength = 0.2 low = (4.0 / 5.0) * targetEdgeLength high = (4.0 / 3.0) * targetEdgeLength for _ in range(10): remesher.split_long_edges(high) remesher.collapse_short_edges(low, high) remesher.equalize_valences() remesher.tangential_relaxation() # project_to_surface() verts, _ = remesher.get_mesh() norms = np.linalg.norm(verts, axis=1) remesher.update_points(verts / norms[:, np.newaxis]) verts, faces = remesher.get_mesh() mesh = om.TriMesh(verts, faces) om.write_mesh(folder + 'sphere.obj', mesh)
def sphere_with_feature(): fn_mesh = folder + 'sphere.obj' mesh = om.read_trimesh(fn_mesh) # split field = mesh.points()[:, 0] isocurve = mu.pyisocurve.isocurve(mesh.points(), mesh.face_vertex_indices(), field) pts, on_edges, ratios, isocurve_indices = isocurve.extract(0.0, 1.e-5) mu.write_obj_lines(folder + 'curve.obj', pts, isocurve_indices) mesh, curve_idx = mu.split_mesh(mesh.points(), mesh.face_vertex_indices(), on_edges, ratios) # print(curve_idx) # om.write_mesh('../data/mesh_split.obj', mesh) curve = [curve_idx[v] for v in isocurve_indices[0]] feature = np.empty((len(curve) - 1, 2), 'i') feature[:, 0] = curve[:-1] feature[:, 1] = curve[1:] remesher = mu.pyremesh.remesher() remesher.init_mesh(mesh.points(), mesh.face_vertex_indices()) remesher.set_features(feature) feat_edges = remesher.get_features() feat_verts = remesher.get_feature_vertices() # write_obj_lines(folder+'feature_detect_e.obj', mesh.points(), feat_edges) # write_obj_lines(folder+'feature_detect_v.obj', mesh.points()[feat_verts], []) remesher.remesh(0.1, 15) verts, faces = remesher.get_mesh() mesh = om.TriMesh(verts, faces) om.write_mesh(folder + 'sphere_split.obj', mesh)
def test_write_triangle(self): self.mesh = openmesh.TriMesh() # Generate data v1 = self.mesh.add_vertex(np.array([1.0, 0.0, 0.0])) v2 = self.mesh.add_vertex(np.array([0.0, 1.0, 0.0])) v3 = self.mesh.add_vertex(np.array([0.0, 0.0, 1.0])) self.mesh.add_face(v1, v2, v3) # Save filename = "OutFiles/triangle-minimal.om" openmesh.write_mesh(filename, self.mesh) # Load self.mesh = openmesh.read_trimesh(filename) # Compare self.assertEqual(self.mesh.n_vertices(), 3) self.assertEqual(self.mesh.n_edges(), 3) self.assertEqual(self.mesh.n_faces(), 1) self.assertTrue( np.allclose(self.mesh.point(v1), np.array([1.0, 0.0, 0.0]))) self.assertTrue( np.allclose(self.mesh.point(v2), np.array([0.0, 1.0, 0.0]))) self.assertTrue( np.allclose(self.mesh.point(v3), np.array([0.0, 0.0, 1.0]))) # Cleanup os.remove(filename)
def test_add_triangles_to_trimesh(self): self.mesh = openmesh.TriMesh() self.vhandle = [] # Add some vertices self.vhandle.append(self.mesh.add_vertex(np.array([0, 0, 0]))) self.vhandle.append(self.mesh.add_vertex(np.array([0, 1, 0]))) self.vhandle.append(self.mesh.add_vertex(np.array([1, 1, 0]))) self.vhandle.append(self.mesh.add_vertex(np.array([1, 0, 0]))) # Add two faces face_vhandles = [] face_vhandles.append(self.vhandle[2]) face_vhandles.append(self.vhandle[1]) face_vhandles.append(self.vhandle[0]) self.mesh.add_face(face_vhandles) face_vhandles = [] face_vhandles.append(self.vhandle[2]) face_vhandles.append(self.vhandle[0]) face_vhandles.append(self.vhandle[3]) self.mesh.add_face(face_vhandles) # Test setup: # 1 === 2 # | / | # | / | # | / | # 0 === 3 # Check setup self.assertEqual(self.mesh.n_vertices(), 4) self.assertEqual(self.mesh.n_faces(), 2)
def one_triangle(self): mesh = openmesh.TriMesh() vh0 = mesh.add_vertex([0, 0, 0]) vh1 = mesh.add_vertex([1, 0, 0]) vh2 = mesh.add_vertex([1, 1, 0]) mesh.add_face(vh0, vh1, vh2) return mesh
def setUp(self): self.mesh = openmesh.TriMesh() self.mesh.request_vertex_status() self.mesh.request_edge_status() self.mesh.request_halfedge_status() self.mesh.request_face_status() # Add some vertices self.vhandle = [] self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, 1))) self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, 1))) self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, 1))) self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, 1))) self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, -1, -1))) self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, -1, -1))) self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d( 1, 1, -1))) self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(-1, 1, -1))) # Add six faces to form a cube self.mesh.add_face(self.vhandle[0], self.vhandle[1], self.vhandle[3]) self.mesh.add_face(self.vhandle[1], self.vhandle[2], self.vhandle[3]) self.mesh.add_face(self.vhandle[7], self.vhandle[6], self.vhandle[5]) self.mesh.add_face(self.vhandle[7], self.vhandle[5], self.vhandle[4]) self.mesh.add_face(self.vhandle[1], self.vhandle[0], self.vhandle[4]) self.mesh.add_face(self.vhandle[1], self.vhandle[4], self.vhandle[5]) self.mesh.add_face(self.vhandle[2], self.vhandle[1], self.vhandle[5]) self.mesh.add_face(self.vhandle[2], self.vhandle[5], self.vhandle[6]) self.mesh.add_face(self.vhandle[3], self.vhandle[2], self.vhandle[6]) self.mesh.add_face(self.vhandle[3], self.vhandle[6], self.vhandle[7]) self.mesh.add_face(self.vhandle[0], self.vhandle[3], self.vhandle[7]) self.mesh.add_face(self.vhandle[0], self.vhandle[7], self.vhandle[4])
def __init__(self, levels, thickness, length, scaling_length, scaling_thickness, theta1, theta2, delta, leaf=False, leaf_r=0.0): self.levels = levels self.thickness = thickness self.length = length self.base = None self.s_length = scaling_length self.s_thickness = scaling_thickness self.theta1 = theta1 self.theta2 = theta2 self.delta = delta self.node = None self.leaf = leaf self.leaf_r = leaf_r self.mesh = om.TriMesh() self.build_root() self.build_branches()
def createPyramidMesh(textured=False): mesh = openmesh.TriMesh() nw = mesh.add_vertex(np.array([-0.5, 0.5, 0.0])) ne = mesh.add_vertex(np.array([0.5, 0.5, 0.0])) sw = mesh.add_vertex(np.array([-0.5, -0.5, 0.0])) se = mesh.add_vertex(np.array([0.5, -0.5, 0.0])) t = mesh.add_vertex(np.array([0.0, 0.0, 1.0])) # Top Vertex mesh.add_face([ne, nw, t]) # N mesh.add_face([se, ne, t]) # E mesh.add_face([sw, se, t]) # S mesh.add_face([nw, sw, t]) # W mesh.add_face([ne, se, sw]) # Bottom mesh.add_face([sw, nw, ne]) # Bottom if textured: # Do note the trick, faces at the east and west are sampling the texture in the opposite direction. # If you do not want to do this, you need to replicate the spatial vertex and assign different texture coordinates to each of them. # This is only to use the same texture on each side of the pyramid. mesh.set_texcoord2D(nw, [1.0, 1.0]) mesh.set_texcoord2D(ne, [0.0, 1.0]) mesh.set_texcoord2D(sw, [0.0, 1.0]) mesh.set_texcoord2D(se, [1.0, 1.0]) mesh.set_texcoord2D(t, [0.5, 0.0]) return mesh
def read_obj(filename): mesh = OM.TriMesh() options = OM.Options() ok = OM.read_mesh(mesh, filename, options) mesh.request_face_normals() mesh.update_face_normals() if not ok: raise RuntimeError('read_obj() failed to read file: ' + filename) return mesh
def cut_along_curve_igl(V, F, curve_index): mesh = om.TriMesh(V, F) cuts = np.zeros_like(F, 'i') vhs = [mesh.vertex_handle(i) for i in curve_index] for i in range(len(curve_index)-1): he0 = mesh.find_halfedge(vhs[i], vhs[i+1]) if not he0.is_valid(): warnings.warn('[meshutility.cut_along_curve] invalid edge to cut %d->%d' % (curve_index[i], curve_index[i+1])) he1 = mesh.opposite_halfedge_handle(he0) for he in [he0, he1]: if not mesh.is_boundary(he): fh = mesh.face_handle(he) f = F[fh.idx()] for j in range(3): if {f[j], f[(j+1)%3]} == {curve_index[i], curve_index[i+1]}: # compare two sets cuts[fh.idx(),j] = 1 break V1, F1 = igl_cut_mesh(V, F, cuts) curve_new_index = [F1[np.where(F==i)].max() for i in curve_index] # But curve_new_index may not be a valid curve index_mapping = np.arange(V1.shape[0]) mesh = om.TriMesh(V1, F1) v0 = curve_index[0] for i in range(len(curve_index)-1): # which is correct? # curve_index[i] -> curve_index[i+1] # curve_index[i] -> curve_new_index[i+1] vh0 = mesh.vertex_handle(v0) vh1 = mesh.vertex_handle(curve_index[i+1]) #vh2 = mesh.vertex_handle(curve_new_index[i+1]) he01 = mesh.find_halfedge(vh0, vh1) #he02 = mesh.find_halfedge(vh0, vh2) if not he01.is_valid(): index_mapping[curve_index[i+1]] = curve_new_index[i+1] index_mapping[curve_new_index[i+1]] = curve_index[i+1] v0 = curve_new_index[i+1] else: v0 = curve_index[i+1] # But curve_new_index may not be a valid curve F1 = index_mapping[F1.ravel()].reshape((-1,3)) mesh = om.TriMesh(V1, F1) return mesh, curve_new_index
def mesh2obj_file(dest_path, mesh, color=None, center=None, scale=None): """ Writes mesh to .obj file. Parameters ---------- dest_path : str mesh : List[np.array] flattend arrays of indices (triangle faces), vertices and normals color : center : np.array Subtracts center from original vertex locations scale : float Multiplies vertex locations after centering Returns ------- """ # # Commented lines belonged to self-compiled openmesh version # options = openmesh.Options() # options += openmesh.Options.Binary mesh_obj = openmesh.TriMesh() ind, vert, norm = mesh if vert.ndim == 1: vert = vert.reshape(-1, 3) if ind.ndim == 1: ind = ind.reshape(-1, 3) if center is not None: vert -= center if scale is not None: vert *= scale vert_openmesh = [] if color is not None: mesh_obj.request_vertex_colors() # options += openmesh.Options.VertexColor if color.ndim == 1: color = np.array([color] * len(vert)) color = color.astype(np.float64) # required by openmesh for ii, v in enumerate(vert): v = v.astype(np.float64) # Point requires double # v_openmesh = mesh_obj.add_vertex(openmesh.TriMesh.Point(v[0], v[1], v[2])) v_openmesh = mesh_obj.add_vertex(v) if color is not None: # mesh_obj.set_color(v_openmesh, openmesh.TriMesh.Color(*color[ii])) mesh_obj.set_color(v_openmesh, color[ii]) vert_openmesh.append(v_openmesh) for f in ind: f_openmesh = [ vert_openmesh[f[0]], vert_openmesh[f[1]], vert_openmesh[f[2]] ] mesh_obj.add_face(f_openmesh) # result = openmesh.write_mesh(mesh_obj, dest_path, options) # result = openmesh.write_mesh(mesh_obj, dest_path) result = openmesh.write_mesh(dest_path, mesh_obj)
def convert_to_trimesh(V, F): m = om.TriMesh() for e in V: m.add_vertex(e) for e in F: m.add_face([ m.vertex_handle(e[0]), m.vertex_handle(e[1]), m.vertex_handle(e[2]) ]) return m
def setUp(self): self.mesh = openmesh.TriMesh() self.vh1 = self.mesh.add_vertex([0, 0, 0]) self.vh2 = self.mesh.add_vertex([1, 0, 0]) self.vh3 = self.mesh.add_vertex([1, 1, 0]) self.fh = self.mesh.add_face(self.vh1, self.vh2, self.vh3) self.mesh.set_vertex_property('test', self.vh1, self.mesh) self.mesh.set_vertex_property('test', self.vh2, self.mesh) self.one_two_three = [1, 2, 3] self.mesh.set_vertex_property('test', self.vh3, self.one_two_three) self.mesh.set_face_property('test', self.fh, self.one_two_three)
def _convert_to_trimesh(V, F, VL) -> om.TriMesh: m = om.TriMesh() for i, e in enumerate(V): m.set_vertex_property("cur_v:label", m.add_vertex(e), VL[i]) for e in F: m.add_face([ m.vertex_handle(e[0]), m.vertex_handle(e[1]), m.vertex_handle(e[2]) ]) return m
def setUp(self): self.mesh = openmesh.TriMesh() # Add some vertices self.vhandle = [] self.vhandle.append(self.mesh.add_vertex(np.array([0, 1, 0]))) self.vhandle.append(self.mesh.add_vertex(np.array([1, 0, 0]))) self.vhandle.append(self.mesh.add_vertex(np.array([2, 1, 0]))) self.vhandle.append(self.mesh.add_vertex(np.array([0, -1, 0]))) self.vhandle.append(self.mesh.add_vertex(np.array([2, -1, 0])))
def setUp(self): self.mesh = openmesh.TriMesh() # Add some vertices self.vhandle = [] self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, 1, 0))) self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(1, 0, 0))) self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, 1, 0))) self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(0, -1, 0))) self.vhandle.append(self.mesh.add_vertex(openmesh.Vec3d(2, -1, 0)))
def cut_along_curve_mu(V, F, curve_index): mesh = om.TriMesh(V, F) assert mesh.n_vertices() == V.shape[0], "Invalid input mesh" assert(len(curve_index) > 1) be_loop = (curve_index[0] == curve_index[-1]) if be_loop: cutter = MeshCutterLoop() return cutter.cut(mesh, curve_index) else: cutter = MeshCutter() return cutter.cut(mesh, curve_index)
def create_adj_mtx(coords_file, tri_file, is_sparse=True): """ Given a file with the coordinates for each point as well as triplets of ids for each mesh triangle, creates an adjacency matrix :param coords_file: a CSV file or python object that includes the coordinates for each point in the mesh :param tri_file: a CSV file or python object that includes the triplets of vertices for each triangle of the mesh :param is_sparse: whether a sparse implementation is desired :return: adjacency matrix and the coordinates and triangles parsed as python list objects """ mesh = om.TriMesh() if isinstance(coords_file, str) and isinstance(tri_file, str): coords = genfromtxt( coords_file, delimiter=',') # these include the coordinates for each point triangles = genfromtxt( tri_file, delimiter=',') # these include the vertices in each triangle triangles = triangles.astype(int) else: coords = coords_file triangles = tri_file triangles = np.array(triangles) verts = [] for i in coords: verts.append(mesh.add_vertex(i)) faces = [] for i in triangles: faces.append(mesh.add_face(verts[i[0]], verts[i[1]], verts[i[2]])) adj_mtx = np.zeros(shape=(coords.shape[0], coords.shape[0])) for i in triangles: p1 = i[0] p2 = i[1] p3 = i[2] adj_mtx[p1][p2] = 1 adj_mtx[p2][p1] = 1 adj_mtx[p1][p3] = 1 adj_mtx[p3][p1] = 1 adj_mtx[p2][p3] = 1 adj_mtx[p3][p2] = 1 if is_sparse: return sparse.csr_matrix(adj_mtx), coords, triangles else: return adj_mtx, coords, triangles
def array_to_mesh(V, F, v_colors=None, f_colors=None, v_normals=True, cmap_name="Set1"): """ convert a mesh with (N,3) vertices and (F,3) faces to a trimesh object """ assert(V.ndim==2) assert(F.ndim==2) assert(F.shape[-1]==3) if isinstance(V, torch.Tensor): V = V.detach().cpu().numpy() if isinstance(F, torch.Tensor): F = F.detach().cpu().numpy() mesh = om.TriMesh(points=V, face_vertex_indices=F) if v_colors is not None: if isinstance(v_colors, torch.Tensor): v_colors = v_colors.detach().cpu().numpy() assert(v_colors.shape[0]==V.shape[0]) # 1D scalar for each face if v_colors.size == V.shape[0]: cmap = cm.get_cmap(cmap_name) minV, maxV = v_colors.min(), v_colors.max() v_colors = (v_colors-minV)/maxV v_colors = [cmap(color) for color in v_colors] else: assert(v_colors.shape[1]==3 or v_colors.shape[1]==4) if v_colors.shape[1] == 3: mesh.vertex_colors()[:,-1]=1 mesh.request_vertex_colors() mesh.vertex_colors()[:] = v_colors if f_colors is not None: assert(f_colors.shape[0]==F.shape[0]) # 1D scalar for each face if f_colors.size == F.shape[0]: cmap = cm.get_cmap(cmap_name) minV, maxV = f_colors.min(), f_colors.max() f_colors = (f_colors-minV)/maxV f_colors = [cmap(color) for color in f_colors] else: assert(f_colors.shape[1]==3 or f_colors.shape[1]==4) if f_colors.shape[1] == 3: mesh.face_colors()[:,-1]=1 mesh.request_face_colors() mesh.face_colors()[:] = f_colors mesh.request_face_normals() if v_normals: mesh.request_vertex_normals() mesh.update_normals() return mesh
def openmesh_from_cdt(vertices, triangles): omesh = openmesh.TriMesh() vertex_handles = [] for sv in vertices: vertex_handles.append(omesh.add_vertex(sv.XYZ_vec3())) for triangle in cdt_triangles: i0, i1, i2 = triangle vh0 = vertex_handles[i0] vh1 = vertex_handles[i1] vh2 = vertex_handles[i2] omesh.add_face(vh0, vh1, vh2) return omesh
def setUp(self): self.mesh = openmesh.TriMesh() # Add some vertices self.vhandle = [] self.vhandle.append(self.mesh.add_vertex(np.array([0, 1, 0]))) self.vhandle.append(self.mesh.add_vertex(np.array([1, 0, 0]))) self.vhandle.append(self.mesh.add_vertex(np.array([2, 1, 0]))) self.vhandle.append(self.mesh.add_vertex(np.array([0,-1, 0]))) self.vhandle.append(self.mesh.add_vertex(np.array([2,-1, 0]))) self.vhandle.append(self.mesh.add_vertex(np.array([3, 0, 0]))) # Single point self.vhandle.append(self.mesh.add_vertex(np.array([0,-2, 0]))) # Add five faces self.fhandle = [] face_vhandles = [] face_vhandles.append(self.vhandle[0]) face_vhandles.append(self.vhandle[1]) face_vhandles.append(self.vhandle[2]) self.fhandle.append(self.mesh.add_face(face_vhandles)) face_vhandles = [] face_vhandles.append(self.vhandle[1]) face_vhandles.append(self.vhandle[3]) face_vhandles.append(self.vhandle[4]) self.fhandle.append(self.mesh.add_face(face_vhandles)) face_vhandles = [] face_vhandles.append(self.vhandle[0]) face_vhandles.append(self.vhandle[3]) face_vhandles.append(self.vhandle[1]) self.fhandle.append(self.mesh.add_face(face_vhandles)) face_vhandles = [] face_vhandles.append(self.vhandle[2]) face_vhandles.append(self.vhandle[1]) face_vhandles.append(self.vhandle[4]) self.fhandle.append(self.mesh.add_face(face_vhandles)) face_vhandles = [] face_vhandles.append(self.vhandle[5]) face_vhandles.append(self.vhandle[2]) face_vhandles.append(self.vhandle[4]) self.fhandle.append(self.mesh.add_face(face_vhandles))
def rect(): pts = np.array([ [-1, -1, 0], [1, -1, 0], [1, 1, 0], [-1, 1, 0], ], 'f') faces = np.array([[0, 1, 2], [0, 2, 3]], 'i') remesher = mu.pyremesh.remesher() remesher.init_mesh(pts, faces) remesher.set_feature_vertices_by_angle(20) remesher.remesh(0.5, 10) verts, faces = remesher.get_mesh() mesh = om.TriMesh(verts, faces) om.write_mesh(folder + 'rect.obj', mesh)
def make_cuboid(p0, p1, p2, p3, p4, p5, p6, p7): """ Creates a cuboid like object. The ccw-order front face is given by [p0 p1 p2 p3], the ccw-order back-face is given by [p4, p7, p6, p5] :param p0: :param p1: :param p2: :param p3: :param p4: :param p5: :param p6: :param p7: :return: """ mesh = OM.TriMesh() v0 = mesh.add_vertex(OM.TriMesh.Point(p0[0], p0[1], p0[2])) v1 = mesh.add_vertex(OM.TriMesh.Point(p1[0], p1[1], p1[2])) v2 = mesh.add_vertex(OM.TriMesh.Point(p2[0], p2[1], p2[2])) v3 = mesh.add_vertex(OM.TriMesh.Point(p3[0], p3[1], p3[2])) v4 = mesh.add_vertex(OM.TriMesh.Point(p4[0], p4[1], p4[2])) v5 = mesh.add_vertex(OM.TriMesh.Point(p5[0], p5[1], p5[2])) v6 = mesh.add_vertex(OM.TriMesh.Point(p6[0], p6[1], p6[2])) v7 = mesh.add_vertex(OM.TriMesh.Point(p7[0], p7[1], p7[2])) quads = [ [v0, v1, v2, v3], # front face [v4, v7, v6, v5], # back face [v4, v0, v3, v7], # left face [v1, v5, v6, v2], # right face [v7, v3, v2, v6], # top face [v5, v1, v0, v4], # bottom face ] for i in range(6): vi = quads[i][0] vj = quads[i][1] vk = quads[i][2] vm = quads[i][3] mesh.add_face(vi, vj, vk) mesh.add_face(vi, vk, vm) mesh.request_face_normals() mesh.update_face_normals() return mesh
def join(mesh_list): mesh = OM.TriMesh() for part in mesh_list: lut = dict() for vh in part.vertices(): p = get_vertex_coords(part, vh) lut[vh.idx()] = mesh.add_vertex(OM.TriMesh.Point(p[0], p[1], p[2])) for fh in part.faces(): vhandle = [] for vh in part.fv(fh): vhandle.append(lut[vh.idx()]) mesh.add_face(vhandle[0], vhandle[1], vhandle[2]) mesh.request_face_normals() mesh.update_face_normals() return mesh
def make_tetrahedron(p0, p1, p2, p3): mesh = OM.TriMesh() vi = mesh.add_vertex(OM.TriMesh.Point(p0[0], p0[1], p0[2])) vj = mesh.add_vertex(OM.TriMesh.Point(p1[0], p1[1], p1[2])) vk = mesh.add_vertex(OM.TriMesh.Point(p2[0], p2[1], p2[2])) vm = mesh.add_vertex(OM.TriMesh.Point(p3[0], p3[1], p3[2])) mesh.add_face(vi, vk, vj) mesh.add_face(vi, vj, vm) mesh.add_face(vj, vk, vm) mesh.add_face(vk, vi, vm) mesh.request_face_normals() mesh.update_face_normals() return mesh
def test_write_and_read_vertex_colors_to_and_from_off_file(self): self.mesh = openmesh.TriMesh() self.mesh.request_vertex_colors() self.mesh.add_vertex(np.array([0, 0, 1])) self.mesh.add_vertex(np.array([0, 1, 0])) self.mesh.add_vertex(np.array([0, 1, 1])) self.mesh.add_vertex(np.array([1, 0, 1])) # Using the default openmesh Python color type testColor = np.array([1.0, 0.5, 0.25, 1.0]) # Setting colors (different from black) for v in self.mesh.vertices(): self.mesh.set_color(v, testColor) # Check if the colors are correctly set count = 0 for v in self.mesh.vertices(): color = self.mesh.color(v) if color[0] != testColor[0] or color[1] != testColor[1] or color[ 2] != testColor[2]: count += 1 self.assertEqual(count, 0) openmesh.write_mesh("OutFiles/temp.off", self.mesh, vertex_color=True, color_float=True) self.mesh = openmesh.read_trimesh("OutFiles/temp.off", vertex_color=True, color_float=True) # Check if vertices still have the same color count = 0 for v in self.mesh.vertices(): color = self.mesh.color(v) if color[0] != testColor[0] or color[1] != testColor[1] or color[ 2] != testColor[2]: count += 1 self.assertEqual(count, 0) self.mesh.release_vertex_colors()