def example_import_mesh_from_arrays():
    # lines needed to run this specific example
    print('\n')
    from . import samples_common
    output_path = samples_common.test_output_path()

    # create a numpy 8x3 array of vertices
    # columns are the coordinates (x, y, z)
    # every row represents a vertex
    verts = numpy.array([[-0.5, -0.5, -0.5], [0.5, -0.5, -0.5],
                         [-0.5, 0.5, -0.5], [0.5, 0.5, -0.5],
                         [-0.5, -0.5, 0.5], [0.5, -0.5, 0.5], [-0.5, 0.5, 0.5],
                         [0.5, 0.5, 0.5]])

    # create a numpy 12x3 array of faces
    # every row represents a face (trianlge in this case)
    # for every triangle, the index of the vertex
    # in the vertex array
    faces = numpy.array([[2, 1, 0], [1, 2, 3], [4, 2, 0], [2, 4, 6], [1, 4, 0],
                         [4, 1, 5], [6, 5, 7], [5, 6, 4], [3, 6, 7], [6, 3, 2],
                         [5, 3, 7], [3, 5, 1]])

    # create a new Mesh with the two arrays
    m = pymeshlab.Mesh(verts, faces)

    assert m.vertex_number() == 8
    assert m.face_number() == 12

    # create a new MeshSet
    ms = pymeshlab.MeshSet()

    # add the mesh to the MeshSet
    ms.add_mesh(m, "cube_mesh")

    # save the current mesh
    ms.save_current_mesh(output_path + "saved_cube_from_array.ply")

    # create a 1D numpy array of 8 elements to store per vertex quality
    vert_quality = numpy.array([1, 2, 3, 4, 5, 6, 7, 8])

    # create a 1D numpy array of 12 elements to store per face quality
    face_quality = numpy.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])

    # create a new mesh with the selected arrays
    m1 = pymeshlab.Mesh(vertex_matrix=verts,
                        face_matrix=faces,
                        v_quality_array=vert_quality,
                        f_quality_array=face_quality)

    # add the mesh to the MeshSet
    ms.add_mesh(m1, "cube_quality_mesh")

    # colorize the cube according to the per face and per vertex quality
    ms.colorize_by_vertex_quality()
    ms.colorize_by_face_quality()

    # save the mesh
    ms.save_current_mesh(output_path + "colored_cube_from_array.ply")
Exemple #2
0
    def __init__(self,
                 point_cloud_file="",
                 output_file="",
                 filter_script_file="",
                 clean_up=True):
        self.mesh_set = pymeshlab.MeshSet()
        self.point_cloud = pymeshlab.Mesh()
        self.mesh = pymeshlab.Mesh()

        super().__init__(point_cloud_file, output_file, filter_script_file,
                         clean_up)
def example_import_mesh_from_arrays():
    # lines needed to run this specific example
    print('\n')
    from . import samples_common
    output_path = samples_common.test_output_path()

    # create a numpy 8x3 array of vertices
    # columns are the coordinates (x, y, z)
    # every row represents a vertex
    verts = numpy.array([
        [-0.5, -0.5, -0.5],
        [0.5, -0.5, -0.5],
        [-0.5, 0.5, -0.5],
        [0.5, 0.5, -0.5],
        [-0.5, -0.5, 0.5],
        [0.5, -0.5, 0.5],
        [-0.5, 0.5, 0.5],
        [0.5, 0.5, 0.5]])

    # create a numpy 12x3 array of faces
    # every row represents a face (trianlge in this case)
    # for every triangle, the index of the vertex
    # in the vertex array
    faces = numpy.array([
        [2, 1, 0],
        [1, 2, 3],
        [4, 2, 0],
        [2, 4, 6],
        [1, 4, 0],
        [4, 1, 5],
        [6, 5, 7],
        [5, 6, 4],
        [3, 6, 7],
        [6, 3, 2],
        [5, 3, 7],
        [3, 5, 1]])

    # create a new Mesh with the two arrays
    m = pymeshlab.Mesh(verts, faces)

    assert m.vertex_number() == 8
    assert m.face_number() == 12

    # create a new MeshSet
    ms = pymeshlab.MeshSet()

    # add the mesh to the MeshSet
    ms.add_mesh(m, "cube_mesh")

    # save the current mesh
    ms.save_current_mesh(output_path + "saved_cube_from_array.ply")
Exemple #4
0
def exportMeshToMeshLab(blenderMesh):
    # NB pymeshlab is fussy
    # verts and faces have to be provided in a numpy array with verts as type float64 and faces as int32
    # faces have to be triangulated - quads and ngons are not allowed

    verts = []  #numpyp.empty((0,3), float64)
    for v in blenderMesh.vertices:
        verts.append([v.co[0], v.co[1], v.co[2]])
    verts = numpy.asarray(verts, dtype=numpy.float64)
    if len(verts) == 0:
        print("No vertices were found, so function aborting")
        return


#    print(verts.shape)   # must report (numOfVerts, 3)
#    print(verts.dtype.name)   # must report float64

    faces = []
    tooManyVerts = False
    for poly in blenderMesh.polygons:
        curFace = []
        for loop_index in range(poly.loop_start,
                                poly.loop_start + poly.loop_total):
            curFace.append(blenderMesh.loops[loop_index].vertex_index)
        if len(curFace) == 3:
            faces.append(curFace)
        else:
            tooManyVerts = True

    if tooManyVerts:
        print("WARNING: Meshlab will only accept faces with THREE vertices")
    if len(faces) == 0:
        print("No triangular faces were found, so function aborting")
        return
    faces = numpy.asarray(faces, dtype=numpy.int32)
    #    print(faces.shape)   # must report (numOfVerts, 3)
    #    print(faces.dtype.name)

    # create a new Mesh with the two arrays
    meshlabMesh = pymeshlab.Mesh(verts, faces)

    # create a new MeshSet (a meshset can have multiple meshes each in a differnt layer - but that's not covered with this function)
    meshlabMeshSet = pymeshlab.MeshSet()

    # add the mesh to the MeshSet with the current name
    meshlabMeshSet.add_mesh(meshlabMesh, blenderMesh.name)

    return meshlabMeshSet
def example_import_poly_mesh_from_arrays():
    # lines needed to run this specific example
    print('\n')
    from . import samples_common
    output_path = samples_common.test_output_path()

    # create a numpy 8x3 array of vertices
    # columns are the coordinates (x, y, z)
    # every row represents a vertex
    verts = numpy.array([[-0.5, -0.5, -0.5], [0.5, -0.5, -0.5],
                         [-0.5, 0.5, -0.5], [0.5, 0.5, -0.5],
                         [-0.5, -0.5, 0.5], [0.5, -0.5, 0.5], [-0.5, 0.5, 0.5],
                         [0.5, 0.5, 0.5]])

    # create a list of 6 polygonal faces
    # every row represents a face (quads in this case)
    # faces do not need to have all the same number of vertex indices
    faces = [[0, 2, 3, 1], [0, 4, 6, 2], [0, 1, 5, 4], [7, 6, 4, 5],
             [7, 3, 2, 6], [7, 5, 1, 3]]

    # create a new Mesh with the two arrays
    m = pymeshlab.Mesh(verts, faces)

    assert m.vertex_number() == 8

    # number of faces of the mesh remains 12, since meshes in meshlab are stored as triangle meshes
    # with faux edges
    assert m.face_number() == 12

    # when creating a mesh from a polymesh, a custom per face scalar attribute is added to the newly created mesh
    # storing the birth polygon faces for each triangle
    # get the birth polygon for each face of the mesh
    birth_faces = m.face_custom_scalar_attribute_array('poly_birth_faces')

    print(birth_faces)

    # the birth face of triangle with id 5 is 2
    assert (birth_faces[5] == 2)

    # create a new MeshSet
    ms = pymeshlab.MeshSet()

    # add the mesh to the MeshSet (note: ms contains a *copy* of m)
    ms.add_mesh(m, "cube_mesh")

    # save the current mesh
    # obj format in meshlab supports saving polygonal meshes
    ms.save_current_mesh(output_path + "saved_polygonal_cube_from_array.obj")
Exemple #6
0
def test_import_mesh_from_array():
    print('\n')
    output_path = samples_common.test_output_path()

    verts = numpy.array([[-0.5, -0.5, -0.5], [0.5, -0.5, -0.5],
                         [-0.5, 0.5, -0.5], [0.5, 0.5, -0.5],
                         [-0.5, -0.5, 0.5], [0.5, -0.5, 0.5], [-0.5, 0.5, 0.5],
                         [0.5, 0.5, 0.5]])

    faces = numpy.array([[2, 1, 0], [1, 2, 3], [4, 2, 0], [2, 4, 6], [1, 4, 0],
                         [4, 1, 5], [6, 5, 7], [5, 6, 4], [3, 6, 7], [6, 3, 2],
                         [5, 3, 7], [3, 5, 1]])

    m = ml.Mesh(verts, faces)

    assert m.vertex_number() == 8
    assert m.face_number() == 12

    ms = ml.MeshSet()
    ms.add_mesh(m, "cube_mesh")
    ms.save_current_mesh(output_path + "saved_cube_from_array.ply")
Exemple #7
0
    def get_pointclouds(self, num_points=None) -> PointClouds3D:
        """ Returns points, normals and color in object coordinate """
        if hasattr(self, 'point_clouds'):
            if num_points is None or (
                    self.point_clouds.points_packed().shape[0] == num_points):
                return self.point_clouds

        if num_points is None or num_points == self.data_dict['points'].shape[
                0]:
            points = torch.tensor(
                self.data_dict["points"]).to(dtype=torch.float32)
            normals = torch.tensor(
                self.data_dict["normals"]).to(dtype=torch.float32)
            colors = torch.tensor(
                self.data_dict["colors"]).to(dtype=torch.float32)
            self.point_clouds = PointClouds3D([points], [normals], [colors])
        else:
            import pymeshlab
            meshes = self.get_meshes()
            # sample on the mesh with poisson disc sampling
            points_list = []
            normals_list = []
            for i in range(len(meshes)):
                mesh = meshes[i]
                m = pymeshlab.Mesh(mesh.verts_packed().cpu().numpy(),
                                   mesh.faces_packed().cpu().numpy())
                breakpoint()
                ms = pymeshlab.MeshSet()
                ms.add_mesh(m, 'mesh0')
                ms.poisson_disk_sampling(samplenum=num_points,
                                         approximategeodesicdistance=True,
                                         exactnumflag=True)
                m = ms.current_mesh()
                points = m.vertex_matrix().astype(np.float32)
                normals = m.vertex_normal_matrix().astype(np.float32)
                points_list.append(torch.from_numpy(points))
                normals_list.append(torch.from_numpy(normals))
            self.point_clouds = PointClouds3D(points_list, normals_list)

        return self.point_clouds
Exemple #8
0
"""pymeshlab interoperability example:
    Surface reconstruction by ball pivoting"""
import pymeshlab
import vedo

pts = vedo.Mesh(vedo.dataurl + 'cow.vtk').points()  # numpy array of vertices

m = pymeshlab.Mesh(vertex_matrix=pts)

ms = pymeshlab.MeshSet()
ms.add_mesh(m)

ms.surface_reconstruction_ball_pivoting(ballradius=0.15)
# ms.compute_normals_for_point_sets()
# ms.surface_reconstruction_screened_poisson()

mlab_mesh = ms.current_mesh()

reco_mesh = vedo.Mesh(mlab_mesh).computeNormals().flat()

vedo.show(__doc__, reco_mesh, axes=True, bg2='blue9', title="vedo + pymeshlab")

################################################################################
# Full list of filters, https://pymeshlab.readthedocs.io/en/latest/filter_list.html
#
# MeshLab offers plenty of useful filters, among which:
#
# ambient_occlusion
# compute_curvature_principal_directions
# colorize_by_geodesic_distance_from_a_given_point
# colorize_by_border_distance
Exemple #9
0
def simplify_mesh_pyml(x, F, method='quadric', inplace=False, **kwargs):
    """Simplify mesh using pymeshlab.

    Parameters
    ----------
    x :         MeshNeuron | Volume | Trimesh
                Mesh object to simplify.
    F :         float [0-1]
                For method "quadric" this is the target number of faces as
                fraction of the original face count. For method "cluster" this
                is the size of the cells used for clustering: larger values =
                coarser mesh.
    method :    "quadric" | "cluster"
                Which method to use for simplification: quadratic mesh
                decimation or vertex clustering.
    inplace :   bool
                If True, will perform simplication on ``x``. If False, will
                simplify and return a copy.
    **kwargs
                Passed to pymeshlab filter functions:
                `simplification_quadric_edge_collapse_decimation` or
                `simplification_clustering_decimation` depending on method.

    Returns
    -------
    simp
                Simplified mesh-like object.

    """
    try:
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            import pymeshlab
    except ImportError:
        raise ImportError('Please install pymeshlab: pip3 install pymeshlab')
    except BaseException:
        raise

    utils.eval_param(method,
                     name='method',
                     allowed_values=('quadric', 'cluster'))

    if not isinstance(x, (core.MeshNeuron, tm.Trimesh, core.Volume)):
        raise TypeError(
            f'Expected MeshNeuron, Volume or Trimesh, got "{type(x)}"')

    if (F <= 0) or (F >= 1):
        raise ValueError(f'`t` must be between 0-1, got {F}')

    verts, faces = x.vertices, x.faces

    # Create mesh from vertices and faces
    m = pymeshlab.Mesh(verts, faces)

    # Create a new MeshSet
    ms = pymeshlab.MeshSet()

    # Add the mesh to the MeshSet
    ms.add_mesh(m, "mymesh")

    # Apply filter
    if method == 'quadric':
        defaults = {'targetperc': F}
        defaults.update(kwargs)
        ms.simplification_quadric_edge_collapse_decimation(**defaults)
    else:
        # Threshold is for some reason in percent, not fraction
        defaults = {'thresholds': F * 100}
        defaults.update(kwargs)
        ms.simplification_clustering_decimation(**defaults)

    # Get update mesh
    m2 = ms.current_mesh()

    # Get new vertices and faces
    new_verts = m2.vertex_matrix()
    new_faces = m2.face_matrix()

    # Make copy of the original mesh and assign new vertices + faces
    if not inplace:
        x = x.copy()

    x.vertices = new_verts
    x.faces = new_faces

    if isinstance(x, core.MeshNeuron):
        x._clear_temp_attr()

    return x
Exemple #10
0
        if faces.shape[0] != max_faces:
            print("Model with more than {} faces ({}): {}".format(max_faces, faces.shape[0], out_dir))
            continue

        # move to center
        center = (np.max(vertices, 0) + np.min(vertices, 0)) / 2
        vertices -= center

        # normalize
        max_len = np.max(vertices[:, 0]**2 + vertices[:, 1]**2 + vertices[:, 2]**2)
        vertices /= np.sqrt(max_len)

        # get normal vector
        ms.clear()
        mesh = pymeshlab.Mesh(vertices, faces)
        ms.add_mesh(mesh)
        face_normal = ms.current_mesh().face_normal_matrix()

        # get neighbors
        faces_contain_this_vertex = []
        for i in range(len(vertices)):
            faces_contain_this_vertex.append(set([]))
        centers = []
        corners = []
        for i in range(len(faces)):
            [v1, v2, v3] = faces[i]
            x1, y1, z1 = vertices[v1]
            x2, y2, z2 = vertices[v2]
            x3, y3, z3 = vertices[v3]
            centers.append([(x1 + x2 + x3) / 3, (y1 + y2 + y3) / 3, (z1 + z2 + z3) / 3])
Exemple #11
0
def main():
    argv = sys.argv
    argv = argv[argv.index("--") + 1:]  # get all args after "--"

    inputPath = argv[0]  # "output"
    inputExt = argv[1]  # "_final.ply"
    samplePercentage = float(argv[2])  #0.1
    minStrokePoints = int(argv[3])  #2

    la = latk.Latk()
    la.layers.append(latk.LatkLayer())
    counter = 0

    urls = []

    for fileName in os.listdir(inputPath):
        if fileName.endswith(inputExt):
            url = os.path.abspath(os.path.join(inputPath, fileName))
            urls.append(url)
    urls.sort()

    la = latk.Latk()
    layer = latk.LatkLayer()
    la.layers.append(layer)
    for i in range(0, len(urls)):
        frame = latk.LatkFrame(frame_number=i)
        la.layers[0].frames.append(frame)

    for i in range(0, len(urls)):
        print("\nLoading meshes " + str(i + 1) + " / " + str(len(urls)))

        ms = ml.MeshSet()
        ms.load_new_mesh(urls[i])
        mesh = ms.current_mesh()

        newSampleNum = int(mesh.vertex_number() * samplePercentage)
        if (mesh.edge_number() == 0 and mesh.face_number() == 0):
            ms.poisson_disk_sampling(samplenum=newSampleNum, subsample=True)
        else:
            ms.poisson_disk_sampling(samplenum=newSampleNum, subsample=False)
        ms.surface_reconstruction_ball_pivoting()
        ms.vertex_attribute_transfer(sourcemesh=0, targetmesh=1)
        ms.save_current_mesh("input.ply", save_vertex_color=True)

        os.system("SynDraw -p test.template")

        print("parsing SVG")
        tree = etree.parse("out.svg")
        root = tree.getroot()
        for element in root:
            if (element.tag.endswith("polyline")):
                points = element.get("points3d").split(" ")
                lPoints = []
                for point in points:
                    point2 = point.split(",")
                    try:
                        point3 = (float(point2[0]), float(point2[2]),
                                  float(point2[1]))
                        lPoints.append(latk.LatkPoint(point3))
                    except:
                        pass
                if (len(lPoints) >= minStrokePoints):
                    la.layers[0].frames[counter].strokes.append(
                        latk.LatkStroke(lPoints))

        allPoints = []
        for stroke in la.layers[0].frames[counter].strokes:
            for point in stroke.points:
                allPoints.append([point.co[0], point.co[2], point.co[1]])
        vertices = np.array(allPoints)
        faces = np.array([[0, 0, 0]])
        mesh = ml.Mesh(vertices, faces)
        ms.add_mesh(mesh)
        ms.vertex_attribute_transfer(sourcemesh=1, targetmesh=2)

        strokeCounter = 0
        pointCounter = 0
        vertexColors = ms.current_mesh().vertex_color_matrix()

        for vertexColor in vertexColors:
            color = (vertexColor[0], vertexColor[1], vertexColor[2], 1.0)
            color = (color[0] * color[0], color[1] * color[1],
                     color[2] * color[2], 1.0)
            la.layers[0].frames[counter].strokes[strokeCounter].points[
                pointCounter].vertex_color = color
            pointCounter += 1
            if (pointCounter > len(
                    la.layers[0].frames[counter].strokes[strokeCounter].points)
                    - 1):
                pointCounter = 0
                strokeCounter += 1

        print("Finished frame " + str(counter + 1))
        counter += 1

    la.write("output.latk")
    print("Wrote latk")
Exemple #12
0
def process_mesh(path, max_faces):
    ms = pymeshlab.MeshSet()
    ms.clear()

    # load mesh
    ms.load_new_mesh(path)
    mesh = ms.current_mesh()

    # # clean up
    # mesh, _ = pymesh.remove_isolated_vertices(mesh)
    # mesh, _ = pymesh.remove_duplicated_vertices(mesh)

    # get elements
    vertices = mesh.vertex_matrix()
    faces = mesh.face_matrix()

    if faces.shape[
            0] != max_faces:  # only occur once in train set of Manifold40
        print("Model with more than {} faces ({}): {}".format(
            max_faces, faces.shape[0], path))
        return None, None

    # move to center
    center = (np.max(vertices, 0) + np.min(vertices, 0)) / 2
    vertices -= center

    # normalize
    max_len = np.max(vertices[:, 0]**2 + vertices[:, 1]**2 + vertices[:, 2]**2)
    vertices /= np.sqrt(max_len)

    # get normal vector
    ms.clear()
    mesh = pymeshlab.Mesh(vertices, faces)
    ms.add_mesh(mesh)
    face_normal = ms.current_mesh().face_normal_matrix()

    # get neighbors
    faces_contain_this_vertex = []
    for i in range(len(vertices)):
        faces_contain_this_vertex.append(set([]))
    centers = []
    corners = []
    for i in range(len(faces)):
        [v1, v2, v3] = faces[i]
        x1, y1, z1 = vertices[v1]
        x2, y2, z2 = vertices[v2]
        x3, y3, z3 = vertices[v3]
        centers.append([(x1 + x2 + x3) / 3, (y1 + y2 + y3) / 3,
                        (z1 + z2 + z3) / 3])
        corners.append([x1, y1, z1, x2, y2, z2, x3, y3, z3])
        faces_contain_this_vertex[v1].add(i)
        faces_contain_this_vertex[v2].add(i)
        faces_contain_this_vertex[v3].add(i)

    neighbors = []
    for i in range(len(faces)):
        [v1, v2, v3] = faces[i]
        n1 = find_neighbor(faces, faces_contain_this_vertex, v1, v2, i)
        n2 = find_neighbor(faces, faces_contain_this_vertex, v2, v3, i)
        n3 = find_neighbor(faces, faces_contain_this_vertex, v3, v1, i)
        neighbors.append([n1, n2, n3])

    centers = np.array(centers)
    corners = np.array(corners)
    faces = np.concatenate([centers, corners, face_normal], axis=1)
    neighbors = np.array(neighbors)

    return faces, neighbors