def compute_distortion_energies_3D(mesh): if mesh.num_voxels > 0 and mesh.vertex_per_voxel != 4: raise RuntimeError( "Only tet mesh is supported for distortion computation") regular_tet = pymesh.generate_regular_tetrahedron() assembler = pymesh.Assembler(regular_tet) G = assembler.assemble("gradient") vertices = mesh.vertices tets = mesh.voxels Js = [G * vertices[tet] for tet in tets] J_F = np.array([np.trace(np.dot(J.T, J)) for J in Js]) J_det = np.array([numpy.linalg.det(J) for J in Js]) invert_J = lambda args: np.full( (3, 3), np.inf) if args[1] == 0 else numpy.linalg.inv(args[0]) J_inv = map(invert_J, zip(Js, J_det)) J_inv_F = np.array([np.trace(np.dot(Ji.T, Ji)) for Ji in J_inv]) conformal_amips = np.divide(J_F, np.cbrt(np.square(J_det))) finite_conformal_amips = np.isfinite(conformal_amips) symmetric_dirichlet = J_F + J_inv_F finite_symmetric_dirichlet = np.isfinite(symmetric_dirichlet) orientations = pymesh.get_tet_orientations(mesh) orientations[orientations > 0] = 1 orientations[orientations < 0] = -1 num_degenerate_tets = np.count_nonzero(orientations == 0) num_inverted_tets = np.count_nonzero(orientations < 0) num_nonfinite_amips = np.count_nonzero( np.logical_not(finite_conformal_amips)) num_nonfinite_dirichlet =\ np.count_nonzero(np.logical_not(finite_symmetric_dirichlet)) logger = logging.getLogger("Distorsion") if num_degenerate_tets > 0: logger.warn("degenerate tets: {}".format(num_degenerate_tets)) if num_inverted_tets > 0: logger.warn("inverted tets: {}".format(num_inverted_tets)) if num_nonfinite_amips > 0: logger.warn( "Non-finite conformal AMIPS: {}".format(num_nonfinite_amips)) if num_nonfinite_dirichlet > 0: logger.warn("Non-finite symmetric Dirichlet: {}".format( num_nonfinite_dirichlet)) mesh.add_attribute("conformal_AMIPS") mesh.set_attribute("conformal_AMIPS", conformal_amips) mesh.add_attribute("finite_conformal_AMIPS") mesh.set_attribute("finite_conformal_AMIPS", finite_conformal_amips) mesh.add_attribute("symmetric_Dirichlet") mesh.set_attribute("symmetric_Dirichlet", symmetric_dirichlet) mesh.add_attribute("finite_symmetric_Dirichlet") mesh.set_attribute("finite_symmetric_Dirichlet", finite_symmetric_dirichlet) mesh.add_attribute("orientations") mesh.set_attribute("orientations", orientations)
def main(): args = parse_args() basename, ext = os.path.splitext(args.output_mesh) mesh = pymesh.load_mesh(args.input_mesh) mesh = generate_tet_mesh(mesh) pymesh.save_mesh("{}_source.msh".format(basename), mesh) bd_vertex_indices, bd_vertex_positions = map_boundary_to_sphere( mesh, basename) out_mesh = tutte_3D(mesh, bd_vertex_indices, bd_vertex_positions) tet_orientations = pymesh.get_tet_orientations(out_mesh) out_mesh.add_attribute("orientation") out_mesh.set_attribute("orientation", tet_orientations) pymesh.save_mesh(args.output_mesh, out_mesh, "orientation")
def main(): args = parse_args(); basename, ext = os.path.splitext(args.output_mesh); mesh = pymesh.load_mesh(args.input_mesh); mesh = generate_tet_mesh(mesh); pymesh.save_mesh("{}_source.msh".format(basename), mesh); bd_vertex_indices, bd_vertex_positions = map_boundary_to_sphere( mesh, basename); out_mesh = tutte_3D(mesh, bd_vertex_indices, bd_vertex_positions); tet_orientations = pymesh.get_tet_orientations(out_mesh); out_mesh.add_attribute("orientation"); out_mesh.set_attribute("orientation", tet_orientations); pymesh.save_mesh(args.output_mesh, out_mesh, "orientation");
def print_extended_info(mesh, info): print_section_header("Extended info") num_cc = mesh.num_components num_f_cc = mesh.num_surface_components if mesh.num_voxels > 0: num_v_cc = mesh.num_volume_components else: num_v_cc = 0 isolated_vertices = mesh.num_isolated_vertices duplicated_faces = mesh.num_duplicated_faces unique_vertices = pymesh.unique_rows(mesh.vertices)[0] duplicated_vertices = mesh.num_vertices - len(unique_vertices) degenerated_indices = pymesh.get_degenerated_faces(mesh) num_degenerated = len(degenerated_indices) if num_degenerated > 0: degenerated_faces = mesh.faces[degenerated_indices] combinatorially_degenerated_faces = \ [f for f in degenerated_faces if len(set(f)) != len(f) ] num_combinatorial_degenerated_faces =\ len(combinatorially_degenerated_faces) else: num_combinatorial_degenerated_faces = 0 print_property("num connected components", num_cc) print_property("num connected surface components", num_f_cc) print_property("num connected volume components", num_v_cc) print_property("num isolated vertices", isolated_vertices, 0) print_property("num duplicated vertices", duplicated_vertices, 0) print_property("num duplicated faces", duplicated_faces, 0) print_property("num boundary edges", mesh.num_boundary_edges) print_property("num boundary loops", mesh.num_boundary_loops) print_property("num degenerated faces", num_degenerated, 0) if num_degenerated > 0: print_property(" combinatorially degenerated", num_combinatorial_degenerated_faces, 0) print_property(" geometrically degenerated", num_degenerated - num_combinatorial_degenerated_faces, 0) info["num_connected_components"] = num_cc info["num_connected_surface_components"] = num_f_cc info["num_connected_volume_components"] = num_v_cc info["num_isolated_vertices"] = isolated_vertices info["num_duplicated_vertices"] = duplicated_vertices info["num_duplicated_faces"] = duplicated_faces info["num_boundary_edges"] = mesh.num_boundary_edges info["num_boundary_loops"] = mesh.num_boundary_loops info["num_degenerated_faces"] = num_degenerated info["num_combinatorial_degenerated_faces"] =\ num_combinatorial_degenerated_faces info["num_geometrical_degenerated_faces"] =\ num_degenerated - num_combinatorial_degenerated_faces if mesh.dim == 2 and mesh.vertex_per_face == 3: tri_orientations = pymesh.get_triangle_orientations(mesh) num_inverted_tris = np.sum(tri_orientations < 0) print_property("num inverted triangles:", num_inverted_tris, 0) info["num_inverted_triangles"] = int(num_inverted_tris) if mesh.num_voxels > 0 and mesh.vertex_per_voxel == 4: tet_orientations = pymesh.get_tet_orientations(mesh) num_degenerate_tets = np.sum(tet_orientations == 0) num_inverted_tets = np.sum(tet_orientations < 0) print_property("num degenerated tets:", num_degenerate_tets, 0) print_property("num inverted tets:", num_inverted_tets, 0) info["num_degenerated_tets"] = int(num_degenerate_tets) info["num_inverted_tets"] = int(num_inverted_tets) is_closed = mesh.is_closed() is_edge_manifold = mesh.is_edge_manifold() is_vertex_manifold = mesh.is_vertex_manifold() is_oriented = mesh.is_oriented() euler = mesh.euler_characteristic print_property("oriented", is_oriented, True) print_property("closed", is_closed, True) print_property("edge manifold", is_edge_manifold, True) print_property("vertex manifold", is_vertex_manifold, True) print_property("euler characteristic", euler) info["oriented"] = is_oriented info["closed"] = is_closed info["vertex_manifold"] = is_vertex_manifold info["edge_manifold"] = is_edge_manifold info["euler_characteristic"] = euler
def print_extended_info(mesh, info): print_section_header("Extended info"); num_cc = mesh.num_components; num_f_cc = mesh.num_surface_components; if mesh.num_voxels > 0: num_v_cc = mesh.num_volume_components; else: num_v_cc = 0; isolated_vertices = mesh.num_isolated_vertices; duplicated_faces = mesh.num_duplicated_faces; degenerated_indices = pymesh.get_degenerated_faces(mesh); num_degenerated = len(degenerated_indices); if num_degenerated > 0: degenerated_faces = mesh.faces[degenerated_indices]; combinatorially_degenerated_faces = \ [f for f in degenerated_faces if len(set(f)) != len(f) ]; num_combinatorial_degenerated_faces =\ len(combinatorially_degenerated_faces); else: num_combinatorial_degenerated_faces = 0; print_property("num connected components", num_cc); print_property("num connected surface components", num_f_cc); print_property("num connected volume components", num_v_cc); print_property("num isolated vertices", isolated_vertices, 0); print_property("num duplicated faces", duplicated_faces, 0); print_property("num boundary edges", mesh.num_boundary_edges); print_property("num boundary loops", mesh.num_boundary_loops); print_property("num degenerated faces", num_degenerated, 0) if num_degenerated > 0: print_property(" combinatorially degenerated", num_combinatorial_degenerated_faces, 0); print_property(" geometrically degenerated", num_degenerated - num_combinatorial_degenerated_faces, 0); info["num_connected_components"] = num_cc; info["num_connected_surface_components"] = num_f_cc; info["num_connected_volume_components"] = num_v_cc; info["num_isolated_vertices"] = isolated_vertices; info["num_duplicated_faces"] = duplicated_faces; info["num_boundary_edges"] = mesh.num_boundary_edges; info["num_boundary_loops"] = mesh.num_boundary_loops; info["num_degenerated_faces"] = num_degenerated; info["num_combinatorial_degenerated_faces"] =\ num_combinatorial_degenerated_faces; info["num_geometrical_degenerated_faces"] =\ num_degenerated - num_combinatorial_degenerated_faces; if mesh.num_voxels > 0 and mesh.vertex_per_voxel == 4: tet_orientations = pymesh.get_tet_orientations(mesh); num_degenerate_tets = np.sum(tet_orientations == 0); num_inverted_tets = np.sum(tet_orientations < 0); print_property("num degenerated tets:", num_degenerate_tets, 0); print_property("num inverted tets:", num_inverted_tets, 0); info["num_degenerated_tets"] = int(num_degenerate_tets); info["num_inverted_tets"] = int(num_inverted_tets); is_closed = mesh.is_closed(); is_edge_manifold = mesh.is_edge_manifold(); is_vertex_manifold = mesh.is_vertex_manifold(); is_oriented = mesh.is_oriented(); euler = mesh.euler_characteristic; print_property("oriented", is_oriented, True); print_property("closed", is_closed, True) print_property("edge manifold", is_edge_manifold, True); print_property("vertex manifold", is_vertex_manifold, True); print_property("euler characteristic", euler); info["oriented"] = is_oriented; info["closed"] = is_closed; info["vertex_manifold"] = is_vertex_manifold; info["edge_manifold"] = is_edge_manifold; info["euler_characteristic"] = euler;
def print_extended_info(mesh, info): print_section_header("Extended info"); num_cc = mesh.num_components; num_f_cc = mesh.num_surface_components; if mesh.num_voxels > 0: num_v_cc = mesh.num_volume_components; else: num_v_cc = 0; isolated_vertices = mesh.num_isolated_vertices; duplicated_faces = mesh.num_duplicated_faces; unique_vertices = pymesh.unique_rows(mesh.vertices)[0]; duplicated_vertices = mesh.num_vertices - len(unique_vertices); degenerated_indices = pymesh.get_degenerated_faces(mesh); num_degenerated = len(degenerated_indices); if num_degenerated > 0: degenerated_faces = mesh.faces[degenerated_indices]; combinatorially_degenerated_faces = \ [f for f in degenerated_faces if len(set(f)) != len(f) ]; num_combinatorial_degenerated_faces =\ len(combinatorially_degenerated_faces); else: num_combinatorial_degenerated_faces = 0; print_property("num connected components", num_cc); print_property("num connected surface components", num_f_cc); print_property("num connected volume components", num_v_cc); print_property("num isolated vertices", isolated_vertices, 0); print_property("num duplicated vertices", duplicated_vertices, 0); print_property("num duplicated faces", duplicated_faces, 0); print_property("num boundary edges", mesh.num_boundary_edges); print_property("num boundary loops", mesh.num_boundary_loops); print_property("num degenerated faces", num_degenerated, 0) if num_degenerated > 0: print_property(" combinatorially degenerated", num_combinatorial_degenerated_faces, 0); print_property(" geometrically degenerated", num_degenerated - num_combinatorial_degenerated_faces, 0); info["num_connected_components"] = num_cc; info["num_connected_surface_components"] = num_f_cc; info["num_connected_volume_components"] = num_v_cc; info["num_isolated_vertices"] = isolated_vertices; info["num_duplicated_vertices"] = duplicated_vertices; info["num_duplicated_faces"] = duplicated_faces; info["num_boundary_edges"] = mesh.num_boundary_edges; info["num_boundary_loops"] = mesh.num_boundary_loops; info["num_degenerated_faces"] = num_degenerated; info["num_combinatorial_degenerated_faces"] =\ num_combinatorial_degenerated_faces; info["num_geometrical_degenerated_faces"] =\ num_degenerated - num_combinatorial_degenerated_faces; if mesh.dim == 2 and mesh.vertex_per_face == 3: tri_orientations = pymesh.get_triangle_orientations(mesh); num_inverted_tris = np.sum(tri_orientations < 0); print_property("num inverted triangles:", num_inverted_tris, 0); info["num_inverted_triangles"] = int(num_inverted_tris); if mesh.num_voxels > 0 and mesh.vertex_per_voxel == 4: tet_orientations = pymesh.get_tet_orientations(mesh); num_degenerate_tets = np.sum(tet_orientations == 0); num_inverted_tets = np.sum(tet_orientations < 0); print_property("num degenerated tets:", num_degenerate_tets, 0); print_property("num inverted tets:", num_inverted_tets, 0); info["num_degenerated_tets"] = int(num_degenerate_tets); info["num_inverted_tets"] = int(num_inverted_tets); is_closed = mesh.is_closed(); is_edge_manifold = mesh.is_edge_manifold(); is_vertex_manifold = mesh.is_vertex_manifold(); is_oriented = mesh.is_oriented(); euler = mesh.euler_characteristic; print_property("oriented", is_oriented, True); print_property("closed", is_closed, True) print_property("edge manifold", is_edge_manifold, True); print_property("vertex manifold", is_vertex_manifold, True); print_property("euler characteristic", euler); info["oriented"] = is_oriented; info["closed"] = is_closed; info["vertex_manifold"] = is_vertex_manifold; info["edge_manifold"] = is_edge_manifold; info["euler_characteristic"] = euler;