Fix T54414: Address changes to object.ray_cast, cleanup
[blender-addons-contrib.git] / add_mesh_space_tree / simplefork.py
1 # ##### BEGIN GPL LICENSE BLOCK #####
2 #
3 #  SCA Tree Generator,  a Blender addon
4 #  (c) 2013 Michel J. Anders (varkenvarken)
5 #
6 #  This program is free software; you can redistribute it and/or
7 #  modify it under the terms of the GNU General Public License
8 #  as published by the Free Software Foundation; either version 2
9 #  of the License,  or (at your option) any later version.
10 #
11 #  This program is distributed in the hope that it will be useful,
12 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 #  GNU General Public License for more details.
15 #
16 #  You should have received a copy of the GNU General Public License
17 #  along with this program; if not,  write to the Free Software Foundation,
18 #  Inc.,  51 Franklin Street,  Fifth Floor,  Boston,  MA 02110-1301,  USA.
19 #
20 # ##### END GPL LICENSE BLOCK #####
21
22 # <pep8 compliant>
23
24 from math import pi
25 from mathutils import Quaternion
26
27 rot120 = 2 * pi / 3
28
29
30 def rot(point, axis, angle):
31     q = Quaternion(axis, angle)
32     P = point.copy()
33     P.rotate(q)
34     # print(point, P)
35     return P
36
37
38 def vertexnormal(d1, d2, d3):
39     n1 = d1.cross(d2).normalized()
40     n2 = d2.cross(d3).normalized()
41     n3 = d3.cross(d1).normalized()
42     n = (n1 + n2 + n3).normalized()
43     if (d1 + d2 + d3).dot(n) > 0:
44         return -n
45     return n
46
47
48 def simplefork2(p0, p1, p2, p3, r0, r1, r2, r3):
49     d1 = p1 - p0
50     d2 = p2 - p0
51     d3 = p3 - p0
52     # print(d1, d2, d3)
53     n = vertexnormal(d1, d2, d3)
54     # print(n)
55
56     pp1 = p0 + d1 / 3
57     n1a = r1 * n
58     n1b = rot(n1a, d1, rot120)
59     n1c = rot(n1a, d1, -rot120)
60     v1a = pp1 + n1a
61     v1b = pp1 + n1b
62     v1c = pp1 + n1c
63
64     pp2 = p0 + d2 / 3
65     n2a = r2 * n
66     n2b = rot(n2a, d2, rot120)
67     n2c = rot(n2a, d2, -rot120)
68     v2a = pp2 + n2a
69     v2b = pp2 + n2b
70     v2c = pp2 + n2c
71
72     pp3 = p0 + d3 / 3
73     n3a = r3 * n
74     n3b = rot(n3a, d3, rot120)
75     n3c = rot(n3a, d3, -rot120)
76     v3a = pp3 + n3a
77     v3b = pp3 + n3b
78     v3c = pp3 + n3c
79
80     n0a = n * r0
81     v0a = p0 + n0a
82     v0c = p0 - d3.normalized() * r0 - n0a / 3
83     v0d = p0 - d1.normalized() * r0 - n0a / 3
84     v0b = p0 - d2.normalized() * r0 - n0a / 3
85
86     # v0b=p0+(n1b+n2c)/2
87     # v0d=p0+(n2b+n3c)/2
88     # v0c=p0+(n3b+n1c)/2
89
90     verts = (v1a, v1b, v1c, v2a, v2b, v2c, v3a, v3b, v3c, v0a, v0b, v0c, v0d)
91     faces = ((0, 1, 10, 9), (1, 2, 11, 10), (2, 0, 9, 11),  # chck
92         (3, 4, 11, 9), (4, 5, 12, 11), (5, 3, 9, 12),  # chck
93
94         (6, 7, 12, 9),
95         (7, 8, 10, 12),
96         (8, 6, 9, 10),
97
98         (10, 11, 12))
99
100     return verts, faces
101
102
103 def simplefork(p0, p1, p2, p3, r0, r1, r2, r3):
104     d1 = p1 - p0
105     d2 = p2 - p0
106     d3 = p3 - p0
107     # print(d1, d2, d3)
108     n = -vertexnormal(d1, d2, d3)
109     # print(n)
110
111     # the central tetrahedron
112     n0a = n * r0 * 0.3
113     v0a = n0a
114     v0b = -d1 / 6 - n0a / 2
115     v0c = -d2 / 6 - n0a / 2
116     v0d = -d3 / 6 - n0a / 2
117
118     n1 = v0a + v0c + v0d
119     n2 = v0a + v0b + v0d
120     n3 = v0a + v0b + v0c
121
122     q1 = n1.rotation_difference(d1)
123     q2 = n2.rotation_difference(d2)
124     q3 = n3.rotation_difference(d3)
125
126     pp1 = p0 + d1 / 3
127     v1a = v0a.copy()
128     v1b = v0c.copy()
129     v1c = v0d.copy()
130     v1a.rotate(q1)
131     v1b.rotate(q1)
132     v1c.rotate(q1)
133     v1a += pp1
134     v1b += pp1
135     v1c += pp1
136
137     pp2 = p0 + d2 / 3
138     v2a = v0a.copy()
139     v2b = v0b.copy()
140     v2c = v0d.copy()
141     v2a.rotate(q2)
142     v2b.rotate(q2)
143     v2c.rotate(q2)
144     v2a += pp2
145     v2b += pp2
146     v2c += pp2
147
148     pp3 = p0 + d3 / 3
149     v3a = v0a.copy()
150     v3b = v0b.copy()
151     v3c = v0c.copy()
152     v3a.rotate(q3)
153     v3b.rotate(q3)
154     v3c.rotate(q3)
155     v3a += pp3
156     v3b += pp3
157     v3c += pp3
158
159     v0a += p0
160     v0b += p0
161     v0c += p0
162     v0d += p0
163
164     verts = (v1a, v1b, v1c, v2a, v2b, v2c, v3a, v3b, v3c, v0a, v0b, v0c, v0d)
165     faces = (
166         # (1, 2, 12, 11),
167         # (9, 12, 2, 0),
168         # (11, 9, 0, 1),
169
170         # (5, 4, 10, 12),
171         # (4, 3, 9, 10),
172         # (3, 5, 12, 9),
173
174         (8, 7, 11, 10),
175         (7, 5, 9, 11),
176         (6, 8, 10, 9),
177
178         (10, 11, 12))
179
180     return verts, faces
181
182
183 def bridgequads(aquad, bquad, verts):
184     "return faces,  aloop,  bloop"
185     ai, bi, _ = min([(ai, bi, (verts[a] - verts[b]).length_squared) for ai, a in
186                     enumerate(aquad) for bi, b in enumerate(bquad)], key=lambda x: x[2])
187     n = len(aquad)
188     # print([(aquad[(ai+i)%n],  aquad[(ai+i+1)%n],  bquad[(bi+i+1)%n],
189     #         bquad[(bi+i)%n]) for i in range(n)], "\n",  [aquad[(ai+i)%n] for i in range(n)],
190     #        "\n",   [aquad[(bi+i)%n] for i in range(n)])
191
192     # print('bridgequads', aquad, bquad, ai, bi)
193
194     return ([(aquad[(ai + i) % n], aquad[(ai + i + 1) % n], bquad[(bi + i + 1) % n],
195               bquad[(bi + i) % n]) for i in range(n)],
196              [aquad[(ai + i) % n] for i in range(n)],
197              [bquad[(bi + i) % n] for i in range(n)]
198             )
199
200
201 def quadfork(p0, p1, p2, p3, r0, r1, r2, r3):
202     d1 = p1 - p0
203     d2 = p2 - p0
204     d3 = p3 - p0
205     a = (d3 - d2).normalized()
206     n = d2.cross(d3).normalized()
207     pp1 = p0 + d1 / 3
208     pp2 = p0 + d2 / 3
209     pp3 = p0 + d3 / 3
210
211     v2a = pp2 + (n + a) * r2
212     v2b = pp2 + (n - a) * r2
213     v2c = pp2 + (-n - a) * r2
214     v2d = pp2 + (-n + a) * r2
215
216     v3a = pp3 + (n + a) * r3
217     v3b = pp3 + (n - a) * r3
218     v3c = pp3 + (-n - a) * r3
219     v3d = pp3 + (-n + a) * r3
220
221     a = d1.cross(n).normalized()
222     n = a.cross(d1).normalized()
223     v1a = pp1 + (n + a) * r1
224     v1b = pp1 + (n - a) * r1
225     v1c = pp1 + (-n - a) * r1
226     v1d = pp1 + (-n + a) * r1
227
228     # the top of the connecting block consist of two quads
229     v0a = p0 + (n + a) * r0
230     v0b = p0 + (n - a) * r0
231     v0c = p0 + (-n - a) * r0
232     v0d = p0 + (-n + a) * r0
233     v0ab = p0 + n * r0
234     v0cd = p0 - n * r0
235     # the bottom is a single quad (which means the front and back are 5gons)
236     d = d1.normalized() * r0 * 0.1
237     vb0a = v0a + d
238     vb0b = v0b + d
239     vb0c = v0c + d
240     vb0d = v0d + d
241
242     verts = [
243         v1a, v1b, v1c, v1d,               # 0 1 2 3
244         v2a, v2b, v2c, v2d,               # 4 5 6 7
245         v3a, v3b, v3c, v3d,               # 8 9 10 11
246         v0a, v0ab, v0b, v0c, v0cd, v0d,   # 12 13 14 15 16 17
247         vb0a, vb0b, vb0c, vb0d            # 18 19 20 21
248     ]
249
250     faces = [
251         (0, 1, 19, 18),          # p1->p0 bottom
252         (1, 2, 20, 19),
253         (2, 3, 21, 20),
254         (3, 0, 18, 21),
255
256         # (4, 5, 14, 13),        # p2 -> p0 top right
257         # (5, 6, 15, 14),
258         # (6, 7, 16, 15),
259         # (7, 4, 13, 16),
260
261         (13, 14, 5, 4),
262         (14, 15, 6, 5),
263         (15, 16, 7, 6),
264         (16, 13, 4, 7),
265
266         # (8, 9, 13, 12),        # p3 -> p0 top left
267         # (9, 10, 16, 13),
268         # (10, 11, 17, 16),
269         # (11, 8, 12, 17),
270
271         (12, 13, 9, 8),
272         (13, 16, 10, 9),
273         (16, 17, 11, 10),
274         (17, 12, 8, 11),
275
276         # (12, 17, 21, 18),      # connecting block
277         # (14, 15, 20, 19),
278         # (12, 13, 14, 19, 18),
279         # (15, 16, 17, 21, 20)]
280
281         (12, 17, 21, 18),        # connecting block
282         (19, 20, 15, 14),
283         (18, 19, 14, 13, 12),
284         (20, 21, 17, 16, 15)]
285
286     return verts, faces