diff options
Diffstat (limited to 'mesh.py')
-rw-r--r-- | mesh.py | 113 |
1 files changed, 113 insertions, 0 deletions
@@ -0,0 +1,113 @@ +import numpy as np +import string +import struct + +class Mesh(object): + def __init__(self, vertices, triangles): + vertices = np.asarray(vertices, dtype=float) + triangles = np.asarray(triangles, dtype=int) + + if len(vertices.shape) != 2 or vertices.shape[1] != 3: + raise ValueError('shape mismatch') + + if len(triangles.shape) != 2 or triangles.shape[1] != 3: + raise ValueError('shape mismatch') + + if (triangles < 0).any(): + raise ValueError('indices in `triangles` must be positive.') + + if (triangles >= len(vertices)).any(): + raise ValueError('indices in `triangles` must be less than the ' + 'length of the vertex array.') + + self.vertices = vertices + self.triangles = triangles + + def build(self): + return self.vertices[self.triangles] + + def __add__(self, other): + vertices = np.concatenate((self.vertices, other.vertices)) + triangles = np.concatenate((self.triangles, other.triangles+len(self.vertices))) + + return Mesh(vertices, triangles) + + def __len__(self): + return len(self.triangles) + +def mesh_from_stl(filename): + f = open(filename) + buf = f.read(200) + f.close() + + for char in buf: + if char not in string.printable: + return mesh_from_binary_stl(filename) + + return mesh_from_ascii_stl(filename) + +def mesh_from_ascii_stl(filename): + f = open(filename) + + vertices = [] + triangles = [] + vertex_map = {} + + while True: + line = f.readline() + + if line == '': + break + + if not line.strip().startswith('vertex'): + continue + + triangle = [None]*3 + for i in range(3): + vertex = tuple([float(s) for s in line.strip().split()[1:]]) + + if vertex not in vertex_map: + vertices.append(vertex) + vertex_map[vertex] = len(vertices) - 1 + + triangle[i] = vertex_map[vertex] + + if i < 3: + line = f.readline() + + triangles.append(triangle) + + f.close() + + return Mesh(np.array(vertices), np.array(triangles, dtype=np.uint32)) + +def mesh_from_binary_stl(filename): + f = open(filename) + + vertices = [] + triangles = [] + vertex_map = {} + + f.read(80) + ntriangles = struct.unpack('<I', f.read(4))[0] + + for i in range(ntriangles): + f.read(12) + + triangle = [None]*3 + for j in range(3): + vertex = tuple(struct.unpack('<fff', f.read(12))) + + if vertex not in vertex_map: + vertices.append(vertex) + vertex_map[vertex] = len(vertices) - 1 + + triangle[j] = vertex_map[vertex] + + triangles.append(triangle) + + f.read(2) + + f.close() + + return Mesh(np.array(vertices), np.array(triangles, dtype=np.uint32)) |