summaryrefslogtreecommitdiff
path: root/mesh.py
diff options
context:
space:
mode:
Diffstat (limited to 'mesh.py')
-rw-r--r--mesh.py113
1 files changed, 113 insertions, 0 deletions
diff --git a/mesh.py b/mesh.py
new file mode 100644
index 0000000..a4b9048
--- /dev/null
+++ b/mesh.py
@@ -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))