Пример #1
0
def create_box(f):
    mesh = lib_msh.Mesh(f)
    cube = lib_msh.Mesh(cube=[mesh.xmin, mesh.xmax, mesh.ymin, mesh.ymax, mesh.zmin, mesh.zmax])
    cube.verts[:,:3] -= mesh.center
    cube.verts[:,:3] *= 1.25
    cube.verts[:,:3] += mesh.center
    cube.write("box.mesh")
    lib_exe.execute( lib_exe.tetgen + "-pgANEF box.mesh > /dev/null 2>&1" )
    hausd = 0.02 * np.max(mesh.dims)
    lib_exe.execute( lib_exe.mmg3d + "box.1.mesh -hausd %f -hmax %f > /dev/null 2>&1" % (hausd, hausd) )
Пример #2
0
def adapt_box_to(f, box, maxNb=20000):
    shutil.copyfile(box,"box.mesh")
    cube = lib_msh.Mesh("box.mesh")
    mesh = lib_msh.Mesh(f)
    step = 1 if len(mesh.verts)<maxNb else int(len(mesh.verts)/maxNb)+1
    dists, _ = nearest_neighbor(cube.verts[:,:3], mesh.verts[::step,:3])
    cube.scalars = np.array(dists)
    ABS = np.absolute(cube.scalars)
    mini, maxi = 0.005*np.max(cube.dims), 0.5*np.max(cube.dims)
    cube.scalars = mini + (maxi-mini) * (ABS - np.min(ABS)) / (np.max(ABS) - np.min(ABS))
    cube.write("box.1.mesh")
    cube.writeSol("box.1.sol")
    lib_exe.execute(lib_exe.mmg3d + "box.1.mesh -hgrad 1.5  > /dev/null 2>&1")
Пример #3
0
def import_mesh(filepath):
    MESH = lib_msh.Mesh(filepath)
    if os.path.exists(filepath[:-5] + ".sol"):
        MESH.readSol()
    MESH.tets = lib_msh.np.array([])
    MESH.discardUnused()

    meshes = []
    rTris = MESH.tris[:, -1].tolist() if len(MESH.tris) > 0 else []
    rQuads = MESH.quads[:, -1].tolist() if len(MESH.quads) > 0 else []
    tris = [t.tolist() for t in MESH.tris]
    quads = [q.tolist() for q in MESH.quads]
    verts = [v.tolist()[:-1] for v in MESH.verts]
    REFS = set(rTris + rQuads)

    for i, r in enumerate(REFS):
        refFaces = [t[:-1] for t in tris + quads if t[-1] == r]
        mesh_name = bpy.path.display_name_from_filepath(filepath)
        mesh = bpy.data.meshes.new(name=mesh_name)
        meshes.append(mesh)
        mesh.from_pydata(verts, [], refFaces)
        mesh.validate()
        mesh.update()

    scene = bpy.context.scene

    objects = []
    for i, m in enumerate(meshes):
        obj = bpy.data.objects.new(m.name, m)
        bpy.ops.object.select_all(action='DESELECT')
        scene.objects.link(obj)
        scene.objects.active = obj
        objects.append(obj)
    del meshes

    scene.update()
    bpy.ops.object.select_all(action='DESELECT')
    for o in objects:
        o.select = True
    bpy.ops.object.join()
    bpy.ops.object.editmode_toggle()
    bpy.ops.mesh.remove_doubles()
    bpy.ops.object.editmode_toggle()
Пример #4
0
def to_mesh(f, output):

    #Convert a stl to mesh with meshlabserver
    meshlabScript = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                 "meshlab_scripts", "cleanSTL.mlx")
    tmp = f.replace(".stl", ".obj")
    lib_exe.execute(lib_exe.meshlabserver +
                    "-i %s -o %s -s %s > /dev/null 2>&1" %
                    (f, tmp, meshlabScript))
    f = tmp

    #Convert a .obj to .mesh
    with open(f, "r") as _f:
        LINES = _f.readlines()
        mesh = lib_msh.Mesh()
        mesh.verts = np.array([[float(x) for x in l.split()[1:]] for l in LINES
                               if l[0] == "v"])
        mesh.tris = np.array([[int(x) - 1 for x in l.split()[1:]]
                              for l in LINES if l[0] == "f"])
        mesh.verts = np.insert(mesh.verts, 3, 0, axis=1)
        mesh.tris = np.insert(mesh.tris, 3, 0, axis=1)
        mesh.computeBBox()
        mesh.write(output)
Пример #5
0
def export_mesh(filepath):
    #Get the selected object
    APPLY_MODIFIERS = True
    scene = bpy.context.scene
    bpy.ops.object.duplicate()
    obj = scene.objects.active

    bpy.ops.object.editmode_toggle()
    bpy.ops.mesh.select_all(action='DESELECT')
    bpy.ops.mesh.select_face_by_sides(number=4, type='GREATER')
    bpy.ops.mesh.quads_convert_to_tris(quad_method='BEAUTY',
                                       ngon_method='BEAUTY')
    bpy.ops.mesh.select_all(action='DESELECT')
    bpy.ops.mesh.select_face_by_sides(number=3, type='GREATER')
    bpy.ops.mesh.quads_convert_to_tris(quad_method='BEAUTY',
                                       ngon_method='BEAUTY')
    bpy.ops.object.editmode_toggle()

    mesh = obj.to_mesh(scene, APPLY_MODIFIERS, 'PREVIEW')
    mesh.transform(obj.matrix_world)

    #Get the info
    verts = [[v.co[0], v.co[1], v.co[2], 0] for v in mesh.vertices[:]]
    triangles = [[v for v in f.vertices] + [f.material_index + 1]
                 for f in mesh.polygons if len(f.vertices) == 3]
    quads = [[v for v in f.vertices] + [f.material_index + 1]
             for f in mesh.polygons if len(f.vertices) == 4]
    edges = [[e.vertices[0], e.vertices[1], 0] for e in mesh.edges
             if e.use_edge_sharp]

    exportMesh = lib_msh.Mesh()
    exportMesh.verts = lib_msh.np.array(verts)
    exportMesh.tris = lib_msh.np.array(triangles)
    exportMesh.quads = lib_msh.np.array(quads)
    exportMesh.edges = lib_msh.np.array(edges)
    exportMesh.write(filepath)
Пример #6
0
import os
import argparse
import lib_msh

if __name__ == "__main__":

    #arguments
    parser = argparse.ArgumentParser(
        description="Merges multiple .mesh together")
    parser.add_argument("-i",
                        "--input",
                        type=str,
                        nargs="+",
                        help="Input .mesh files",
                        required=True)
    parser.add_argument("-o",
                        "--output",
                        type=str,
                        help="Output .mesh file",
                        required=True)
    args = parser.parse_args()

    original = lib_msh.Mesh(args.input[0])
    for other in args.input[1:]:
        original.fondre(lib_msh.Mesh(other))
    original.write(args.output)
Пример #7
0
        lib_exe.python_cmd("carve.py") + "-i %s -o %s -r %d" % (IN, OUT, 31))
    if args.medit: lib_exe.execute(lib_exe.medit + "%s" % (OUT))
    os.remove(OUT)

    # 2 - convert .obj and .stl objects to .mesh
    print("Testing convert.py")
    IN1 = os.path.join(args.directory, "buddha.obj")
    OUT1 = os.path.join(args.directory, "buddha1.mesh")
    lib_exe.execute(
        lib_exe.python_cmd("convert.py") + "-i %s -o %s" % (IN1, OUT1))
    IN2 = os.path.join(args.directory, "buddha.stl")
    OUT2 = os.path.join(args.directory, "buddha2.mesh")
    lib_exe.execute(
        lib_exe.python_cmd("convert.py") + "-i %s -o %s" % (IN2, OUT2))
    if args.medit: lib_exe.execute(lib_exe.medit + "%s %s" % (OUT1, OUT2))
    buddha1 = lib_msh.Mesh(OUT1)
    buddha2 = lib_msh.Mesh(OUT2)
    #print(len(buddha1.verts), len(buddha2.verts))
    #assert( len(buddha1.verts) == len(buddha2.verts) )
    assert (buddha1.verts[0][1] == buddha2.verts[0][1])
    assert (buddha1.tris[10][2] == buddha2.tris[10][2])
    os.remove(OUT1)
    os.remove(OUT2)

    # 3 - compute the distance between two meshes
    print("Testing distance.py")
    IN1 = os.path.join(args.directory, "buddha.mesh")
    IN2 = os.path.join(args.directory, "buddha.displaced.mesh")
    OUT = os.path.join(args.directory, "buddha.distance.mesh")
    lib_exe.execute(
        lib_exe.python_cmd("distance.py") + "-i1 %s -i2 %s -o %s" %
Пример #8
0
    args.template = os.path.abspath(args.template) if args.template else None
    args.input    = os.path.abspath(args.input)
    args.output   = os.path.abspath(args.output)

    #Copy the template to warp
    shutil.copyfile(args.template, "sphere.mesh")

    #Warp
    lib_exe.execute(lib_paths.wrapping + " %s -p -nit %d -load %f > /dev/null 2>&1" % (args.input, 150, 40) )

    #Clean the mesh and extract the surface
    final = None
    try:
        number_max=-1
        for f in [x for x in os.listdir(".") if "sphere.d." in x and ".mesh" in x]:
            number = int(f.split(".")[2])
            if number>number_max:
                final = f
    except:
        final = "sphere.d.mesh"

    warped = lib_msh.Mesh(final)
    warped.tris = warped.tris[warped.tris[:,-1] != 2]
    warped.tets = np.array([])
    warped.discardUnused()
    warped.write(args.output)

    #Remove the unused files
    #os.remove("sphere.mesh")
    #os.remove("sphere.d.mesh")
Пример #9
0
        print(args.source + " is not a valid file")
        sys.exit()
    if not os.path.splitext(args.source)[1] == ".mesh":
        print(args.source + " is not a .mesh file")
        sys.exit()
    if not os.path.isfile(args.target):
        print(args.target + " is not a valid file")
        sys.exit()
    if not os.path.splitext(args.target)[1] == ".mesh":
        print(args.target + " is not a .mesh file")
        sys.exit()
    if not os.path.splitext(args.matrix)[1] == ".txt":
        print("Output file must be in the .txt format")
        sys.exit()

    sourceMesh = lib_msh.Mesh(args.source)
    targetMesh = lib_msh.Mesh(args.target)

    sourceStep = int(len(sourceMesh.verts) / args.maxPoints) + 1
    targetStep = int(len(targetMesh.verts) / args.maxPoints) + 1

    sourceVerts = sourceMesh.verts[::sourceStep, :-1]
    targetVerts = targetMesh.verts[::targetStep, :-1]

    MAT, dist = icp(sourceVerts,
                    targetVerts,
                    max_iterations=args.maxIterations,
                    tolerance=args.tolerance)

    writeMatrixToFile(MAT, args.matrix)
Пример #10
0
    args = parser.parse_args()

    #check
    args.input = os.path.abspath(args.input)
    if not os.path.exists(args.input):
        print("No input file")
        sys.exit(1)
    if args.matrix:
        for i, m in enumerate(args.matrix):
            args.matrix[i] = os.path.abspath(m)
            if not os.path.exists(m):
                print("No matrix file", m)
                sys.exit(1)

    #apply
    mesh = lib_msh.Mesh(args.input)
    if args.matrix:
        for matrix in args.matrix:
            mesh.applyMatrix(matFile=matrix)
    else:
        """
        if args.center:
            mesh.verts[:,:3] -= mesh.center
            if args.scale:
                mesh.verts[:,:3] *= args.scale
            else:
                mesh.verts[:,:3] *= 1. / np.max(mesh.dims)
            mesh.verts[:,:3] += [0.5,0.5,0.5]
        """
        #else:
        #Scale relative to the appropriate center
Пример #11
0
    if not os.path.splitext(args.input1)[1] == ".mesh":
        print(args.input1 + " is not a .mesh file")
        sys.exit()
    if not os.path.isfile(args.input2):
        print(args.input2 + " is not a valid file")
        sys.exit()
    if not os.path.splitext(args.input2)[1] == ".mesh":
        print(args.input2 + " is not a .mesh file")
        sys.exit()
    if not os.path.splitext(
            args.output)[1] == ".mesh" and not os.path.splitext(
                args.output)[1] == ".sol":
        print("Output file must be in the .mesh format")
        sys.exit()


if __name__ == "__main__":
    args = parse()
    checkArgs(args)
    mesh1 = lib_msh.Mesh(args.input1)
    mesh2 = lib_msh.Mesh(args.input2)
    if len(mesh1.verts) != len(mesh2.verts):
        print("Different number of verts for the two meshes")
        sys.exit()
    mesh1.vectors = mesh1.verts[:, :3] - mesh2.verts[:, :3]
    if os.path.splitext(args.output)[1] == ".mesh":
        mesh1.write(args.output)
        mesh1.writeSol(args.output.replace(".mesh", ".sol"))
    else:
        mesh1.writeSol(args.output)
Пример #12
0
    parser.add_argument("-d", "--icotris",  type=int, help="Icosphere triangles reference", required=True)
    parser.add_argument("-e", "--icotets",     type=int, help="Icosphere tetrahedra reference", required=True)
    parser.add_argument("-b", "--fixtris",      type=int, help="Fixed triangles reference", required=True)

    args = parser.parse_args(sys.argv[1:])

    #checks
    args.template = os.path.abspath(args.template)
    args.signed   = os.path.abspath(args.signed)
    args.output   = os.path.abspath(args.output)

    # dref: Fixed surface inside the template (number + ref)
    # elref: Elements inside the fixed surface
    # bref: Follower elements
    shutil.copyfile(args.template, "template.mesh")
    cmd = lib_exe.morphing + " %s %s -nit %d -dref 1 %d -elref 1 %d -bref 1 %d  > /dev/null 2>&1" % (args.signed, "template.mesh", args.iterations, args.icotris, args.icotets, args.fixtris)
    lib_exe.execute(cmd)

    #Clean the mesh
    mesh = lib_msh.Mesh(args.signed[:-5] + ".1.mesh")
    mesh.readSol(   args.signed[:-5] + ".1.depl.sol")
    mesh.tets = np.array([])
    mesh.tris = mesh.tris[mesh.tris[:,-1]!=10]
    mesh.discardUnused()
    mesh.write(args.output)
    mesh.writeSol(args.output.replace("mesh", "sol"))

    #Remove the temporary files
    os.remove(args.signed[:-5] + ".1.mesh")
    os.remove(args.signed[:-5] + ".1.depl.sol")
Пример #13
0
                        help="Hausdorff distance",
                        default=0.01)
    parser.add_argument("-r",
                        "--reference",
                        type=int,
                        help="New surface reference",
                        default=0)
    parser.add_argument("-l",
                        "--levelset",
                        type=float,
                        help="Levelset value",
                        default=0)
    args = parser.parse_args(sys.argv[1:])

    #checks
    args.input = os.path.abspath(args.input)
    args.output = os.path.abspath(args.output)

    lib_exe.execute(lib_exe.mmg3d + "%s -ls %f -hausd %f -o tmp.mesh" %
                    (args.input, args.levelset, args.distance))

    mesh = lib_msh.Mesh("tmp.mesh")
    mesh.tets = np.array([])
    mesh.tris = mesh.tris[mesh.tris[:, -1] == 10]
    mesh.discardUnused()
    mesh.tris[:, -1] = args.reference
    mesh.write(args.output)

    os.remove("tmp.mesh")
    os.remove("tmp.sol")
Пример #14
0
    if not os.path.isfile(args.input):
        print(args.input + " is not a valid file")
        sys.exit()
    if not os.path.splitext(args.input)[1] == ".mesh":
        print(args.input + " is not a .mesh file")
        sys.exit()
    if not os.path.splitext(args.output)[1] == ".mesh":
        print("Output file must be in the .mesh format")
        sys.exit()
    if args.resolution < 11 or args.resolution > 301:
        print("The resolution must be in [11, 301]")
        sys.exit()

    print("1 - Converting .mesh to binary .xyz")
    print("-  1.1 - Opening the mesh file")
    mesh = lib_msh.Mesh(args.input)
    print("-  1.2 - Converting to binary point data")
    binaryData, totalScale = ptsToXYZCubes(mesh.verts, args.resolution)

    print("2 - Creating the filled volume")
    print("-  2.1 - Space carving")
    newData = spaceCarve(binaryData)
    newData = nd.binary_closing(newData,
                                structure=nd.generate_binary_structure(3, 3),
                                iterations=3)
    print("-  2.2 - Marching cubes")
    verts, faces, _, _ = mea.marching_cubes_lewiner(volume=newData, level=0.5)
    recon = lib_msh.Mesh()
    recon.verts = np.insert(np.array(verts), 3, 0, axis=1)
    recon.tris = np.insert(np.array(faces), 3, 0, axis=1)
    recon.computeBBox()
Пример #15
0
    args.interior = os.path.abspath(args.interior)
    args.exterior = os.path.abspath(args.exterior)
    args.output = os.path.abspath(args.output)
    if args.template:
        args.template = os.path.abspath(args.template)

    #check for intersections
    if intersects(args.interior):
        print("interior surface is self-intersecting")
        sys.exit(1)
    if intersects(args.exterior):
        print("exterior surface is self-intersecting")
        sys.exit(2)

    #Merge the meshes and run tetgen
    exterior, interior = lib_msh.Mesh(args.exterior), lib_msh.Mesh(
        args.interior)
    #exterior.tris = exterior.tris[exterior.tris[:,-1]!=2]
    exterior.tris[:, -1] = 2
    exterior.discardUnused()
    interior.tris[:, -1] = 1
    interior.fondre(exterior)
    interior.write("mask.mesh")

    if intersects("mask.mesh"):
        print("mask is self-intersecting")
        sys.exit(3)

    #Run tetgen
    lib_exe.execute(lib_exe.tetgen + "-pgaANEFY mask.mesh")
    for f in os.listdir("."):
Пример #16
0
        if f.endswith(".obj") or f.endswith(".stl"):
            lib_exe.execute(
                lib_exe.python_cmd("convert.py") + "-i %s -o %s" %
                (f, f.replace(f[-3:], "mesh")))
            args.input[i] = f.replace(f[-3:], "mesh")

    # 2 - If needed, merge everything together
    if len(args.input) > 1:
        lib_exe.execute(
            lib_exe.python_cmd("merge.py") + "-i %s -o %s" %
            (" ".join(args.input), NAME + ".mesh"))
    else:
        shutil.copyfile(args.input[0], NAME + ".mesh")

    # 3 - Transform to an object between 0.1 and 0.9
    mesh = lib_msh.Mesh(NAME + ".mesh")
    S = 0.8 / np.max(mesh.dims)
    C = mesh.center
    lib_exe.execute(
        lib_exe.python_cmd("transform.py") + "-i %s -o %s -t %f %f %f" %
        (NAME + ".mesh", "tmp.mesh", -C[0], -C[1], -C[2]))
    lib_exe.execute(
        lib_exe.python_cmd("transform.py") + "-i %s -o %s -s %f %f %f" %
        ("tmp.mesh", "tmp.mesh", S, S, S))
    lib_exe.execute(
        lib_exe.python_cmd("transform.py") + "-i %s -o %s -t %f %f %f" %
        ("tmp.mesh", NAME + ".scaled.mesh", 0.5, 0.5, 0.5))
    os.remove("tmp.mesh")

    # 4 - Remesh
    HAUSD = 0.0025
Пример #17
0
    args = parser.parse_args()

    if not os.path.isfile(args.input):
        print(args.input + " is not a valid file")
        sys.exit()
    if not os.path.splitext(args.input)[1] == ".mesh":
        print(args.input + " is not a .mesh file")
        sys.exit()
    if not os.path.splitext(args.output)[1] == ".mesh":
        print("Output file must be in the .mesh format")
        sys.exit()
    if intersects(args.input):
        print(args.input + " has intersecting facets")
        sys.exit()

    mesh = lib_msh.Mesh(args.input)
    ico = lib_msh.Mesh(ico=[args.center, args.radius])
    ico.tris[:, -1] = 10
    mesh.fondre(ico)
    mesh.write("out.mesh")
    lib_exe.execute(lib_exe.tetgen + "-pgANEYF out.mesh")
    lib_exe.execute(lib_exe.mmg3d + "out.1.mesh -nosurf -o " + args.output)
    os.remove(args.output.replace(".mesh", ".sol"))

    #Make the same references in args.output than in out.mesh
    def distance(a, b):
        return ((a[0] - b[0])**2 + (a[1] - b[1])**2 + (a[2] - b[2])**2)**0.5

    final = lib_msh.Mesh(args.output)
    for i, t in enumerate(final.tris):
        vert1 = final.verts[t[0]]
Пример #18
0
    if args.interiorIsovalue < args.exteriorIsovalue:
        print("The inner shell must be closer than the outer shell")
        sys.exit()
    if args.interiorIsovalue < 5 or args.exteriorIsovalue < 5:
        print("The shell must be closer than maxDim/5")
        sys.exit()
    args.input = os.path.abspath(args.input)
    args.output = os.path.abspath(args.output)

    #Carve the input mesh
    lib_exe.execute(
        lib_exe.python_cmd("carve.py") + "-i %s -o %s -r %d" %
        (args.input, args.output.replace(".mesh", ".carved.mesh"), 31))

    #Create a box and mesh it to compute the signed distance on
    mesh = lib_msh.Mesh(args.input)
    c = np.max(mesh.dims) / 8
    cube = lib_msh.Mesh(cube=[
        mesh.xmin - c, mesh.xmax + c, mesh.ymin - c, mesh.ymax + c, mesh.zmin -
        c, mesh.zmax + c
    ])
    cube.write("box.mesh")
    lib_exe.execute(lib_exe.tetgen + "-pgANEF %s" % ("box.mesh"))
    lib_exe.execute(
        lib_exe.mmg3d + "%s -hausd %f -hmax %f" %
        ("box.1.mesh", np.max(mesh.dims) / 50, np.max(mesh.dims) / 25))

    #Compute the signed distance to the carved object
    lib_exe.execute(
        lib_exe.mshdist + "-ncpu 16 -noscale %s %s" %
        ("box.1.o.mesh", args.output.replace(".mesh", ".carved.mesh")))