printrun-src/printrun/stltool.py

Wed, 20 Jan 2021 10:15:13 +0100

author
mdd
date
Wed, 20 Jan 2021 10:15:13 +0100
changeset 46
cce0af6351f0
parent 15
0bbb006204fc
permissions
-rw-r--r--

updated and added new files for printrun

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

mercurial