def get_one(self, path, subsamplemesh=False):
        if path in self.cache:
            return self.cache[path]
        else:
            try:
                h5_f = h5py.File(path)
                if (self.maxnverts != -1 and h5_f['verts'].shape[0] > self.maxnverts) or (self.maxntris != -1 and h5_f['tris'].shape[0] > self.maxntris):
                    raise Exception()

                verts, tris = h5_f['verts'][:], h5_f['tris'][:]
            except:
                h5_f.close()
                self.cache[path] = None
                return None

            if self.normalize:
                centroid = None
                verts, _ = self.pc_normalize(verts, centroid)

            if subsamplemesh:
                mesh = pymesh.form_mesh(verts, tris)
                mesh, _ = pymesh.split_long_edges(mesh, 0.05)
                verts, tris = mesh.vertices, mesh.faces
                if (self.maxnverts != -1 and verts.shape[0] > self.maxnverts) or (self.maxntris != -1 and tris.shape[0] > self.maxntris):
                    return None

            if len(self.cache) < self.cache_size:
                self.cache[path] = (verts, tris)
            h5_f.close()

            return verts, tris
Exemple #2
0
def fix_mesh(mesh, resolution):
    bbox_min, bbox_max = mesh.bbox
    diag_len = norm(bbox_max - bbox_min)

    target_len = diag_len * resolution

    rospy.loginfo("\tTarget resolution: {} mm".format(target_len))

    count = 0
    mesh, __ = pymesh.remove_degenerated_triangles(mesh, 100)
    mesh, __ = pymesh.split_long_edges(mesh, target_len)
    num_vertices = mesh.num_vertices
    while True:
        mesh, __ = pymesh.collapse_short_edges(mesh, 1e-6)
        mesh, __ = pymesh.collapse_short_edges(mesh,
                                               target_len,
                                               preserve_feature=True)
        mesh, __ = pymesh.remove_obtuse_triangles(mesh, 150.0, 100)
        if mesh.num_vertices == num_vertices:
            break

        num_vertices = mesh.num_vertices
        rospy.loginfo("\t#vertices: {}".format(num_vertices))
        count += 1
        if count > 2: break

    mesh = pymesh.resolve_self_intersection(mesh)
    mesh, __ = pymesh.remove_duplicated_faces(mesh)
    mesh = pymesh.compute_outer_hull(mesh)
    mesh, __ = pymesh.remove_duplicated_faces(mesh)
    mesh, __ = pymesh.remove_obtuse_triangles(mesh, 179.0, 5)
    mesh, __ = pymesh.remove_isolated_vertices(mesh)

    return mesh
Exemple #3
0
    def make_high_res_template_from_low_res(self):
        """
        This function takes a path to the orginal shapenet model and subsample it nicely
        """
        import pymesh
        if not(self.point_translation or self.patch_deformation):
            self.template[0].template_learned_HR = self.template[0].vertex_HR

        if self.patch_deformation:
            templates = self.get_patch_deformation_template(high_res = True)
            self.template[0].template_learned_HR = templates[0]

        if self.point_translation:
            templates = self.get_points_translation_template()

            if self.dim_template == 3:
                template_points = templates[0].cpu().clone().detach().numpy()
                obj1 = pymesh.form_mesh(vertices=template_points, faces=self.template[0].mesh.faces)
                if len(obj1.vertices)<100000:
                    obj1 = pymesh.split_long_edges(obj1, 0.02)[0]
                    while len(obj1.vertices)<100000:
                        obj1 = pymesh.subdivide(obj1)
                self.template[0].mesh_HR = obj1
                self.template[0].template_learned_HR = torch.from_numpy(obj1.vertices).cuda().float()
                self.template[0].num_vertex_HR = self.template[0].template_learned_HR.size(0)
                print(f"Make high res template with {self.template[0].num_vertex_HR} points.")
Exemple #4
0
def repousse(mesh, logger):
    cell_ids = mesh.get_attribute("cell").ravel().astype(int);
    mesh.add_attribute("edge_length");
    tol = np.amax(mesh.get_attribute("edge_length")) * 0.1;

    bbox_min, bbox_max = mesh.bbox;
    scaling = 2.0 / norm(bbox_max - bbox_min);

    start_time = time();
    num_cells = np.amax(cell_ids)+1;
    results = [];
    for i in range(num_cells):
        to_keep = np.arange(mesh.num_faces, dtype=int)[cell_ids == i];
        if not np.any(to_keep):
            continue;

        cut_mesh = pymesh.submesh(mesh, to_keep, 0);
        pymesh.save_mesh("debug.msh", cut_mesh);
        cut_mesh, __ = pymesh.remove_degenerated_triangles(cut_mesh, 100);
        cut_mesh, __ = pymesh.split_long_edges(cut_mesh, tol);

        dof = cut_mesh.num_vertices;
        assembler = pymesh.Assembler(cut_mesh);
        L = assembler.assemble("laplacian");
        M = assembler.assemble("mass");

        L_rhs = M * np.ones(dof) * -0.5;
        bd_indices = cut_mesh.boundary_vertices;
        n = len(bd_indices);
        C = scipy.sparse.coo_matrix((np.ones(n),
            (np.arange(n, dtype=int), bd_indices)), shape=(n, dof));
        C_rhs = np.zeros(n);

        A = scipy.sparse.bmat([
            [-L, C.T],
            [C, None]
            ]);
        rhs = np.concatenate((L_rhs.ravel(), C_rhs));

        solver = pymesh.SparseSolver.create("SparseLU");
        solver.compute(A);
        x = solver.solve(rhs);

        z = x[:dof].reshape((-1, 1));

        vertices = np.hstack((cut_mesh.vertices, z));
        out_mesh = pymesh.form_mesh(vertices, cut_mesh.faces);
        results.append(out_mesh);

    finish_time = time();
    t = finish_time - start_time;
    logger.info("Repousse running time: {}".format(t));

    mesh = pymesh.merge_meshes(results);

    vertices = mesh.vertices[:,:2];
    mesh_2d = pymesh.form_mesh(vertices, mesh.faces);
    pymesh.save_mesh("out_2d.msh", mesh_2d)
    return mesh;
Exemple #5
0
def main():
    args = parse_args()
    mesh = pymesh.load_mesh(args.input_mesh, drop_zero_dim=True)
    mesh, __ = pymesh.split_long_edges(mesh, 0.01)
    points = mesh.vertices[mesh.boundary_vertices, :]
    mesh = pymesh.triangulate_beta(points, args.engine)
    pymesh.save_mesh(args.output_mesh, mesh)
    pymesh.timethis.summarize()
Exemple #6
0
def main():
    args = parse_args();
    mesh = pymesh.load_mesh(args.input_mesh, drop_zero_dim=True);
    mesh,__ = pymesh.split_long_edges(mesh, 0.01);
    points = mesh.vertices[mesh.boundary_vertices,:];
    mesh = pymesh.triangulate_beta(points, args.engine);
    pymesh.save_mesh(args.output_mesh, mesh);
    pymesh.timethis.summarize();
Exemple #7
0
def demo():
    with tf.device('/gpu:0'):
        for i in range(2,4):
            src_verts, src_tris = data_off.read_off('%02d_input.off' % i)
            src_verts = pc_normalize(src_verts)
            mesh = pymesh.form_mesh(src_verts, src_tris)
            mesh, _ = pymesh.split_long_edges(mesh, 0.03)
            src_verts, src_tris = mesh.vertices, mesh.faces
            ref_img = cv2.imread('%02d_ref.png' % i, cv2.IMREAD_UNCHANGED)[:,:,:3].astype(np.float32) / 255.
            # ref_img = cv2.imresize(ref_img, (137,137))
            # cv2.imwrite('%02d_ref.png' % i, (ref_img * 255).astype(np.int8))
            # print(ref_img.shape)
            # print(ref_img.shape)

            src_mesh = model.mesh_placeholder_inputs(1, src_verts.shape[0], src_tris.shape[0], (IMG_SIZE,IMG_SIZE), 'src')
            ref_mesh = model.mesh_placeholder_inputs(1, src_verts.shape[0], src_tris.shape[0], (IMG_SIZE,IMG_SIZE), 'ref')
            is_training_pl = tf.placeholder(tf.bool, shape=())

            end_points = model.get_model(src_mesh, ref_mesh, NUM_POINTS, is_training_pl)

            config = tf.ConfigProto()
            config.gpu_options.allow_growth = True
            config.allow_soft_placement = True
            config.log_device_placement = False
            sess = tf.Session(config=config)

            # Init variables
            init = tf.global_variables_initializer()
            sess.run(init)

            saver = tf.train.Saver()  
            ckptstate = tf.train.get_checkpoint_state(PRETRAINED_MODEL_PATH)
            if ckptstate is not None:
                LOAD_MODEL_FILE = os.path.join(PRETRAINED_MODEL_PATH, os.path.basename(ckptstate.model_checkpoint_path))
                saver.restore(sess, LOAD_MODEL_FILE)
                print( "Model loaded in file: %s" % LOAD_MODEL_FILE)

            else:
                print( "Fail to load modelfile: %s" % PRETRAINED_MODEL_PATH)
                return


            feed_dict = {is_training_pl: False,}
            feed_dict[src_mesh['verts']] = np.expand_dims(src_verts, axis = 0)
            feed_dict[src_mesh['nverts']] = np.expand_dims([src_verts.shape[0]], axis = 0)
            feed_dict[src_mesh['tris']] = np.expand_dims(src_tris, axis = 0)
            feed_dict[src_mesh['ntris']] = np.expand_dims([src_tris.shape[0]], axis = 0)

            feed_dict[ref_mesh['verts']] = np.expand_dims(src_verts, axis = 0) # not using
            feed_dict[ref_mesh['nverts']] = np.expand_dims([src_verts.shape[0]], axis = 0) # not using
            feed_dict[ref_mesh['tris']] = np.expand_dims(src_tris, axis = 0) # not using
            feed_dict[ref_mesh['ntris']] = np.expand_dims([src_tris.shape[0]], axis = 0) # not using
            feed_dict[ref_mesh['imgs']] = np.expand_dims(ref_img, axis = 0)

            
            pred_verts_val = sess.run(end_points['pred_verts'], feed_dict=feed_dict)
            data_off.write_off('%02d_deformed.off' % i, pred_verts_val[0,:,:], src_tris)
            tf.reset_default_graph()
Exemple #8
0
def main():
    args = parse_args()
    mesh = pymesh.load_mesh(args.input_mesh)
    out_mesh, info = pymesh.split_long_edges(mesh, args.max_edge_length)

    if mesh.has_attribute("corner_texture"):
        pymesh.map_corner_attribute(mesh, out_mesh, "corner_texture")

    pymesh.save_mesh(args.output_mesh, out_mesh, *out_mesh.attribute_names)
Exemple #9
0
def repousse(mesh, logger):
    cell_ids = mesh.get_attribute("cell").ravel().astype(int)
    mesh.add_attribute("edge_length")
    tol = np.amax(mesh.get_attribute("edge_length")) * 0.1

    bbox_min, bbox_max = mesh.bbox
    scaling = 2.0 / norm(bbox_max - bbox_min)

    start_time = time()
    num_cells = np.amax(cell_ids) + 1
    results = []
    for i in range(num_cells):
        to_keep = np.arange(mesh.num_faces, dtype=int)[cell_ids == i]
        if not np.any(to_keep):
            continue

        cut_mesh = pymesh.submesh(mesh, to_keep, 0)
        pymesh.save_mesh("debug.msh", cut_mesh)
        cut_mesh, __ = pymesh.remove_degenerated_triangles(cut_mesh, 100)
        cut_mesh, __ = pymesh.split_long_edges(cut_mesh, tol)

        dof = cut_mesh.num_vertices
        assembler = pymesh.Assembler(cut_mesh)
        L = assembler.assemble("laplacian")
        M = assembler.assemble("mass")

        L_rhs = M * np.ones(dof) * -0.5
        bd_indices = cut_mesh.boundary_vertices
        n = len(bd_indices)
        C = scipy.sparse.coo_matrix(
            (np.ones(n), (np.arange(n, dtype=int), bd_indices)),
            shape=(n, dof))
        C_rhs = np.zeros(n)

        A = scipy.sparse.bmat([[-L, C.T], [C, None]])
        rhs = np.concatenate((L_rhs.ravel(), C_rhs))

        solver = pymesh.SparseSolver.create("SparseLU")
        solver.compute(A)
        x = solver.solve(rhs)

        z = x[:dof].reshape((-1, 1))

        vertices = np.hstack((cut_mesh.vertices, z))
        out_mesh = pymesh.form_mesh(vertices, cut_mesh.faces)
        results.append(out_mesh)

    finish_time = time()
    t = finish_time - start_time
    logger.info("Repousse running time: {}".format(t))

    mesh = pymesh.merge_meshes(results)

    vertices = mesh.vertices[:, :2]
    mesh_2d = pymesh.form_mesh(vertices, mesh.faces)
    pymesh.save_mesh("out_2d.msh", mesh_2d)
    return mesh
Exemple #10
0
def main():
    args = parse_args();
    mesh = pymesh.load_mesh(args.input_mesh);
    out_mesh, info = pymesh.split_long_edges(mesh, args.max_edge_length);

    if mesh.has_attribute("corner_texture"):
        pymesh.map_corner_attribute(mesh, out_mesh, "corner_texture");

    pymesh.save_mesh(args.output_mesh, out_mesh, *out_mesh.attribute_names);
def refine_mesh(mesh, cycles, long_threshold, **kwargs):
    """
    kwargs can be: abs_threshold, rel_threshold, preserve_feature
    """
    for i in range(cycles):
        mesh, _ = pymesh.split_long_edges(mesh, long_threshold)
        mesh, _ = pymesh.collapse_short_edges(mesh, **kwargs)
        
    return mesh
Exemple #12
0
def fix_meshes(mesh, detail="normal"):
    meshCopy = mesh

    # copy/pasta of pymesh script fix_mesh from qnzhou, see pymesh on GitHub
    bbox_min, bbox_max = mesh.bbox
    diag_len = np.linalg.norm(bbox_max - bbox_min)
    if detail == "normal":
        target_len = diag_len * 5e-3
    elif detail == "high":
        target_len = diag_len * 2.5e-3
    elif detail == "low":
        target_len = diag_len * 1e-2

    count = 0
    mesh, __ = pymesh.remove_degenerated_triangles(mesh, 100)
    mesh, __ = pymesh.split_long_edges(mesh, target_len)
    num_vertices = mesh.num_vertices
    while True:
        mesh, __ = pymesh.collapse_short_edges(mesh, 1e-6)
        mesh, __ = pymesh.collapse_short_edges(mesh,
                                               target_len,
                                               preserve_feature=True)
        mesh, __ = pymesh.remove_obtuse_triangles(mesh, 150.0, 100)
        if mesh.num_vertices == num_vertices:
            break

        num_vertices = mesh.num_vertices
        count += 1
        if count > 10:
            break

    mesh = pymesh.resolve_self_intersection(mesh)
    mesh, __ = pymesh.remove_duplicated_faces(mesh)
    mesh = pymesh.compute_outer_hull(mesh)
    mesh, __ = pymesh.remove_duplicated_faces(mesh)
    mesh, __ = pymesh.remove_obtuse_triangles(mesh, 179.0, 5)
    mesh, __ = pymesh.remove_isolated_vertices(mesh)

    if is_mesh_broken(mesh, meshCopy) is True:
        if detail == "high":
            print(
                f'The function fix_meshes broke mesh, trying with lower details settings'
            )
            fix_meshes(mesh, detail="normal")
        if detail == "normal":
            print(
                f'The function fix_meshes broke mesh, trying with lower details settings'
            )
            fix_meshes(mesh, detail="low")
        if detail == "low":
            print(
                f'The function fix_meshes broke mesh, no lower settings can be applied, no fix was done'
            )
            return meshCopy
    else:
        return mesh
def link(path1):
    """
	This function takes a path to the orginal shapenet model and subsample it nicely
	"""
    obj1 = pymesh.load_mesh(path1)
    if len(obj1.vertices) < 10000:
        obj1 = pymesh.split_long_edges(obj1, 0.02)[0]
        while len(obj1.vertices) < 10000:
            obj1 = pymesh.subdivide(obj1)

    new_mesh = pymesh.form_mesh(
        normalize_points.BoundingBox(torch.from_numpy(obj1.vertices)).numpy(),
        obj1.faces)
    return new_mesh
Exemple #14
0
def fix_mesh(mesh, detail=5e-3):
    # "normal": 5e-3
    # "high":   2.5e-3
    # "low":    2e-2
    # "vlow":   2.5e-2
    bbox_min, bbox_max = mesh.bbox
    diag_len = np.linalg.norm(bbox_max - bbox_min)
    if detail is None:
        detail = 5e-3
    target_len = diag_len * detail
    print("Target resolution: {} mm".format(target_len))

    count = 0
    mesh, __ = pymesh.remove_degenerated_triangles(mesh, 100)
    mesh, __ = pymesh.split_long_edges(mesh, target_len)
    num_vertices = mesh.num_vertices
    while True:
        mesh, __ = pymesh.collapse_short_edges(mesh, 1e-4)
        mesh, __ = pymesh.collapse_short_edges(mesh,
                                               target_len,
                                               preserve_feature=True)

        mesh, __ = pymesh.remove_isolated_vertices(mesh)
        mesh, __ = pymesh.remove_duplicated_vertices(mesh, tol=1e-4)
        mesh, __ = pymesh.remove_duplicated_faces(mesh)
        mesh, __ = pymesh.remove_degenerated_triangles(mesh)
        mesh, __ = pymesh.remove_isolated_vertices(mesh)

        mesh, __ = pymesh.remove_obtuse_triangles(mesh, 150.0, 100)
        if mesh.num_vertices == num_vertices:
            break

        num_vertices = mesh.num_vertices
        print("fix #v: {}".format(num_vertices))
        count += 1
        if count > 10:
            break

    mesh = pymesh.resolve_self_intersection(mesh)
    mesh, __ = pymesh.remove_duplicated_faces(mesh)
    mesh = pymesh.compute_outer_hull(mesh)
    mesh, __ = pymesh.remove_duplicated_faces(mesh)
    mesh, __ = pymesh.remove_obtuse_triangles(mesh, 179.0, 5)
    mesh, __ = pymesh.remove_isolated_vertices(mesh)

    return mesh
Exemple #15
0
def fix_mesh(mesh, detail="normal"):

    bbox_min, bbox_max = mesh.bbox
    diag_len = norm(bbox_max - bbox_min)

    if detail == "normal":
        target_len = diag_len * 1e-2

    elif detail == "high":
        target_len = diag_len * 5e-3

    elif detail == "low":
        target_len = diag_len * 0.03

    print("Target resolution: {} mm".format(target_len))

    count = 0
    mesh, __ = pymesh.remove_degenerated_triangles(mesh, 100)
    mesh, __ = pymesh.split_long_edges(mesh, target_len)
    num_vertices = mesh.num_vertices

    while True:
        mesh, __ = pymesh.collapse_short_edges(mesh, 1e-6)
        mesh, __ = pymesh.collapse_short_edges(mesh,
                                               target_len,
                                               preserve_feature=True)
        mesh, __ = pymesh.remove_obtuse_triangles(mesh, 150.0, 100)

        if mesh.num_vertices == num_vertices:
            break

        num_vertices = mesh.num_vertices
        print("#v: {}".format(num_vertices))
        count += 1
        if count > 10:
            break

    mesh = pymesh.resolve_self_intersection(mesh)
    mesh, __ = pymesh.remove_duplicated_faces(mesh)
    mesh = pymesh.compute_outer_hull(mesh)
    mesh, __ = pymesh.remove_duplicated_faces(mesh)
    mesh, __ = pymesh.remove_obtuse_triangles(mesh, 179.0, 5)
    mesh, __ = pymesh.remove_isolated_vertices(mesh)

    return mesh
Exemple #16
0
def repousse_all(mesh, logger):
    cell_ids = mesh.get_attribute("cell").ravel().astype(int);
    mesh.add_attribute("edge_length");
    tol = np.amax(mesh.get_attribute("edge_length")) * 0.1;

    out_mesh, info = pymesh.remove_degenerated_triangles(mesh, 100);
    cell_ids = cell_ids[info["ori_face_indices"]].ravel();
    mesh, info = pymesh.split_long_edges(out_mesh, tol);
    cell_ids = cell_ids[info["ori_face_indices"]].ravel();

    mesh.enable_connectivity();
    is_border = [len(np.unique(cell_ids[mesh.get_vertex_adjacent_faces(vi)])) > 1
            for vi in range(mesh.num_vertices)];

    start_time = time();
    dof = mesh.num_vertices;
    assembler = pymesh.Assembler(mesh);
    L = assembler.assemble("laplacian");
    M = assembler.assemble("mass");

    L_rhs = M * np.ones(dof) * -1 * 1e-1;
    bd_indices = np.arange(mesh.num_vertices, dtype=int)[is_border];
    n = len(bd_indices);
    C = scipy.sparse.coo_matrix((np.ones(n),
        (np.arange(n, dtype=int), bd_indices)), shape=(n, dof));
    C_rhs = np.zeros(n);

    A = scipy.sparse.bmat([
        [-L, C.T],
        [C, None]
        ]);
    rhs = np.concatenate((L_rhs.ravel(), C_rhs));

    solver = pymesh.SparseSolver.create("SparseLU");
    solver.compute(A);
    x = solver.solve(rhs);
    z = x[:dof].reshape((-1, 1));
    vertices = np.hstack((mesh.vertices, z));

    finish_time = time();
    t = finish_time - start_time;
    logger.info("Repousse running time: {}".format(t));

    return pymesh.form_mesh(vertices, mesh.faces);
def fix_mesh(mesh, detail="normal"):
    bbox_min, bbox_max = mesh.bbox;
    diag_len = norm(bbox_max - bbox_min);
    if detail == "normal":
        target_len = diag_len * 1e-2;
        #target_len = diag_len * 5e-3;
    elif detail == "enormal":
        target_len = diag_len * 5e-3
    elif detail == "high":
        target_len = diag_len * 3e-3
        #target_len = diag_len * 2.5e-3;
    elif detail == "low":
        target_len = diag_len * 1e-2;
    elif detail == "ehigh":
        target_len = diag_len * 1e-3;
    print("Target resolution: {} mm".format(target_len));

    count = 0;
    mesh, __ = pymesh.remove_degenerated_triangles(mesh, 100);
    mesh, __ = pymesh.split_long_edges(mesh, target_len);
    num_vertices = mesh.num_vertices;
    while True:
        #mesh, __ = pymesh.collapse_short_edges(mesh, 1e-6);
        if detail == "low":
            mesh, __ = pymesh.collapse_short_edges(mesh, target_len, preserve_feature=False);
        else:
            mesh, __ = pymesh.collapse_short_edges(mesh, target_len, preserve_feature=True);
        mesh, __ = pymesh.remove_obtuse_triangles(mesh, 150.0, 100);
        if mesh.num_vertices == num_vertices:
            break;

        num_vertices = mesh.num_vertices;
        print("#v: {}".format(num_vertices));
        count += 1;
        if count > 10: break;

    mesh = pymesh.resolve_self_intersection(mesh);
    mesh, __ = pymesh.remove_duplicated_faces(mesh);
    mesh = pymesh.compute_outer_hull(mesh);
    mesh, __ = pymesh.remove_duplicated_faces(mesh);
    mesh, __ = pymesh.remove_obtuse_triangles(mesh, 179.0, 5);
    mesh, __ = pymesh.remove_isolated_vertices(mesh);

    return mesh;
Exemple #18
0
def fix_mesh(mesh, target_len):
    bbox_min, bbox_max = mesh.bbox
    diag_len = np.linalg.norm(bbox_max - bbox_min)

    count = 0
    print("  remove degenerated triangles")
    mesh, __ = pymesh.remove_degenerated_triangles(mesh, 100)
    print("  split long edges")
    mesh, __ = pymesh.split_long_edges(mesh, target_len)
    num_vertices = mesh.num_vertices
    while True:
        print("  pass %d" % count)
        print("    collapse short edges #1")
        mesh, __ = pymesh.collapse_short_edges(mesh, 1e-6)
        print("    collapse short edges #2")
        mesh, __ = pymesh.collapse_short_edges(mesh,
                                               target_len,
                                               preserve_feature=True)
        print("    remove obtuse triangles")
        mesh, __ = pymesh.remove_obtuse_triangles(mesh, 150.0, 100)
        print("    %d of %s vertices." % (num_vertices, mesh.num_vertices))

        if mesh.num_vertices == num_vertices:
            break

        num_vertices = mesh.num_vertices
        count += 1
        if count > 10: break

    print("  resolve self intersection")
    mesh = pymesh.resolve_self_intersection(mesh)
    print("  remove duplicated faces")
    mesh, __ = pymesh.remove_duplicated_faces(mesh)
    print("  computer outer hull")
    mesh = pymesh.compute_outer_hull(mesh)
    print("  remove duplicated faces")
    mesh, __ = pymesh.remove_duplicated_faces(mesh)
    print("  remove obtuse triangles")
    mesh, __ = pymesh.remove_obtuse_triangles(mesh, 179.0, 5)
    print("  remove isolated vertices")
    mesh, __ = pymesh.remove_isolated_vertices(mesh)

    return mesh
Exemple #19
0
def repousse_all(mesh, logger):
    cell_ids = mesh.get_attribute("cell").ravel().astype(int)
    mesh.add_attribute("edge_length")
    tol = np.amax(mesh.get_attribute("edge_length")) * 0.1

    out_mesh, info = pymesh.remove_degenerated_triangles(mesh, 100)
    cell_ids = cell_ids[info["ori_face_indices"]].ravel()
    mesh, info = pymesh.split_long_edges(out_mesh, tol)
    cell_ids = cell_ids[info["ori_face_indices"]].ravel()

    mesh.enable_connectivity()
    is_border = [
        len(np.unique(cell_ids[mesh.get_vertex_adjacent_faces(vi)])) > 1
        for vi in range(mesh.num_vertices)
    ]

    start_time = time()
    dof = mesh.num_vertices
    assembler = pymesh.Assembler(mesh)
    L = assembler.assemble("laplacian")
    M = assembler.assemble("mass")

    L_rhs = M * np.ones(dof) * -1 * 1e-1
    bd_indices = np.arange(mesh.num_vertices, dtype=int)[is_border]
    n = len(bd_indices)
    C = scipy.sparse.coo_matrix(
        (np.ones(n), (np.arange(n, dtype=int), bd_indices)), shape=(n, dof))
    C_rhs = np.zeros(n)

    A = scipy.sparse.bmat([[-L, C.T], [C, None]])
    rhs = np.concatenate((L_rhs.ravel(), C_rhs))

    solver = pymesh.SparseSolver.create("SparseLU")
    solver.compute(A)
    x = solver.solve(rhs)
    z = x[:dof].reshape((-1, 1))
    vertices = np.hstack((mesh.vertices, z))

    finish_time = time()
    t = finish_time - start_time
    logger.info("Repousse running time: {}".format(t))

    return pymesh.form_mesh(vertices, mesh.faces)
Exemple #20
0
    def filter(self):
        mesh = pymesh.form_mesh(self.mesh.points.values,
                                self.mesh.cells.values)

        mesh, _ = pymesh.remove_degenerated_triangles(mesh,
                                                      self.max_iterations)
        mesh, _ = pymesh.split_long_edges(mesh, self.size)
        num_vertices = mesh.num_vertices
        for _ in range(self.max_iterations):
            mesh, _ = pymesh.collapse_short_edges(mesh,
                                                  self.size,
                                                  preserve_feature=True)
            mesh, _ = pymesh.remove_obtuse_triangles(mesh, self.max_angle,
                                                     self.max_iterations)

            if mesh.num_vertices == num_vertices:
                break

            num_vertices = mesh.num_vertices

        return self.mesh.mesh_class()(mesh, parents=[self.mesh])
def fix_mesh(mesh, target_len):
    bbox_min, bbox_max = mesh.bbox
    diag_len = np.linalg.norm(bbox_max - bbox_min)

    print("running downsample mesh to len %.3f" % target_len)
    count = 0
    mesh, __ = pymesh.split_long_edges(mesh, target_len)
    num_vertices = mesh.num_vertices
    while True:
        mesh, __ = pymesh.collapse_short_edges(mesh, 1e-6)
        mesh, __ = pymesh.collapse_short_edges(mesh,
                                               target_len,
                                               preserve_feature=True)

        if mesh.num_vertices == num_vertices:
            break

        num_vertices = mesh.num_vertices
        count += 1
        if count > 10: break

    return mesh
Exemple #22
0
    def __fix_mesh(self, mesh, improvement_thres=0.8):
        mesh, __ = pymesh.split_long_edges(mesh, self.mesh_target_len)
        num_vertices = len(mesh.vertices)

        for __ in range(10):
            mesh, __ = pymesh.collapse_short_edges(mesh, 1e-6)
            mesh, __ = pymesh.collapse_short_edges(
                mesh, self.mesh_target_len, preserve_feature=True
            )
            mesh, __ = pymesh.remove_obtuse_triangles(mesh, 150.0, 100)

            if len(mesh.vertices) < num_vertices * improvement_thres:
                break

        mesh = pymesh.resolve_self_intersection(mesh)
        mesh, __ = pymesh.collapse_short_edges(mesh, 1e-6)
        mesh, __ = pymesh.remove_duplicated_faces(mesh)
        mesh, __ = pymesh.remove_duplicated_faces(mesh)
        mesh, __ = pymesh.remove_obtuse_triangles(mesh, 179.0, 5)
        mesh, __ = pymesh.remove_isolated_vertices(mesh)

        return mesh
Exemple #23
0
def old_fix_mesh(vertices, faces, detail="normal"):
    bbox_min = np.amin(vertices, axis=0)
    bbox_max = np.amax(vertices, axis=0)
    diag_len = norm(bbox_max - bbox_min)
    if detail == "normal":
        target_len = diag_len * 5e-3
    elif detail == "high":
        target_len = diag_len * 2.5e-3
    elif detail == "low":
        target_len = diag_len * 1e-2
    print("Target resolution: {} mm".format(target_len))

    count = 0
    vertices, faces = pymesh.split_long_edges(vertices, faces, target_len)
    num_vertices = len(vertices)
    while True:
        vertices, faces = pymesh.collapse_short_edges(vertices, faces, 1e-6)
        vertices, faces = pymesh.collapse_short_edges(vertices,
                                                      faces,
                                                      target_len,
                                                      preserve_feature=True)
        vertices, faces = pymesh.remove_obtuse_triangles(
            vertices, faces, 150.0, 100)
        if num_vertices == len(vertices):
            break
        num_vertices = len(vertices)
        print("#v: {}".format(num_vertices))
        count += 1
        if count > 10: break

    vertices, faces = pymesh.resolve_self_intersection(vertices, faces)
    vertices, faces = pymesh.remove_duplicated_faces(vertices, faces)
    vertices, faces, _ = pymesh.compute_outer_hull(vertices, faces, False)
    vertices, faces = pymesh.remove_duplicated_faces(vertices, faces)
    vertices, faces = pymesh.remove_obtuse_triangles(vertices, faces, 179.0, 5)
    vertices, faces, voxels = pymesh.remove_isolated_vertices(vertices, faces)
    return vertices, faces
Exemple #24
0
def fix_mesh(mesh, detail="normal"):
    bbox_min, bbox_max = mesh.bbox;
    diag_len = norm(bbox_max - bbox_min);
    if detail == "normal":
        target_len = diag_len * 5e-3;
    elif detail == "high":
        target_len = diag_len * 2.5e-3;
    elif detail == "low":
        target_len = diag_len * 1e-2;
    print("Target resolution: {} mm".format(target_len));

    count = 0;
    mesh, __ = pymesh.remove_degenerated_triangles(mesh, 100);
    mesh, __ = pymesh.split_long_edges(mesh, target_len);
    num_vertices = mesh.num_vertices;
    while True:
        mesh, __ = pymesh.collapse_short_edges(mesh, 1e-6);
        mesh, __ = pymesh.collapse_short_edges(mesh, target_len,
                preserve_feature=True);
        mesh, __ = pymesh.remove_obtuse_triangles(mesh, 150.0, 100);
        if mesh.num_vertices == num_vertices:
            break;

        num_vertices = mesh.num_vertices;
        print("#v: {}".format(num_vertices));
        count += 1;
        if count > 10: break;

    mesh = pymesh.resolve_self_intersection(mesh);
    mesh, __ = pymesh.remove_duplicated_faces(mesh);
    mesh = pymesh.compute_outer_hull(mesh);
    mesh, __ = pymesh.remove_duplicated_faces(mesh);
    mesh, __ = pymesh.remove_obtuse_triangles(mesh, 179.0, 5);
    mesh, __ = pymesh.remove_isolated_vertices(mesh);

    return mesh;
Exemple #25
0
def uniformize(input):
    input = pymesh.form_mesh(input.vertices, input.faces)
    input, _ = pymesh.split_long_edges(input, 0.005)
    return input
import pymesh
print(sys.argv)

polyfile = sys.argv[1]
meshfile = sys.argv[2]
trilineleng = float(sys.argv[3])
trilineshortleng = float(sys.argv[4])

x = json.loads(open(polyfile).readline())
vertices = numpy.array(x[0])
faces = numpy.array(x[1])
mesh = pymesh.form_mesh(vertices, faces)

#mesh, info = pymesh.remove_degenerated_triangles(mesh, 100)
preserve_feature = False  # see https://github.com/PyMesh/PyMesh/issues/289
mesh, info = pymesh.split_long_edges(mesh, trilineleng)
mesh, info = pymesh.collapse_short_edges(mesh,
                                         trilineshortleng,
                                         preserve_feature=preserve_feature)
mesh, info = pymesh.split_long_edges(mesh, trilineleng)
mesh, info = pymesh.collapse_short_edges(mesh,
                                         trilineshortleng,
                                         preserve_feature=preserve_feature)

#print(info)

fout = open("temp.txt", "w")
print("writing %d verts and %d faces" % (len(mesh.vertices), len(mesh.faces)))
fout.write(json.dumps([mesh.vertices.tolist(), mesh.faces.flatten().tolist()]))
fout.close()
shutil.move("temp.txt", meshfile)
Exemple #27
0
def user_approves_surface(perch_region, full_mesh, full_mesh_path, R, g=np.array([0, 0, -1]), env_path=None):
    #  Find Oriented Bounding Box for surface
    global approved

    # load mesh in open3d
    mesh = trimesh.load('/home/simon/catkin_ws/src/mesh_partition/datasets/apartment_1m.ply')
    R_aug = np.zeros([4, 4])
    R_aug[:3, :3] = R
    mesh.vertices = trimesh.transform_points(mesh.vertices, R_aug)

    # Crop the mesh using face color
    f_colors = np.asarray(mesh.visual.face_colors)
    f_colors = f_colors / 255.0
    # add opacity
    f_colors[:, 3] = 1.0

    # vedo_mesh = vedo.mesh.Mesh(mesh)
    # vedo_mesh.cellIndividualColors(f_colors, alphaPerCell=True)
    # vedo_mesh.frontFaceCulling()
    # plt1.clear()
    # plt1.add(vedo_mesh)
    # plt1.add(vedo.Text2D("Press 'y' to approve surface. Press 'n' to reject. "
    #                      "\nPress 'f' for front culling, 'b' for back culling, 'c' to disable culling "
    #                      "\nPress 'q' when done",
    #                      pos='bottom-right', c='dg', bg='g', font='Godsway'))

    pvm = pv.PolyData('/home/simon/catkin_ws/src/mesh_partition/datasets/apartment_1m.ply')
    n = perch_region.mesh_normal
    pm = pymesh.form_mesh(perch_region.points + n*0.1, perch_region.faces)
    pms, _ = pymesh.split_long_edges(pm, 0.1)
    pm2 = pymesh.form_mesh(perch_region.points - n*0.1, perch_region.faces)
    pms2, _ = pymesh.split_long_edges(pm2, 0.1)
    #
    # surf_colors = np.zeros([len(pms.faces), 4])
    # surf_colors[:, 1] = 0.5  # g
    # surf_colors[:, 3] = 1.0  # alpha
    surf_mesh = pv.PolyData(pms.vertices, np.hstack([np.ones([len(pms.faces), 1])*3, pms.faces]).astype(int))
    surf_mesh2 = pv.PolyData(pms2.vertices, np.hstack([np.ones([len(pms2.faces), 1])*3, pms2.faces]).astype(int))

    # p.add_mesh(surf_mesh, scalars=surf_colors, rgb=True, name="surf_mesh")
    p.add_mesh(surf_mesh, color='g', opacity=.50, name="surf_mesh", culling=False)
    p.add_mesh(surf_mesh2, color='g', opacity=.50, name="surf_mesh2", culling=False)

    p.add_mesh(pvm, scalars=f_colors, rgb=True, name="env_mesh", culling=False)  # f_colors[:,:3])

    p.enable_cell_picking(mesh=surf_mesh, style='wireframe', color='r', through=True,
                          show_message="")
    p.add_text(text="Press R to toggle selection tool\n"
                                       "Press D to remove selected region\n"
                                       "Press A to keep only the selected region\n"
                                       "Press Y to approve region\n"
                                       "Press N to reject region\n"
                                       "Press Q to confirm selection\n",
               color='k', font_size=18)

    p.add_key_event(key='d', callback=pyvista_remove_region)
    p.add_key_event(key='a', callback=pyvista_select_region)
    p.add_key_event(key='y', callback=pyvista_approve_region)
    p.add_key_event(key='n', callback=pyvista_reject_region)

    # pvm.plot(scalars=f_colors, rgb=True)

    p.show(auto_close=True, interactive=True, full_screen=True)

    # plt1.show()
    p.deep_clean()
    p.clear()
    p.close()

    return approved, selection
Exemple #28
0
    def __getitem__(self, index):
        if index in self.cache:
            verts, tris, textures, surfacebinvoxpc, solidbinvoxpc = self.cache[index]
        else:
            try:
                h5_f = h5py.File(self.datapath[index])
                if (self.maxnverts != -1 and h5_f['verts'].shape[0] > self.maxnverts) or (self.maxntris != -1 and h5_f['tris'].shape[0] > self.maxntris):
                    h5_f.close()
                    raise Exception()
                if self.load_surfacebinvox != 0 and ('surfacebinvoxsparse' not in h5_f.keys()):
                    raise Exception()

                verts, tris = h5_f['verts'][:], h5_f['tris'][:]
            except:
                self.cache[index] = None
                return None


            if self.texture != 0:
                textures = h5_f['textures'][:]
            else:
                textures = None

            if self.load_surfacebinvox != 0:
                surfacebinvoxpc = h5_f['surfacebinvoxsparse'][:].T
            else:
                surfacebinvoxpc = None

            if self.load_solidbinvox != 0:
                solidbinvoxpc = h5_f['binvoxsolid'][:].T
            else:
                solidbinvoxpc = None

            if self.normalize:
                centroid = None

                if self.load_solidbinvox != 0:
                    solidbinvoxpc, centroid = self.pc_normalize(solidbinvoxpc)

                if self.load_surfacebinvox != 0:
                    surfacebinvoxpc, centroid = self.pc_normalize(surfacebinvoxpc)

                verts, _ = self.pc_normalize(verts, centroid)

            if self.test:
                mesh = pymesh.form_mesh(verts, tris)
                mesh, _ = pymesh.split_long_edges(mesh, 0.05)
                verts, tris = mesh.vertices, mesh.faces
                if (self.maxnverts != -1 and verts.shape[0] > self.maxnverts) or (self.maxntris != -1 and tris.shape[0] > self.maxntris):
                    return None

            if self.subsamplemesh:
                mesh = pymesh.form_mesh(verts, tris)
                mesh, _ = pymesh.split_long_edges(mesh, 0.05)
                verts, tris = mesh.vertices, mesh.faces
                if (self.maxnverts != -1 and verts.shape[0] > self.maxnverts) or (self.maxntris != -1 and tris.shape[0] > self.maxntris):
                    return None

            if len(self.cache) < self.cache_size:
                self.cache[index] = (verts, tris, textures, surfacebinvoxpc, solidbinvoxpc)
            h5_f.close()

        return verts, tris, textures, surfacebinvoxpc, solidbinvoxpc
def regularise_mesh(mesh, tol):
    """Takes mesh & resizes triangles to tol size"""
    mesh, __ = pymesh.remove_degenerated_triangles(mesh, 100)
    mesh, _info = pymesh.split_long_edges(mesh, tol)
    mesh, __ = pymesh.collapse_short_edges(mesh, 1e-6)
    mesh, _info = pymesh.collapse_short_edges(mesh, tol, preserve_feature=True)
Exemple #30
0
def fix_meshes(mesh, detail="normal"):
    """
    A pipeline to optimise and fix mesh based on pymesh Mesh object.

    1. A box is created around the mesh.
    2. A target length is found based on diagonal of the mesh box.
    3. You can choose between 3 level of details, normal details settings seems to be a good compromise between
    final mesh size and sufficient number of vertices. It highly depends on your final goal.
    4. Remove degenerated triangles aka collinear triangles composed of 3 aligned points. The number of iterations is 5
    and should remove all degenerated triangles
    5. Remove isolated vertices, not connected to any faces or edges
    6. Remove self intersection edges and faces which is not realistic
    7. Remove duplicated faces
    8. The removing of duplicated faces can leave some vertices alone, we will removed them
    9. The calculation of outer hull volume is useful to be sure that the mesh is still ok
    10. Remove obtuse triangles > 179 who is not realistic and increase computation time
    11. We will remove potential duplicated faces again
    12. And duplicated vertices again
    13. Finally we will look if the mesh is broken or not. If yes we will try lower settings, if the lowest settings
    broke the mesh we will return the initial mesh. If not, we will return the optimised mesh.

    :param mesh: Pymesh Mesh object to optimise
    :param detail: string 'high', 'normal' or 'low' ('normal' as default), or float/int
    Settings to choose the targeting minimum length of edges
    :return: Pymesh Mesh object
    An optimised mesh or not depending on detail settings and mesh quality
    """
    meshCopy = mesh

    # copy/pasta of pymesh script fix_mesh from qnzhou, see pymesh on GitHub
    bbox_min, bbox_max = mesh.bbox
    diag_len = np.linalg.norm(bbox_max - bbox_min)
    if detail == "normal":
        target_len = diag_len * 5e-3
    elif detail == "high":
        target_len = diag_len * 2.5e-3
    elif detail == "low":
        target_len = diag_len * 1e-2
    elif detail is float or detail is int and detail > 0:
        target_len = diag_len * detail
    else:
        print(
            'Details settings is invalid, must be "low", "normal", "high" or positive int or float'
        )
        quit()

    count = 0
    mesh, __ = pymesh.remove_degenerated_triangles(mesh, 5)
    mesh, __ = pymesh.split_long_edges(mesh, target_len)
    num_vertices = mesh.num_vertices
    while True:
        mesh, __ = pymesh.collapse_short_edges(mesh,
                                               target_len,
                                               preserve_feature=True)
        mesh, info = pymesh.remove_obtuse_triangles(mesh, 179.0, 5)
        if mesh.num_vertices == num_vertices:
            break

        num_vertices = mesh.num_vertices
        count += 1
        if count > 10:
            break

    mesh, __ = pymesh.remove_duplicated_vertices(mesh)
    mesh, __ = pymesh.remove_isolated_vertices(mesh)
    mesh = pymesh.resolve_self_intersection(mesh)
    mesh, __ = pymesh.remove_duplicated_faces(mesh)
    mesh, __ = pymesh.remove_duplicated_vertices(mesh)
    mesh = pymesh.compute_outer_hull(mesh)
    mesh, __ = pymesh.remove_obtuse_triangles(mesh, 179.0, 5)
    mesh, __ = pymesh.remove_duplicated_faces(mesh)
    mesh, __ = pymesh.remove_isolated_vertices(mesh)

    if is_mesh_broken(mesh, meshCopy) is True:
        if detail == "high":
            print(
                f'The function fix_meshes broke mesh, trying with lower details settings'
            )
            fix_meshes(meshCopy, detail="normal")
            return mesh
        if detail == "normal":
            print(
                f'The function fix_meshes broke mesh, trying with lower details settings'
            )
            mesh = fix_meshes(meshCopy, detail="low")
            return mesh
        if detail == "low":
            print(
                f'The function fix_meshes broke mesh, no lower settings can be applied, no fix was done'
            )
            return meshCopy
    else:
        return mesh