Example #1
0
def clean_mesh(mesh, connected=True, fill_internals=False):
    print('\t - Cleaning mesh (this may take a moment)')
    vert_list = []
    mesh, info = pymesh.remove_isolated_vertices(mesh)
    mesh, info = pymesh.remove_duplicated_vertices(mesh)
    mesh, info = pymesh.remove_degenerated_triangles(mesh)
    mesh, info = pymesh.remove_duplicated_faces(mesh)

    if connected or fill_internals:
        mesh_list = pymesh.separate_mesh(mesh, 'auto')
        max_verts = 0
        print(' - Total number of meshes (ideally 1): %d' % len(mesh_list))
        for mesh_obj in mesh_list:
            nverts = mesh_obj.num_vertices
            if nverts > max_verts:
                max_verts = nverts
                mesh = mesh_obj

        if fill_internals:
            for mesh_obj in mesh_list:
                if mesh_obj.num_vertices != max_verts:
                    vert_list.append(mesh_obj.vertices)

            return mesh, vert_list

    return mesh, vert_list
Example #2
0
def main():
    args = parse_args()

    mesh = load_mesh(args.mesh_in)
    comps = separate_mesh(mesh, args.connectivity_type)

    if args.highlight:
        if (args.connectivity_type == "face"):
            comp_indicator = np.zeros(mesh.num_faces)
        elif (args.connectivity_type == "voxel"):
            comp_indicator = np.zeros(mesh.num_voxels)
        elif (mesh.num_voxels > 0):
            comp_indicator = np.zeros(mesh.num_voxels)
        else:
            comp_indicator = np.zeros(mesh.num_faces)

        for i in range(len(comps)):
            elem_sources = comps[i].get_attribute("ori_elem_index")\
                    .ravel().astype(int)
            comp_indicator[elem_sources] = i
        mesh.add_attribute("component_index")
        mesh.set_attribute("component_index", comp_indicator)
        save_mesh(args.mesh_out, mesh, *mesh.get_attribute_names())
    else:
        basename, ext = os.path.splitext(args.mesh_out)
        for i, comp in enumerate(comps):
            filename = "{}_cc{}{}".format(basename, i, ext)
            save_mesh(filename, comp, *comp.get_attribute_names())
Example #3
0
def main():
    args = parse_args();

    mesh = load_mesh(args.mesh_in);
    comps = separate_mesh(mesh, args.connectivity_type);

    if args.highlight:
        if (args.connectivity_type == "face"):
            comp_indicator = np.zeros(mesh.num_faces);
        elif (args.connectivity_type == "voxel"):
            comp_indicator = np.zeros(mesh.num_voxels);
        elif (mesh.num_voxels > 0):
            comp_indicator = np.zeros(mesh.num_voxels);
        else:
            comp_indicator = np.zeros(mesh.num_faces);

        for i in range(len(comps)):
            elem_sources = comps[i].get_attribute("ori_elem_index")\
                    .ravel().astype(int);
            comp_indicator[elem_sources] = i;
        mesh.add_attribute("component_index");
        mesh.set_attribute("component_index", comp_indicator);
        save_mesh(args.mesh_out, mesh, *mesh.get_attribute_names());
    else:
        basename, ext = os.path.splitext(args.mesh_out);
        for i,comp in enumerate(comps):
            filename = "{}_cc{}{}".format(basename, i, ext);
            save_mesh(filename, comp, *comp.get_attribute_names());
Example #4
0
def separate_single_mesh(src_mesh, tar_mesh):
    src_mesh = pymesh.load_mesh(src_mesh)
    dis_meshes = pymesh.separate_mesh(src_mesh, connectivity_type='auto')
    pymesh.save_mesh_raw(tar_mesh+".obj", src_mesh.vertices, src_mesh.faces)
    count=0
    for dis_mesh in dis_meshes:
        print("dis_mesh.vertices.shape",dis_mesh.vertices.shape)
        print("dis_mesh.faces.shape",dis_mesh.faces.shape)
        pymesh.save_mesh_raw(tar_mesh+"_"+str(count)+".obj", dis_mesh.vertices, dis_mesh.faces)
        count+=1
    def test_simple(self):
        mesh_1 = generate_box_mesh(np.zeros(3), np.ones(3));
        mesh_2 = generate_box_mesh(np.array([0.5, 0.5, 0.5]), np.ones(3));
        out_mesh = merge_meshes([mesh_1, mesh_2]);

        components = separate_mesh(out_mesh);
        self.assertEqual(2, len(components));

        for comp in components:
            self.assertEqual(8, comp.num_vertices);
            self.assertEqual(12, comp.num_faces);
    def test_face_connectivity(self):
        vertices = np.array([
            [0, 0, 0],
            [1, 0, 0],
            [0, 1, 0],
            [0, 0, 1],
            [1, 1, 1],
            ], dtype=float);

        faces = np.array([
            [0, 1, 2],
            [2, 3, 4],
            ]);

        mesh = form_mesh(vertices, faces);
        components = separate_mesh(mesh, "vertex");
        self.assertEqual(1, len(components));

        components = separate_mesh(mesh, "face");
        self.assertEqual(2, len(components));
Example #7
0
def clean_single_mesh(src_mesh, tar_mesh, dist_thresh, num_thresh):
    src_mesh_obj = pymesh.load_mesh(src_mesh)
    dis_meshes = pymesh.separate_mesh(src_mesh_obj, connectivity_type='auto')
    max_mesh_verts = 0
    for dis_mesh in dis_meshes:
       if dis_mesh.vertices.shape[0] > max_mesh_verts:
           max_mesh_verts = dis_mesh.vertices.shape[0]

    collection=[]
    for dis_mesh in dis_meshes:
       if dis_mesh.vertices.shape[0] > max_mesh_verts*num_thresh:
           centroid = np.mean(dis_mesh.vertices, axis=0)
           if np.sqrt(np.sum(np.square(centroid))) < dist_thresh:
            collection.append(dis_mesh)
    tar_mesh_obj = pymesh.merge_meshes(collection)
    pymesh.save_mesh_raw(tar_mesh, tar_mesh_obj.vertices, tar_mesh_obj.faces)
    print("threshes:", str(dist_thresh), str(num_thresh), " clean: ", src_mesh, " create: ",tar_mesh)
Example #8
0
def separate(vertex, faces, d_max=2):
    new_faces = list()
    for face in faces:
        p1 = vertex[face[0]]
        p2 = vertex[face[1]]
        p3 = vertex[face[2]]
        if not (distance(p1, p2) > d_max or distance(p2, p3) > d_max
                or distance(p1, p3) > d_max):
            new_faces.append(face)

    mesh = form_mesh(np.array(vertex), np.array(new_faces))
    meshs = separate_mesh(mesh)
    max_v = 0
    for i in range(len(meshs)):
        if meshs[i].num_vertices > max_v:
            max_v = meshs[i].num_vertices
            mesh = meshs[i]

    pcloud_2d = cloud2D(mesh.vertices)
    face = Delaunay(pcloud_2d)
    face = [(p[0], p[1], p[2]) for p in face.simplices]

    return parseToList(mesh.vertices), face
Example #9
0
def slice(the_mesh, step=1.0, epsilon=0.001):
    n = math.ceil((the_mesh.bbox[1][2] - the_mesh.bbox[0][2]) / step)
    print("slicing into %d slices" % (n))
    return [[Contour(component) for component in pymesh.separate_mesh(slice)]
            for slice in pymesh.slice_mesh(the_mesh, numpy.array([0, 0, 1]), n)
            ]
Example #10
0
    def __init__(self, path, backplate_thickness=6.35):
        self.path = path
        self.reference_mesh = pymesh.load_mesh(path)

        # we want to separate the submeshes based on face connectivity,
        # since that will give us all the discrete parts
        self.submeshes = pymesh.separate_mesh(
            self.reference_mesh, connectivity_type="face")

        # get all the pattern meshes, which are the submeshes that are
        # NOT the: backplate, pattern plate, or fiducial tag locations
        self.backplate_thickness = backplate_thickness
        self.pattern_plate_thickness = 3
        self.pattern_meshes = []
        self.fiducial_meshes = []
        self.backplate_mesh = None
        self.pattern_plate_mesh = None

        for submesh in self.submeshes:
            if not submesh.is_closed():
                # these are the fiducial marker locations
                # because they are the ones that are 1-dimensional
                self.fiducial_meshes.append(submesh)
            elif (submesh.bbox[0][2] == 0 and
                  submesh.bbox[1][2] == self.backplate_thickness) or \
                    (submesh.bbox[1][2] == 0 and
                     submesh.bbox[0][2] == self.backplate_thickness):
                # this is the backplate, since the bounding box extends to 0
                self.backplate_mesh = submesh
            elif (submesh.bbox[0][2] ==
                  self.backplate_thickness + self.pattern_plate_thickness and
                  submesh.bbox[1][2] == self.backplate_thickness) or \
                    (submesh.bbox[1][2] ==
                     self.backplate_thickness + self.pattern_plate_thickness and
                     submesh.bbox[0][2] == self.backplate_thickness):
                # this is the pattern plate, since the bounding box starts
                # from the end of the backplate and goes the thickness of
                # the pattern plate
                self.pattern_plate_mesh = submesh
            else:
                self.pattern_meshes.append(submesh)

        # the fiducial locations on the reference mesh
        # TODO: generate these automatically from the meshes
        self.fiducial_locations = {
            # top left
            231: {
                TOP_LEFT: [-75.5625, 48.575, self.backplate_thickness],
                TOP_RIGHT: [-55.5625, 48.575, self.backplate_thickness],
                BOTTOM_RIGHT: [-55.5625, 28.575, self.backplate_thickness],
                BOTTOM_LEFT: [-75.5625, 28.575, self.backplate_thickness],
            },
            # top right
            123: {
                TOP_LEFT: [55.5625, 48.575, self.backplate_thickness],
                TOP_RIGHT: [75.5625, 48.575, self.backplate_thickness],
                BOTTOM_RIGHT: [75.5625, 28.575, self.backplate_thickness],
                BOTTOM_LEFT: [55.5625, 28.575, self.backplate_thickness],
            },
            # bottom left
            114: {
                TOP_LEFT: [-75.5625, -28.575, self.backplate_thickness],
                TOP_RIGHT: [-55.5625, -28.575, self.backplate_thickness],
                BOTTOM_RIGHT: [-55.5625, -48.575, self.backplate_thickness],
                BOTTOM_LEFT: [-75.5625, -48.575, self.backplate_thickness],
            },
            # bottom right
            141: {
                TOP_LEFT: [55.5625, -28.575, self.backplate_thickness],
                TOP_RIGHT: [75.5625, -28.575, self.backplate_thickness],
                BOTTOM_RIGHT: [75.5625, -48.575, self.backplate_thickness],
                BOTTOM_LEFT: [55.5625, -48.575, self.backplate_thickness],
            }
        }
Example #11
0
 def components(self):
     comps = pm.separate_mesh(self.mesh)
     return [Topex(c) for c in comps]
Example #12
0
def main():
    args = parse_args()
    mesh = pymesh.load_mesh(args.input_mesh)
    if not mesh.has_attribute("corner_texture"):
        raise RuntimeError("Mesh contains no uv!")
    mesh.add_attribute("face_area")

    uv = mesh.get_attribute("corner_texture").reshape((-1, 2))
    if len(uv) == 0:
        raise RuntimeError("Invalid uv size.")

    faces = np.arange(mesh.num_faces * mesh.vertex_per_face).reshape(
        (-1, mesh.vertex_per_face))
    uv_mesh = pymesh.form_mesh(uv, faces)
    uv_mesh.add_attribute("face_area")

    ori_area = mesh.get_face_attribute("face_area")
    uv_area = uv_mesh.get_face_attribute("face_area")
    area_ratio = np.divide(uv_area, ori_area)

    uv_mesh.add_attribute("area_ratio")
    uv_mesh.set_attribute("area_ratio", area_ratio)
    mesh.add_attribute("area_ratio")
    mesh.set_attribute("area_ratio", area_ratio)
    mesh.add_attribute("u")
    mesh.set_attribute("u", uv[:, 0])

    if (args.separate):
        uv_mesh, info = pymesh.remove_duplicated_vertices(uv_mesh)
        comps = pymesh.separate_mesh(uv_mesh)
        segments = []
        uv = uv.reshape((-1, 6), order="C")
        vertices = mesh.vertices
        combined_uv = []
        for comp in comps:
            ori_vertex_indices = comp.get_attribute(
                "ori_vertex_index").ravel()
            ori_elem_indices = comp.get_attribute(
                "ori_elem_index").ravel().astype(int)

            segment = pymesh.submesh(mesh, ori_elem_indices, 0)
            ori_face_indices = segment.get_attribute(
                "ori_face_index").ravel().astype(int)
            ori_uv = uv[ori_face_indices]
            combined_uv.append(ori_uv)
            segment.add_attribute("corner_texture")
            segment.set_attribute("corner_texture", ori_uv.ravel())
            segments.append(segment)

        combined_uv = np.vstack(combined_uv)
        mesh = pymesh.merge_meshes(segments)
        mesh.add_attribute("corner_texture")
        mesh.set_attribute("corner_texture", combined_uv.ravel(order="C"))
    elif args.cut:
        uv_mesh, info = pymesh.remove_duplicated_vertices(uv_mesh)
        index_map = info["index_map"]
        vertices = mesh.vertices
        faces = mesh.faces
        vertices = vertices[faces.ravel(order="C")]
        new_vertices = np.zeros((uv_mesh.num_vertices, 3))
        new_vertices[index_map] = vertices

        mesh = pymesh.form_mesh(new_vertices, uv_mesh.faces)
        mesh.add_attribute("corner_texture")
        mesh.set_attribute("corner_texture", uv)

    if args.save_uv:
        pymesh.save_mesh(args.output_mesh, uv_mesh, *uv_mesh.attribute_names)
    else:
        pymesh.save_mesh(args.output_mesh, mesh, *mesh.attribute_names)