moved add_column to branches/broken_stuff/add_mesh_column.py it is broken for months...
[blender-addons-contrib.git] / add_mesh_cad_objects / stringer.py
1 # Stairbuilder - Stringer generation
2 #
3 # Generates stringer mesh for stair generation.
4 #   Stair Type (typ):
5 #       - id1 = Freestanding staircase
6 #       - id2 = Housed-open staircase
7 #       - id3 = Box staircase
8 #       - id4 = Circular staircase
9 #   Stringer Type (typ_s):
10 #       - sId1 = Classic
11 #       - sId2 = I-Beam
12 #       - sId3 = C-Beam
13
14 # Paul "BrikBot" Marshall
15 # Created: September 19, 2011
16 # Last Modified: January 29, 2011
17 # Homepage (blog): http://post.darkarsenic.com/
18 #                       //blog.darkarsenic.com/
19 #
20 # Coded in IDLE, tested in Blender 2.61.
21 # Search for "@todo" to quickly find sections that need work.
22 #
23 # ##### BEGIN GPL LICENSE BLOCK #####
24 #
25 #  Stairbuilder is for quick stair generation.
26 #  Copyright (C) 2011  Paul Marshall
27 #
28 #  This program is free software: you can redistribute it and/or modify
29 #  it under the terms of the GNU General Public License as published by
30 #  the Free Software Foundation, either version 3 of the License, or
31 #  (at your option) any later version.
32 #
33 #  This program is distributed in the hope that it will be useful,
34 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
35 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
36 #  GNU General Public License for more details.
37 #
38 #  You should have received a copy of the GNU General Public License
39 #  along with this program.  If not, see <http://www.gnu.org/licenses/>.
40 #
41 # ##### END GPL LICENSE BLOCK #####
42
43 from math import atan, cos, radians, tan
44 from mathutils import Matrix, Vector
45 from mathutils.geometry import (intersect_line_plane,
46                                 intersect_line_line)
47
48 class Stringer:
49     def  __init__(self,G,typ,typ_s,rise,run,w,h,nT,hT,wT,tT,tO,tw,tf,tp,g,
50                   nS=1,dis=False,notMulti=True,deg=4):
51         self.G = G #General
52         self.typ = typ # Stair type
53         self.typ_s = typ_s # Stringer type
54         self.rise = rise #Stair rise
55         self.run = run #Stair run. Degrees if self.typ == "id4"
56         if notMulti:
57             self.w = w / 100 #stringer width
58         else:
59             self.w = (wT * (w / 100)) / nS
60         self.h = h #stringer height
61         self.nT = nT #number of treads
62         self.hT = hT #tread height
63         self.wT = wT #tread width
64         self.tT = tT #tread toe
65         self.tO = tO #Tread overhang. Inner radius if self.typ == "id4"
66         self.tw = self.w * (tw / 100) #stringer web thickness
67         self.tf = tf #stringer flange thickness
68         self.tp = 1 - (tp / 100) #stringer flange taper
69         self.g = g #does stringer intersect the ground?
70         self.nS = nS #number of stringers
71         self.dis = dis #Use distributed stringers
72         self.deg = deg #number of sections per "slice". Only applys if self.typ == "id4"
73         # Default stringer object (classic / sId1):
74         self.faces1=[[0,1,3,2],[1,5,3],[3,5,4],[6,7,9,8],[7,11,9],[9,11,10],
75                      [0,2,8,6],[0,1,7,6],[1,5,11,7],[2,3,9,8],[3,4,10,9],[4,5,11,10]]
76         # Box stair type stringer:
77         self.faces2=[[0,1,7,6],[1,3,9,7],[3,4,10,9],[4,10,11,5],[5,11,8,2],
78                      [2,8,6,0],[0,1,2],[1,2,5,3],[3,4,5],[6,7,8],[7,8,11,9],[9,10,11]]
79         # I-beam stringer (id2 / sId2 / Taper < 100%):
80         self.faces3a=[[0,1,17,16],[1,2,18,17],[2,3,19,18],[3,4,20,19],[4,5,21,20],[5,6,22,21],
81                       [6,7,23,22],[7,8,24,23],[8,9,25,24],[9,10,26,25],[10,11,27,26],
82                       [11,12,28,27],[12,13,29,28],[13,14,30,29],[14,15,31,30],[15,0,16,31],
83                       [0,1,2,15],[2,11,14,15],[11,12,13,14],[2,3,10,11],[3,4,5,6],[3,6,7,10],
84                       [7,8,9,10],[16,17,18,31],[18,27,30,31],[27,28,29,30],[18,19,26,27],
85                       [19,20,21,22],[19,22,23,26],[23,24,25,26]]
86         # I-beam stringer (id2 / sId2 / Taper = 100%):
87         self.faces3b=[[0,1,9,8],[1,2,10,9],[2,3,11,10],[3,4,12,11],[4,5,13,12],[5,6,14,13],
88                       [6,7,15,14],[7,0,8,15],[0,1,6,7],[1,2,5,6],[2,3,4,5],[8,9,14,15],
89                       [9,10,13,14],[10,11,12,13]]
90         # I-beam stringer (id3 / sId2 / Taper < 100%):
91         self.faces3c=[[0,1,2,7],[2,3,6,7],[3,4,5,6],[1,2,23,16],[2,3,22,23],
92                       [3,4,21,22],[16,17,18,23],[18,19,22,23],[19,20,21,22],
93                       [17,8,15,18],[18,15,14,19],[19,14,13,20],[8,9,10,15],
94                       [10,11,14,15],[11,12,13,14],[9,10,53,52],[10,11,54,53],
95                       [11,12,55,54],[52,53,61,60],[53,54,62,61],[54,55,63,62],
96                       [60,61,34,33],[61,62,35,34],[62,63,36,35],[32,33,34,39],
97                       [34,35,38,39],[35,36,37,38],[41,32,39,42],[42,39,38,43],
98                       [43,38,37,44],[40,41,42,47],[42,43,46,47],[43,44,45,46],
99                       [25,26,47,40],[26,27,46,47],[27,28,45,46],[24,25,26,31],
100                       [26,27,30,31],[27,28,29,30],[24,31,57,56],[31,30,58,57],
101                       [30,29,59,58],[48,49,57,56],[49,50,58,57],[50,51,59,58],
102                       [0,7,49,48],[7,6,50,49],[6,5,51,50],[0,1,16,48],[16,40,56,48],
103                       [24,25,40,56],[16,17,41,40],[8,9,52,17],[17,52,60,41],
104                       [32,33,60,41],[12,13,20,55],[20,44,63,55],[37,44,63,36],
105                       [20,21,45,44],[28,29,51,21],[21,51,59,45],[28,45,59,29],
106                       [4,5,51,21]]
107         # C-beam stringer (id3 / sId3 / Taper < 100%):
108         self.faces4c=[[0,1,2,7],[2,3,6,7],[3,4,5,6],[1,2,23,16],[2,3,22,23],[3,4,21,22],
109                       [16,17,18,23],[18,19,22,23],[19,20,21,22],[17,8,15,18],[18,15,14,19],
110                       [19,14,13,20],[8,9,10,15],[10,11,14,15],[11,12,13,14],[0,24,25,7],
111                       [7,25,26,6],[6,26,27,5],[9,31,30,10],[10,30,29,11],[11,29,28,12],
112                       [24,25,30,31],[25,26,29,30],[26,27,28,29],[0,1,16,24],[16,24,31,17],
113                       [8,9,31,17],[4,5,27,21],[20,21,27,28],[12,13,20,28]]
114         self.Create()
115
116
117     def Create(self):
118         if self.typ == "id1":
119             if self.typ_s == "sId1":
120                 if self.dis or self.nS == 1:
121                     offset = (self.wT / (self.nS + 1)) - (self.w / 2)
122                 else:
123                     offset = 0
124                 for i in range(self.nS):
125                     for j in range(self.nT):
126                         coords = []
127                         coords.append(Vector([0, offset, -self.rise]))
128                         coords.append(Vector([self.run, offset, -self.rise]))
129                         coords.append(Vector([0, offset, -self.hT]))
130                         coords.append(Vector([self.run, offset, -self.hT]))
131                         coords.append(Vector([self.run, offset, 0]))
132                         coords.append(Vector([self.run * 2, offset, 0]))
133                         for k in range(6):
134                             coords.append(coords[k]+Vector([0, self.w, 0]))
135                         for k in coords:
136                             k += j*Vector([self.run, 0, self.rise])
137                         self.G.Make_mesh(coords,self.faces1,'stringer')
138                     if self.dis or self.nS == 1:
139                         offset += self.wT / (self.nS + 1)
140                     else:
141                         offset += (self.wT - self.w) / (self.nS - 1)
142             elif self.typ_s == "sId2":
143                 self.I_beam()
144         elif self.typ == "id2":
145             if self.typ_s == "sId1":
146                 coords = []
147                 coords.append(Vector([-self.tT, -self.w, -self.rise]))
148                 coords.append(Vector([self.hT / self.G.slope, -self.w, -self.rise]))
149                 coords.append(Vector([-self.tT, -self.w, 0]))
150                 coords.append(Vector([self.nT * self.run, -self.w,
151                                       ((self.nT - 1) * self.rise) - self.hT]))
152                 coords.append(Vector([self.nT * self.run, -self.w, self.nT * self.rise]))
153                 coords.append(Vector([(self.nT * self.run) - self.tT, -self.w,
154                                       self.nT * self.rise]))
155                 for i in range(6):
156                     coords.append(coords[i] + Vector([0, self.w, 0]))
157                 self.G.Make_mesh(coords, self.faces2, 'stringer')
158                 for i in coords:
159                     i += Vector([0, self.w + self.wT, 0])
160                 self.G.Make_mesh(coords, self.faces2, 'stringer')
161             elif self.typ_s == "sId2":
162                 self.housed_I_beam()
163             elif self.typ_s == "sId3":
164                 self.housed_C_beam()
165         elif self.typ == "id3":
166             h = (self.rise - self.hT) - self.rise #height of top section
167             for i in range(self.nT):
168                 coords = []
169                 coords.append(Vector([i * self.run,0,-self.rise]))
170                 coords.append(Vector([(i + 1) * self.run,0,-self.rise]))
171                 coords.append(Vector([i * self.run,0,h + (i * self.rise)]))
172                 coords.append(Vector([(i + 1) * self.run,0,h + (i * self.rise)]))
173                 for j in range(4):
174                     coords.append(coords[j] + Vector([0,self.wT,0]))
175                 self.G.Make_mesh(coords, self.G.faces, 'stringer')
176         elif self.typ == "id4":
177             offset = (self.wT / (self.nS + 1)) - (self.w / 2)
178             for s in range(self.nS):
179                 base = self.tO + (offset * (s + 1))
180                 start = [Vector([0, -base, -self.hT]),
181                          Vector([0, -base, -self.hT - self.rise]),
182                          Vector([0, -base - self.w, -self.hT]),
183                          Vector([0, -base - self.w, -self.hT - self.rise])]
184                 self.d = radians(self.run) / self.nT
185                 for i in range(self.nT):
186                     coords = []
187                     # Base faces.  Should be able to append more sections:
188                     tId4_faces = [[0, 1, 3, 2]]
189                     t_inner = Matrix.Rotation(self.d * i, 3, 'Z')
190                     coords.append((t_inner * start[0]) + Vector([0, 0, self.rise * i]))
191                     coords.append((t_inner * start[1]) + Vector([0, 0, self.rise * i]))
192                     t_outer = Matrix.Rotation(self.d * i, 3, 'Z')
193                     coords.append((t_outer * start[2]) + Vector([0, 0, self.rise * i]))
194                     coords.append((t_outer * start[3]) + Vector([0, 0, self.rise * i]))
195                     k = 0
196                     for j in range(self.deg):
197                         k = (j * 4) + 4
198                         tId4_faces.append([k, k - 4, k - 3, k + 1])
199                         tId4_faces.append([k - 2, k - 1, k + 3, k + 2])
200                         tId4_faces.append([k + 1, k - 3, k - 1, k + 3])
201                         tId4_faces.append([k, k - 4, k - 2, k + 2])
202                         rot = Matrix.Rotation(((self.d * (j + 1)) / self.deg) + (self.d * i), 3, 'Z')
203                         for v in start:
204                             coords.append((rot * v) + Vector([0, 0, self.rise * i]))
205                     for j in range(self.deg):
206                         k = ((j + self.deg) * 4) + 4
207                         tId4_faces.append([k, k - 4, k - 3, k + 1])
208                         tId4_faces.append([k - 2, k - 1, k + 3, k + 2])
209                         tId4_faces.append([k + 1, k - 3, k - 1, k + 3])
210                         tId4_faces.append([k, k - 4, k - 2, k + 2])
211                         rot = Matrix.Rotation(((self.d * ((j + self.deg) + 1)) / self.deg) + (self.d * i), 3, 'Z')
212                         for v in range(4):
213                             if v in [1, 3]:
214                                 incline = (self.rise * i) + (self.rise / self.deg) * (j + 1)
215                                 coords.append((rot * start[v]) + Vector([0, 0, incline]))
216                             else:
217                                 coords.append((rot * start[v]) + Vector([0, 0, self.rise * i]))
218                     self.G.Make_mesh(coords, tId4_faces, 'treads')
219
220         return {'FINISHED'}
221
222
223     def I_beam(self):
224         mid = self.w / 2
225         web = self.tw / 2
226         # Bottom of the stringer:
227         baseZ = -self.rise - self.hT - self.h
228         # Top of the strigner:
229         topZ = -self.rise - self.hT
230         # Vertical taper amount:
231         taper = self.tf * self.tp
232
233         if self.dis or self.nS == 1:
234             offset = (self.wT / (self.nS + 1)) - mid
235         else:
236             offset = 0
237
238         # taper < 100%:
239         if self.tp > 0:
240             for i in range(self.nS):
241                 coords = []
242                 coords.append(Vector([0, offset,                baseZ]))
243                 coords.append(Vector([0, offset,                baseZ + taper]))
244                 coords.append(Vector([0, offset + (mid - web),  baseZ + self.tf]))
245                 coords.append(Vector([0, offset + (mid - web),  topZ - self.tf]))
246                 coords.append(Vector([0, offset,                topZ - taper]))
247                 coords.append(Vector([0, offset,                topZ]))
248                 coords.append(Vector([0, offset + (mid - web),  topZ]))
249                 coords.append(Vector([0, offset + (mid + web),  topZ]))
250                 coords.append(Vector([0, offset + self.w,       topZ]))
251                 coords.append(Vector([0, offset + self.w,       topZ - taper]))
252                 coords.append(Vector([0, offset + (mid + web),  topZ - self.tf]))
253                 coords.append(Vector([0, offset + (mid + web),  baseZ + self.tf]))
254                 coords.append(Vector([0, offset + self.w,       baseZ + taper]))
255                 coords.append(Vector([0, offset + self.w,       baseZ]))
256                 coords.append(Vector([0, offset + (mid + web),  baseZ]))
257                 coords.append(Vector([0, offset + (mid - web),  baseZ]))
258                 for j in range(16):
259                     coords.append(coords[j]+Vector([self.run * self.nT, 0, self.rise * self.nT]))
260                 # If the bottom meets the ground:
261                 #   Bottom be flat with the xy plane, but shifted down.
262                 #   Either project onto the plane along a vector (hard) or use the built in
263                 #       interest found in mathutils.geometry (easy).  Using intersect:
264                 if self.g:
265                     for j in range(16):
266                         coords[j] = intersect_line_plane(coords[j], coords[j + 16],
267                                                          Vector([0, 0, topZ]),
268                                                          Vector([0, 0, 1]))
269                 self.G.Make_mesh(coords, self.faces3a, 'stringer')
270
271                 if self.dis or self.nS == 1:
272                     offset += self.wT / (self.nS + 1)
273                 else:
274                     offset += (self.wT - self.w) / (self.nS - 1)
275         # taper = 100%:
276         else:
277             for i in range(self.nS):
278                 coords = []
279                 coords.append(Vector([0, offset,                baseZ]))
280                 coords.append(Vector([0, offset + (mid - web),  baseZ + self.tf]))
281                 coords.append(Vector([0, offset + (mid - web),  topZ - self.tf]))
282                 coords.append(Vector([0, offset,                topZ]))
283                 coords.append(Vector([0, offset + self.w,       topZ]))
284                 coords.append(Vector([0, offset + (mid + web),  topZ - self.tf]))
285                 coords.append(Vector([0, offset + (mid + web),  baseZ + self.tf]))
286                 coords.append(Vector([0, offset + self.w,       baseZ]))
287                 for j in range(8):
288                     coords.append(coords[j]+Vector([self.run * self.nT, 0, self.rise * self.nT]))
289                 self.G.Make_mesh(coords, self.faces3b, 'stringer')
290                 offset += self.wT / (self.nS + 1)
291                 
292         return {'FINISHED'}
293
294
295     def housed_I_beam(self):
296         webOrth = Vector([self.rise, 0, -self.run]).normalized()
297         webHeight = Vector([self.run + self.tT, 0, -self.hT]).project(webOrth).length
298         vDelta_1 = self.tf * tan(self.G.angle)
299         vDelta_2 = (self.rise * (self.nT - 1)) - (webHeight + self.tf)
300         flange_y = (self.w - self.tw) / 2
301         front = -self.tT - self.tf
302         outer = -self.tO - self.tw - flange_y
303
304         coords = []
305         if self.tp > 0:
306             # Upper-Outer flange:
307             coords.append(Vector([front, outer, -self.rise]))
308             coords.append(Vector([-self.tT, outer, -self.rise]))
309             coords.append(Vector([-self.tT, outer, 0]))
310             coords.append(Vector([(self.run * (self.nT - 1)) - self.tT, outer,
311                                   self.rise * (self.nT - 1)]))
312             coords.append(Vector([self.run * self.nT, outer,
313                                   self.rise * (self.nT - 1)]))
314             coords.append(Vector([self.run * self.nT, outer,
315                                   (self.rise * (self.nT - 1)) + self.tf]))
316             coords.append(Vector([(self.run * (self.nT - 1)) - self.tT, outer,
317                                   (self.rise * (self.nT - 1)) + self.tf]))
318             coords.append(Vector([front, outer, self.tf - vDelta_1]))
319             # Lower-Outer flange:
320             coords.append(coords[0] + Vector([self.tf + webHeight, 0, 0]))
321             coords.append(coords[1] + Vector([self.tf + webHeight, 0, 0]))
322             coords.append(intersect_line_line(coords[9],
323                                               coords[9] - Vector([0, 0, 1]),
324                                               Vector([self.run, 0, -self.hT - self.tf]),
325                                               Vector([self.run * 2, 0, self.rise - self.hT - self.tf]))[0])
326             coords.append(Vector([(self.run * self.nT) - ((webHeight - self.hT) / tan(self.G.angle)),
327                                   outer, vDelta_2]))
328             coords.append(coords[4] - Vector([0, 0, self.tf + webHeight]))
329             coords.append(coords[5] - Vector([0, 0, self.tf + webHeight]))
330             coords.append(coords[11] + Vector([0, 0, self.tf]))
331             coords.append(intersect_line_line(coords[8],
332                                               coords[8] - Vector([0, 0, 1]),
333                                               Vector([self.run, 0, -self.hT]),
334                                               Vector([self.run * 2, 0, self.rise - self.hT]))[0])
335             # Outer web:
336             coords.append(coords[1] + Vector([0, flange_y, 0]))
337             coords.append(coords[8] + Vector([0, flange_y, 0]))
338             coords.append(coords[15] + Vector([0, flange_y, 0]))
339             coords.append(coords[14] + Vector([0, flange_y, 0]))
340             coords.append(coords[13] + Vector([0, flange_y, 0]))
341             coords.append(coords[4] + Vector([0, flange_y, 0]))
342             coords.append(coords[3] + Vector([0, flange_y, 0]))
343             coords.append(coords[2] + Vector([0, flange_y, 0]))
344             # Upper-Inner flange and lower-inner flange:
345             for i in range(16):
346                 coords.append(coords[i] + Vector([0, self.w, 0]))
347             # Inner web:
348             for i in range(8):
349                 coords.append(coords[i + 16] + Vector([0, self.tw, 0]))
350             # Mid nodes to so faces will be quads:
351             for i in [0,7,6,5,9,10,11,12]:
352                 coords.append(coords[i] + Vector([0, flange_y, 0]))
353             for i in range(8):
354                 coords.append(coords[i + 48] + Vector([0, self.tw, 0]))
355
356             self.G.Make_mesh(coords, self.faces3c, 'stringer')
357
358             for i in coords:
359                 i += Vector([0, self.wT + self.tw, 0])
360
361             self.G.Make_mesh(coords, self.faces3c, 'stringer')
362
363         # @TODO Taper = 100%
364         
365         return {'FINISHED'}
366
367
368     def C_Beam(self):
369         mid = self.w / 2
370         web = self.tw / 2
371         # Bottom of the stringer:
372         baseZ = -self.rise - self.hT - self.h
373         # Top of the strigner:
374         topZ = -self.rise - self.hT
375         # Vertical taper amount:
376         taper = self.tf * self.tp
377
378         if self.dis or self.nS == 1:
379             offset = (self.wT / (self.nS + 1)) - mid
380         else:
381             offset = 0
382
383         # taper < 100%:
384         if self.tp > 0:
385             for i in range(self.nS):
386                 coords = []
387                 coords.append(Vector([0, offset,                baseZ]))
388                 coords.append(Vector([0, offset,                baseZ + taper]))
389                 coords.append(Vector([0, offset + (mid - web),  baseZ + self.tf]))
390                 coords.append(Vector([0, offset + (mid - web),  topZ - self.tf]))
391                 coords.append(Vector([0, offset,                topZ - taper]))
392                 coords.append(Vector([0, offset,                topZ]))
393                 coords.append(Vector([0, offset + (mid - web),  topZ]))
394                 coords.append(Vector([0, offset + (mid + web),  topZ]))
395                 coords.append(Vector([0, offset + self.w,       topZ]))
396                 coords.append(Vector([0, offset + self.w,       topZ - taper]))
397                 coords.append(Vector([0, offset + (mid + web),  topZ - self.tf]))
398                 coords.append(Vector([0, offset + (mid + web),  baseZ + self.tf]))
399                 coords.append(Vector([0, offset + self.w,       baseZ + taper]))
400                 coords.append(Vector([0, offset + self.w,       baseZ]))
401                 coords.append(Vector([0, offset + (mid + web),  baseZ]))
402                 coords.append(Vector([0, offset + (mid - web),  baseZ]))
403                 for j in range(16):
404                     coords.append(coords[j]+Vector([self.run * self.nT, 0, self.rise * self.nT]))
405                 # If the bottom meets the ground:
406                 #   Bottom be flat with the xy plane, but shifted down.
407                 #   Either project onto the plane along a vector (hard) or use the built in
408                 #       interest found in mathutils.geometry (easy).  Using intersect:
409                 if self.g:
410                     for j in range(16):
411                         coords[j] = intersect_line_plane(coords[j], coords[j + 16],
412                                                          Vector([0, 0, topZ]),
413                                                          Vector([0, 0, 1]))
414                 self.G.Make_mesh(coords, self.faces3a, 'stringer')
415
416                 if self.dis or self.nS == 1:
417                     offset += self.wT / (self.nS + 1)
418                 else:
419                     offset += (self.wT - self.w) / (self.nS - 1)
420         # taper = 100%:
421         else:
422             for i in range(self.nS):
423                 coords = []
424                 coords.append(Vector([0, offset,                baseZ]))
425                 coords.append(Vector([0, offset + (mid - web),  baseZ + self.tf]))
426                 coords.append(Vector([0, offset + (mid - web),  topZ - self.tf]))
427                 coords.append(Vector([0, offset,                topZ]))
428                 coords.append(Vector([0, offset + self.w,       topZ]))
429                 coords.append(Vector([0, offset + (mid + web),  topZ - self.tf]))
430                 coords.append(Vector([0, offset + (mid + web),  baseZ + self.tf]))
431                 coords.append(Vector([0, offset + self.w,       baseZ]))
432                 for j in range(8):
433                     coords.append(coords[j]+Vector([self.run * self.nT, 0, self.rise * self.nT]))
434                 self.G.Make_mesh(coords, self.faces3b, 'stringer')
435                 offset += self.wT / (self.nS + 1)
436                 
437         return {'FINISHED'}
438
439
440     def housed_C_beam(self):
441         webOrth = Vector([self.rise, 0, -self.run]).normalized()
442         webHeight = Vector([self.run + self.tT, 0, -self.hT]).project(webOrth).length
443         vDelta_1 = self.tf * tan(self.G.angle)
444         vDelta_2 = (self.rise * (self.nT - 1)) - (webHeight + self.tf)
445         flange_y = (self.w - self.tw) / 2
446         front = -self.tT - self.tf
447         outer = -self.tO - self.tw - flange_y
448
449         coords = []
450         if self.tp > 0:
451             # Upper-Outer flange:
452             coords.append(Vector([front, outer, -self.rise]))
453             coords.append(Vector([-self.tT, outer, -self.rise]))
454             coords.append(Vector([-self.tT, outer, 0]))
455             coords.append(Vector([(self.run * (self.nT - 1)) - self.tT, outer,
456                                   self.rise * (self.nT - 1)]))
457             coords.append(Vector([self.run * self.nT, outer,
458                                   self.rise * (self.nT - 1)]))
459             coords.append(Vector([self.run * self.nT, outer,
460                                   (self.rise * (self.nT - 1)) + self.tf]))
461             coords.append(Vector([(self.run * (self.nT - 1)) - self.tT, outer,
462                                   (self.rise * (self.nT - 1)) + self.tf]))
463             coords.append(Vector([front, outer, self.tf - vDelta_1]))
464             # Lower-Outer flange:
465             coords.append(coords[0] + Vector([self.tf + webHeight, 0, 0]))
466             coords.append(coords[1] + Vector([self.tf + webHeight, 0, 0]))
467             coords.append(intersect_line_line(coords[9],
468                                               coords[9] - Vector([0, 0, 1]),
469                                               Vector([self.run, 0, -self.hT - self.tf]),
470                                               Vector([self.run * 2, 0, self.rise - self.hT - self.tf]))[0])
471             coords.append(Vector([(self.run * self.nT) - ((webHeight - self.hT) / tan(self.G.angle)),
472                                   outer, vDelta_2]))
473             coords.append(coords[4] - Vector([0, 0, self.tf + webHeight]))
474             coords.append(coords[5] - Vector([0, 0, self.tf + webHeight]))
475             coords.append(coords[11] + Vector([0, 0, self.tf]))
476             coords.append(intersect_line_line(coords[8],
477                                               coords[8] - Vector([0, 0, 1]),
478                                               Vector([self.run, 0, -self.hT]),
479                                               Vector([self.run * 2, 0, self.rise - self.hT]))[0])
480             # Outer web:
481             coords.append(coords[1] + Vector([0, flange_y, 0]))
482             coords.append(coords[8] + Vector([0, flange_y, 0]))
483             coords.append(coords[15] + Vector([0, flange_y, 0]))
484             coords.append(coords[14] + Vector([0, flange_y, 0]))
485             coords.append(coords[13] + Vector([0, flange_y, 0]))
486             coords.append(coords[4] + Vector([0, flange_y, 0]))
487             coords.append(coords[3] + Vector([0, flange_y, 0]))
488             coords.append(coords[2] + Vector([0, flange_y, 0]))
489             # Outer corner nodes:
490             for i in [0, 7, 6, 5, 12, 11, 10, 9]:
491                 coords.append(coords[i] + Vector([0, flange_y + self.tw, 0]))
492
493             self.G.Make_mesh(coords, self.faces4c, 'stringer')
494
495             for i in range(16):
496                 coords[i] += Vector([0, -outer * 2, 0])
497             for i in range(8):
498                 coords[i + 16] += Vector([0, (-outer - flange_y) * 2, 0])
499             for i in coords:
500                 i += Vector([0, (self.tO * 2) + self.wT, 0])
501
502             self.G.Make_mesh(coords, self.faces4c, 'stringer')
503         
504         return {'FINISHED'}