printrun-src/printrun/stltool.py

Sat, 08 Sep 2018 12:00:12 +0200

author
mdd
date
Sat, 08 Sep 2018 12:00:12 +0200
changeset 39
74801c0f2709
parent 15
0bbb006204fc
child 46
cce0af6351f0
permissions
-rw-r--r--

bad idea :(

15
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
1 # coding: utf-8
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
2
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
3 # This file is part of the Printrun suite.
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
4 #
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
5 # Printrun is free software: you can redistribute it and/or modify
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
6 # it under the terms of the GNU General Public License as published by
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
7 # the Free Software Foundation, either version 3 of the License, or
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
8 # (at your option) any later version.
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
9 #
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
10 # Printrun is distributed in the hope that it will be useful,
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
13 # GNU General Public License for more details.
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
14 #
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
15 # You should have received a copy of the GNU General Public License
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
16 # along with Printrun. If not, see <http://www.gnu.org/licenses/>.
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
17
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
18 import sys
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
19 import struct
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
20 import math
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
21 import logging
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
22
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
23 import numpy
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
24 import numpy.linalg
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
25
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
26 def normalize(v):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
27 return v / numpy.linalg.norm(v)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
28
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
29 def genfacet(v):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
30 veca = v[1] - v[0]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
31 vecb = v[2] - v[1]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
32 vecx = numpy.cross(veca, vecb)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
33 vlen = numpy.linalg.norm(vecx)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
34 if vlen == 0:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
35 vlen = 1
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
36 normal = vecx / vlen
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
37 return (normal, v)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
38
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
39 I = numpy.identity(4)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
40
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
41 def homogeneous(v, w = 1):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
42 return numpy.append(v, w)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
43
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
44 def applymatrix(facet, matrix = I):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
45 return genfacet(map(lambda x: matrix.dot(homogeneous(x))[:3], facet[1]))
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
46
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
47 def ray_triangle_intersection(ray_near, ray_dir, (v1, v2, v3)):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
48 """
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
49 Möller–Trumbore intersection algorithm in pure python
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
50 Based on http://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
51 """
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
52 eps = 0.000001
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
53 edge1 = v2 - v1
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
54 edge2 = v3 - v1
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
55 pvec = numpy.cross(ray_dir, edge2)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
56 det = edge1.dot(pvec)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
57 if abs(det) < eps:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
58 return False, None
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
59 inv_det = 1. / det
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
60 tvec = ray_near - v1
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
61 u = tvec.dot(pvec) * inv_det
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
62 if u < 0. or u > 1.:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
63 return False, None
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
64 qvec = numpy.cross(tvec, edge1)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
65 v = ray_dir.dot(qvec) * inv_det
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
66 if v < 0. or u + v > 1.:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
67 return False, None
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
68
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
69 t = edge2.dot(qvec) * inv_det
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
70 if t < eps:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
71 return False, None
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
72
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
73 return True, t
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
74
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
75 def ray_rectangle_intersection(ray_near, ray_dir, p0, p1, p2, p3):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
76 match1, _ = ray_triangle_intersection(ray_near, ray_dir, (p0, p1, p2))
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
77 match2, _ = ray_triangle_intersection(ray_near, ray_dir, (p0, p2, p3))
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
78 return match1 or match2
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
79
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
80 def ray_box_intersection(ray_near, ray_dir, p0, p1):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
81 x0, y0, z0 = p0[:]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
82 x1, y1, z1 = p1[:]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
83 rectangles = [((x0, y0, z0), (x1, y0, z0), (x1, y1, z0), (x0, y1, z0)),
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
84 ((x0, y0, z1), (x1, y0, z1), (x1, y1, z1), (x0, y1, z1)),
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
85 ((x0, y0, z0), (x1, y0, z0), (x1, y0, z1), (x0, y0, z1)),
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
86 ((x0, y1, z0), (x1, y1, z0), (x1, y1, z1), (x0, y1, z1)),
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
87 ((x0, y0, z0), (x0, y1, z0), (x0, y1, z1), (x0, y0, z1)),
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
88 ((x1, y0, z0), (x1, y1, z0), (x1, y1, z1), (x1, y0, z1)),
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
89 ]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
90 rectangles = [(numpy.array(p) for p in rect)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
91 for rect in rectangles]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
92 for rect in rectangles:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
93 if ray_rectangle_intersection(ray_near, ray_dir, *rect):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
94 return True
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
95 return False
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
96
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
97 def emitstl(filename, facets = [], objname = "stltool_export", binary = True):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
98 if filename is None:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
99 return
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
100 if binary:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
101 with open(filename, "wb") as f:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
102 buf = "".join(["\0"] * 80)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
103 buf += struct.pack("<I", len(facets))
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
104 facetformat = struct.Struct("<ffffffffffffH")
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
105 for facet in facets:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
106 l = list(facet[0][:])
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
107 for vertex in facet[1]:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
108 l += list(vertex[:])
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
109 l.append(0)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
110 buf += facetformat.pack(*l)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
111 f.write(buf)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
112 else:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
113 with open(filename, "w") as f:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
114 f.write("solid " + objname + "\n")
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
115 for i in facets:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
116 f.write(" facet normal " + " ".join(map(str, i[0])) + "\n outer loop\n")
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
117 for j in i[1]:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
118 f.write(" vertex " + " ".join(map(str, j)) + "\n")
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
119 f.write(" endloop" + "\n")
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
120 f.write(" endfacet" + "\n")
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
121 f.write("endsolid " + objname + "\n")
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
122
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
123 class stl(object):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
124
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
125 _dims = None
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
126
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
127 def _get_dims(self):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
128 if self._dims is None:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
129 minx = float("inf")
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
130 miny = float("inf")
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
131 minz = float("inf")
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
132 maxx = float("-inf")
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
133 maxy = float("-inf")
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
134 maxz = float("-inf")
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
135 for normal, facet in self.facets:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
136 for vert in facet:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
137 if vert[0] < minx:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
138 minx = vert[0]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
139 if vert[1] < miny:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
140 miny = vert[1]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
141 if vert[2] < minz:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
142 minz = vert[2]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
143 if vert[0] > maxx:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
144 maxx = vert[0]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
145 if vert[1] > maxy:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
146 maxy = vert[1]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
147 if vert[2] > maxz:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
148 maxz = vert[2]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
149 self._dims = [minx, maxx, miny, maxy, minz, maxz]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
150 return self._dims
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
151 dims = property(_get_dims)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
152
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
153 def __init__(self, filename = None):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
154 self.facet = (numpy.zeros(3), (numpy.zeros(3), numpy.zeros(3), numpy.zeros(3)))
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
155 self.facets = []
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
156 self.facetsminz = []
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
157 self.facetsmaxz = []
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
158
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
159 self.name = ""
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
160 self.insolid = 0
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
161 self.infacet = 0
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
162 self.inloop = 0
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
163 self.facetloc = 0
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
164 if filename is None:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
165 return
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
166 with open(filename) as f:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
167 data = f.read()
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
168 if "facet normal" in data[1:300] and "outer loop" in data[1:300]:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
169 lines = data.split("\n")
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
170 for line in lines:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
171 if not self.parseline(line):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
172 return
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
173 else:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
174 logging.warning("Not an ascii stl solid - attempting to parse as binary")
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
175 f = open(filename, "rb")
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
176 buf = f.read(84)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
177 while len(buf) < 84:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
178 newdata = f.read(84 - len(buf))
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
179 if not len(newdata):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
180 break
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
181 buf += newdata
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
182 facetcount = struct.unpack_from("<I", buf, 80)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
183 facetformat = struct.Struct("<ffffffffffffH")
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
184 for i in xrange(facetcount[0]):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
185 buf = f.read(50)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
186 while len(buf) < 50:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
187 newdata = f.read(50 - len(buf))
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
188 if not len(newdata):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
189 break
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
190 buf += newdata
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
191 fd = list(facetformat.unpack(buf))
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
192 self.name = "binary soloid"
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
193 facet = [fd[:3], [fd[3:6], fd[6:9], fd[9:12]]]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
194 self.facets.append(facet)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
195 self.facetsminz.append((min(map(lambda x: x[2], facet[1])), facet))
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
196 self.facetsmaxz.append((max(map(lambda x: x[2], facet[1])), facet))
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
197 f.close()
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
198 return
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
199
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
200 def intersect_box(self, ray_near, ray_far):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
201 ray_near = numpy.array(ray_near)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
202 ray_far = numpy.array(ray_far)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
203 ray_dir = normalize(ray_far - ray_near)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
204 x0, x1, y0, y1, z0, z1 = self.dims
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
205 p0 = numpy.array([x0, y0, z0])
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
206 p1 = numpy.array([x1, y1, z1])
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
207 return ray_box_intersection(ray_near, ray_dir, p0, p1)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
208
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
209 def intersect(self, ray_near, ray_far):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
210 ray_near = numpy.array(ray_near)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
211 ray_far = numpy.array(ray_far)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
212 ray_dir = normalize(ray_far - ray_near)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
213 best_facet = None
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
214 best_dist = float("inf")
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
215 for facet_i, (normal, facet) in enumerate(self.facets):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
216 match, dist = ray_triangle_intersection(ray_near, ray_dir, facet)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
217 if match and dist < best_dist:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
218 best_facet = facet_i
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
219 best_dist = dist
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
220 return best_facet, best_dist
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
221
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
222 def rebase(self, facet_i):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
223 normal, facet = self.facets[facet_i]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
224 u1 = facet[1] - facet[0]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
225 v2 = facet[2] - facet[0]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
226 n1 = u1.dot(u1)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
227 e1 = u1 / math.sqrt(n1)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
228 u2 = v2 - u1 * v2.dot(u1) / n1
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
229 e2 = u2 / numpy.linalg.norm(u2)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
230 e3 = numpy.cross(e1, e2)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
231 # Ensure Z direction if opposed to the normal
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
232 if normal.dot(e3) > 0:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
233 e2 = - e2
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
234 e3 = - e3
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
235 matrix = [[e1[0], e2[0], e3[0], 0],
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
236 [e1[1], e2[1], e3[1], 0],
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
237 [e1[2], e2[2], e3[2], 0],
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
238 [0, 0, 0, 1]]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
239 matrix = numpy.array(matrix)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
240 # Inverse change of basis matrix
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
241 matrix = numpy.linalg.inv(matrix)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
242 # Set first vertex of facet as origin
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
243 neworig = matrix.dot(homogeneous(facet[0]))
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
244 matrix[:3, 3] = -neworig[:3]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
245 newmodel = self.transform(matrix)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
246 return newmodel
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
247
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
248 def cut(self, axis, direction, dist):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
249 s = stl()
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
250 s.facets = []
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
251 f = min if direction == 1 else max
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
252 for _, facet in self.facets:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
253 minval = f([vertex[axis] for vertex in facet])
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
254 if direction * minval > direction * dist:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
255 continue
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
256 vertices = []
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
257 for vertex in facet:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
258 vertex = numpy.copy(vertex)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
259 if direction * (vertex[axis] - dist) > 0:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
260 vertex[axis] = dist
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
261 vertices.append(vertex)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
262 s.facets.append(genfacet(vertices))
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
263 s.insolid = 0
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
264 s.infacet = 0
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
265 s.inloop = 0
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
266 s.facetloc = 0
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
267 s.name = self.name
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
268 for facet in s.facets:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
269 s.facetsminz += [(min(map(lambda x:x[2], facet[1])), facet)]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
270 s.facetsmaxz += [(max(map(lambda x:x[2], facet[1])), facet)]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
271 return s
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
272
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
273 def translation_matrix(self, v):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
274 matrix = [[1, 0, 0, v[0]],
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
275 [0, 1, 0, v[1]],
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
276 [0, 0, 1, v[2]],
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
277 [0, 0, 0, 1]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
278 ]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
279 return numpy.array(matrix)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
280
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
281 def translate(self, v = [0, 0, 0]):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
282 return self.transform(self.translation_matrix(v))
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
283
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
284 def rotation_matrix(self, v):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
285 z = v[2]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
286 matrix1 = [[math.cos(math.radians(z)), -math.sin(math.radians(z)), 0, 0],
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
287 [math.sin(math.radians(z)), math.cos(math.radians(z)), 0, 0],
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
288 [0, 0, 1, 0],
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
289 [0, 0, 0, 1]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
290 ]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
291 matrix1 = numpy.array(matrix1)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
292 y = v[0]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
293 matrix2 = [[1, 0, 0, 0],
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
294 [0, math.cos(math.radians(y)), -math.sin(math.radians(y)), 0],
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
295 [0, math.sin(math.radians(y)), math.cos(math.radians(y)), 0],
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
296 [0, 0, 0, 1]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
297 ]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
298 matrix2 = numpy.array(matrix2)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
299 x = v[1]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
300 matrix3 = [[math.cos(math.radians(x)), 0, -math.sin(math.radians(x)), 0],
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
301 [0, 1, 0, 0],
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
302 [math.sin(math.radians(x)), 0, math.cos(math.radians(x)), 0],
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
303 [0, 0, 0, 1]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
304 ]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
305 matrix3 = numpy.array(matrix3)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
306 return matrix3.dot(matrix2.dot(matrix1))
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
307
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
308 def rotate(self, v = [0, 0, 0]):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
309 return self.transform(self.rotation_matrix(v))
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
310
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
311 def scale_matrix(self, v):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
312 matrix = [[v[0], 0, 0, 0],
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
313 [0, v[1], 0, 0],
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
314 [0, 0, v[2], 0],
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
315 [0, 0, 0, 1]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
316 ]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
317 return numpy.array(matrix)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
318
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
319 def scale(self, v = [0, 0, 0]):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
320 return self.transform(self.scale_matrix(v))
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
321
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
322 def transform(self, m = I):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
323 s = stl()
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
324 s.facets = [applymatrix(i, m) for i in self.facets]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
325 s.insolid = 0
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
326 s.infacet = 0
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
327 s.inloop = 0
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
328 s.facetloc = 0
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
329 s.name = self.name
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
330 for facet in s.facets:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
331 s.facetsminz += [(min(map(lambda x:x[2], facet[1])), facet)]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
332 s.facetsmaxz += [(max(map(lambda x:x[2], facet[1])), facet)]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
333 return s
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
334
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
335 def export(self, f = sys.stdout):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
336 f.write("solid " + self.name + "\n")
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
337 for i in self.facets:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
338 f.write(" facet normal " + " ".join(map(str, i[0])) + "\n")
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
339 f.write(" outer loop" + "\n")
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
340 for j in i[1]:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
341 f.write(" vertex " + " ".join(map(str, j)) + "\n")
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
342 f.write(" endloop" + "\n")
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
343 f.write(" endfacet" + "\n")
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
344 f.write("endsolid " + self.name + "\n")
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
345 f.flush()
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
346
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
347 def parseline(self, l):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
348 l = l.strip()
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
349 if l.startswith("solid"):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
350 self.insolid = 1
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
351 self.name = l[6:]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
352 elif l.startswith("endsolid"):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
353 self.insolid = 0
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
354 return 0
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
355 elif l.startswith("facet normal"):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
356 l = l.replace(", ", ".")
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
357 self.infacet = 1
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
358 self.facetloc = 0
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
359 normal = numpy.array(map(float, l.split()[2:]))
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
360 self.facet = (normal, (numpy.zeros(3), numpy.zeros(3), numpy.zeros(3)))
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
361 elif l.startswith("endfacet"):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
362 self.infacet = 0
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
363 self.facets.append(self.facet)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
364 facet = self.facet
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
365 self.facetsminz += [(min(map(lambda x:x[2], facet[1])), facet)]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
366 self.facetsmaxz += [(max(map(lambda x:x[2], facet[1])), facet)]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
367 elif l.startswith("vertex"):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
368 l = l.replace(", ", ".")
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
369 self.facet[1][self.facetloc][:] = numpy.array(map(float, l.split()[1:]))
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
370 self.facetloc += 1
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
371 return 1
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
372
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
373 if __name__ == "__main__":
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
374 s = stl("../../Downloads/frame-vertex-neo-foot-x4.stl")
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
375 for i in xrange(11, 11):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
376 working = s.facets[:]
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
377 for j in reversed(sorted(s.facetsminz)):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
378 if j[0] > i:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
379 working.remove(j[1])
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
380 else:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
381 break
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
382 for j in (sorted(s.facetsmaxz)):
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
383 if j[0] < i:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
384 working.remove(j[1])
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
385 else:
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
386 break
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
387
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
388 print i, len(working)
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
389 emitstl("../../Downloads/frame-vertex-neo-foot-x4-a.stl", s.facets, "emitted_object")
0bbb006204fc Added printrun sourcecode from
mbayer
parents:
diff changeset
390 # stl("../prusamendel/stl/mendelplate.stl")

mercurial