Search code examples
python-3.x3d

Create a .stl file from a collection of points


So the software I am using accepts 3D objects in the form of contours or .stl files. The contours I have are along the z-plane(each plane has a unique z). I have had to modify the contours for my experiment and now the contours do not have a unique z for each plane(they are now slightly angled wrt z=0 plane).

The points represent the edges of the 3D object. What would be the best way to take this collection of points and create a .stl file?

I am relatively new to working with python and 3D objects, so any help, pointers or suggestions would be much appreciated.

Edit: I have the simplices and verticies using the Delaunay(), but how do I proceed next?

  1. The co-ordinates of all points are in this text file in the format "x y z".

Solution

  • So after seeking an answer for months and trying to use Meshlab and Blender I finally stumbled across the answer using numpy-stl. Hopeful that it will help others in a similar situation.

    Here is the code to generate the .STL file:

    from stl import mesh
    num_triangles=len(fin_list)
    data = np.zeros(num_triangles, dtype=mesh.Mesh.dtype)
    for i in range(num_triangles):
        #I did not know how to use numpy-arrays in this case. This was the major roadblock
        # assign vertex co-ordinates to variables to write into mesh
        data["vectors"][i] = np.array([[v1x, v1y, v1z],[v2x, v2y, v2z],[v3x, v3y, v3z]])
    m=mesh.Mesh(data)
    m.save('filename.stl')
    

    The three vertices that form a triangle in the mesh go in as a vector that define the surface normal. I just collected three such vertices that form a triangle and wrote them into the mesh. Since I had a regular array of points, it was easy to collect the triangles:

    for i in range(len(point_list)-1):
            plane_a=[]
            plane_b=[]
            for j in range(len(point_list[i])-1):
                tri_a=[]
                tri_b=[]
                #series a triangles
                tri_a.append(point_list[i+1][j])
                tri_a.append(point_list[i][j+1])
                tri_a.append(point_list[i][j])
                #series b triangles
                tri_b.append(point_list[i+1][j])
                tri_b.append(point_list[i+1][j+1])
                tri_b.append(point_list[i][j+1])
                #load to plane
                plane_a.append(tri_a)
                plane_b.append(tri_b)
            group_a.append(plane_a)
            group_b.append(plane_b)
    

    The rules for choosing triangles for creating a mesh are as follows:

    1. The vertices must be arranged in a counter-clock direction.
    2. Each triangle must share two vertices with adjacent triangles.
    3. The direction normal must point out of the surface.

    There were two more rules that I did not follow but it still worked in my case: 1. All coordinates must be positive(In 1st Quadrant only) 2. All triangles must be arranged in an increasing z-order.

    Note: There can be two kinds of .STL file formats: Binary and ASCII. numpy-stl writes out in the binary format. More info on STL files can be found here.

    Hope this helps!