Merge branch 'blender-v2.92-release'
[blender-addons.git] / add_mesh_BoltFactory / createMesh.py
blobe19f15baae723d7d800e59752c3992c8cc777bd6
1 # ##### BEGIN GPL LICENSE BLOCK #####
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software Foundation,
15 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 # ##### END GPL LICENSE BLOCK #####
19 import bpy
20 from mathutils import (
21 Matrix,
22 Vector,
23 geometry,
25 from math import (
26 sin, cos,
27 tan, radians,atan,degrees
29 from random import triangular
30 from bpy_extras.object_utils import AddObjectHelper, object_data_add
32 NARROW_UI = 180
33 MAX_INPUT_NUMBER = 50
35 GLOBAL_SCALE = 1 # 1 blender unit = X mm
38 # next two utility functions are stolen from import_obj.py
40 def unpack_list(list_of_tuples):
41 l = []
42 for t in list_of_tuples:
43 l.extend(t)
44 return l
47 def unpack_face_list(list_of_tuples):
48 l = []
49 for t in list_of_tuples:
50 face = [i for i in t]
52 if len(face) != 3 and len(face) != 4:
53 raise RuntimeError("{0} vertices in face".format(len(face)))
55 # rotate indices if the 4th is 0
56 if len(face) == 4 and face[3] == 0:
57 face = [face[3], face[0], face[1], face[2]]
59 if len(face) == 3:
60 face.append(0)
62 l.extend(face)
64 return l
67 """
68 Remove Doubles takes a list on Verts and a list of Faces and
69 removes the doubles, much like Blender does in edit mode.
70 It doesn't have the range function but it will round the corrdinates
71 and remove verts that are very close together. The function
72 is useful because you can perform a "Remove Doubles" with out
73 having to enter Edit Mode. Having to enter edit mode has the
74 disadvantage of not being able to interactively change the properties.
75 """
78 def RemoveDoubles(verts, faces, Decimal_Places=4):
80 new_verts = []
81 new_faces = []
82 dict_verts = {}
83 Rounded_Verts = []
85 for v in verts:
86 Rounded_Verts.append([round(v[0], Decimal_Places),
87 round(v[1], Decimal_Places),
88 round(v[2], Decimal_Places)])
90 for face in faces:
91 new_face = []
92 for vert_index in face:
93 Real_co = tuple(verts[vert_index])
94 Rounded_co = tuple(Rounded_Verts[vert_index])
96 if Rounded_co not in dict_verts:
97 dict_verts[Rounded_co] = len(dict_verts)
98 new_verts.append(Real_co)
99 if dict_verts[Rounded_co] not in new_face:
100 new_face.append(dict_verts[Rounded_co])
101 if len(new_face) == 3 or len(new_face) == 4:
102 new_faces.append(new_face)
104 return new_verts, new_faces
107 def Scale_Mesh_Verts(verts, scale_factor):
108 Ret_verts = []
109 for v in verts:
110 Ret_verts.append([v[0] * scale_factor, v[1] * scale_factor, v[2] * scale_factor])
111 return Ret_verts
114 # Create a matrix representing a rotation.
116 # Parameters:
118 # * angle (float) - The angle of rotation desired.
119 # * matSize (int) - The size of the rotation matrix to construct. Can be 2d, 3d, or 4d.
120 # * axisFlag (string (optional)) - Possible values:
121 # o "x - x-axis rotation"
122 # o "y - y-axis rotation"
123 # o "z - z-axis rotation"
124 # o "r - arbitrary rotation around vector"
125 # * axis (Vector object. (optional)) - The arbitrary axis of rotation used with "R"
127 # Returns: Matrix object.
128 # A new rotation matrix.
130 def Simple_RotationMatrix(angle, matSize, axisFlag):
131 if matSize != 4:
132 print("Simple_RotationMatrix can only do 4x4")
134 q = radians(angle) # make the rotation go clockwise
136 if axisFlag == 'x':
137 matrix = Matrix.Rotation(q, 4, 'X')
138 elif axisFlag == 'y':
139 matrix = Matrix.Rotation(q, 4, 'Y')
140 elif axisFlag == 'z':
141 matrix = Matrix.Rotation(q, 4, 'Z')
142 else:
143 print("Simple_RotationMatrix can only do x y z axis")
144 return matrix
147 # ####################################################################
148 # Converter Functions For Bolt Factory
149 # ####################################################################
151 def Flat_To_Radius(FLAT):
152 h = (float(FLAT) / 2) / cos(radians(30))
153 return h
156 def Get_Phillips_Bit_Height(Bit_Dia):
157 Flat_Width_half = (Bit_Dia * (0.5 / 1.82)) / 2.0
158 Bit_Rad = Bit_Dia / 2.0
159 x = Bit_Rad - Flat_Width_half
160 y = tan(radians(60)) * x
161 return float(y)
164 # ####################################################################
165 # Miscellaneous Utilities
166 # ####################################################################
168 # Returns a list of verts rotated by the given matrix. Used by SpinDup
169 def Rot_Mesh(verts, matrix):
170 from mathutils import Vector
171 return [(matrix @ Vector(v))[:] for v in verts]
174 # Returns a list of faces that has there index incremented by offset
175 def Copy_Faces(faces, offset):
176 return [[(i + offset) for i in f] for f in faces]
179 # Much like Blenders built in SpinDup
180 def SpinDup(VERTS, FACES, DEGREE, DIVISIONS, AXIS):
181 verts = []
182 faces = []
184 if DIVISIONS == 0:
185 DIVISIONS = 1
187 step = DEGREE / DIVISIONS # set step so pieces * step = degrees in arc
189 for i in range(int(DIVISIONS)):
190 rotmat = Simple_RotationMatrix(step * i, 4, AXIS) # 4x4 rotation matrix, 30d about the x axis.
191 Rot = Rot_Mesh(VERTS, rotmat)
192 faces.extend(Copy_Faces(FACES, len(verts)))
193 verts.extend(Rot)
194 return verts, faces
197 # Returns a list of verts that have been moved up the z axis by DISTANCE
198 def Move_Verts_Up_Z(VERTS, DISTANCE):
199 ret = []
200 for v in VERTS:
201 ret.append([v[0], v[1], v[2] + DISTANCE])
202 return ret
205 # Returns a list of verts and faces that has been mirrored in the AXIS
206 def Mirror_Verts_Faces(VERTS, FACES, AXIS, FLIP_POINT=0):
207 ret_vert = []
208 ret_face = []
209 offset = len(VERTS)
210 if AXIS == 'y':
211 for v in VERTS:
212 Delta = v[0] - FLIP_POINT
213 ret_vert.append([FLIP_POINT - Delta, v[1], v[2]])
214 if AXIS == 'x':
215 for v in VERTS:
216 Delta = v[1] - FLIP_POINT
217 ret_vert.append([v[0], FLIP_POINT - Delta, v[2]])
218 if AXIS == 'z':
219 for v in VERTS:
220 Delta = v[2] - FLIP_POINT
221 ret_vert.append([v[0], v[1], FLIP_POINT - Delta])
223 for f in FACES:
224 fsub = []
225 for i in range(len(f)):
226 fsub.append(f[i] + offset)
227 fsub.reverse() # flip the order to make norm point out
228 ret_face.append(fsub)
230 return ret_vert, ret_face
233 # Returns a list of faces that
234 # make up an array of 4 point polygon.
235 def Build_Face_List_Quads(OFFSET, COLUMN, ROW, FLIP=0):
236 Ret = []
237 RowStart = 0
238 for j in range(ROW):
239 for i in range(COLUMN):
240 Res1 = RowStart + i
241 Res2 = RowStart + i + (COLUMN + 1)
242 Res3 = RowStart + i + (COLUMN + 1) + 1
243 Res4 = RowStart + i + 1
244 if FLIP:
245 Ret.append([OFFSET + Res1, OFFSET + Res2, OFFSET + Res3, OFFSET + Res4])
246 else:
247 Ret.append([OFFSET + Res4, OFFSET + Res3, OFFSET + Res2, OFFSET + Res1])
248 RowStart += COLUMN + 1
249 return Ret
252 # Returns a list of faces that makes up a fill pattern for a
253 # circle
254 def Fill_Ring_Face(OFFSET, NUM, FACE_DOWN=0):
255 Ret = []
256 Face = [1, 2, 0]
257 TempFace = [0, 0, 0]
258 # A = 0 # UNUSED
259 B = 1
260 C = 2
261 if NUM < 3:
262 return None
263 for i in range(NUM - 2):
264 if (i % 2):
265 TempFace[0] = Face[C]
266 TempFace[1] = Face[C] + 1
267 TempFace[2] = Face[B]
268 if FACE_DOWN:
269 Ret.append([OFFSET + Face[2], OFFSET + Face[1], OFFSET + Face[0]])
270 else:
271 Ret.append([OFFSET + Face[0], OFFSET + Face[1], OFFSET + Face[2]])
272 else:
273 TempFace[0] = Face[C]
274 if Face[C] == 0:
275 TempFace[1] = NUM - 1
276 else:
277 TempFace[1] = Face[C] - 1
278 TempFace[2] = Face[B]
279 if FACE_DOWN:
280 Ret.append([OFFSET + Face[0], OFFSET + Face[1], OFFSET + Face[2]])
281 else:
282 Ret.append([OFFSET + Face[2], OFFSET + Face[1], OFFSET + Face[0]])
284 Face[0] = TempFace[0]
285 Face[1] = TempFace[1]
286 Face[2] = TempFace[2]
287 return Ret
289 # Returns a list of faces that makes up a fill pattern around the last vert
290 def Fill_Fan_Face(OFFSET, NUM, FACE_DOWN=0):
291 Ret = []
292 Face = [NUM-1,0,1]
293 TempFace = [0, 0, 0]
294 A = 0
295 #B = 1 unsed
296 C = 2
297 if NUM < 3:
298 return None
299 for _i in range(NUM - 2):
300 TempFace[0] = Face[A]
301 TempFace[1] = Face[C]
302 TempFace[2] = Face[C]+1
303 if FACE_DOWN:
304 Ret.append([OFFSET + Face[2], OFFSET + Face[1], OFFSET + Face[0]])
305 else:
306 Ret.append([OFFSET + Face[2], OFFSET + Face[1], OFFSET + Face[0]])
308 Face[0] = TempFace[0]
309 Face[1] = TempFace[1]
310 Face[2] = TempFace[2]
311 return Ret
313 # ####################################################################
314 # Create Allen Bit
315 # ####################################################################
317 def Allen_Fill(OFFSET, FLIP=0):
318 faces = []
319 Lookup = [[19, 1, 0],
320 [19, 2, 1],
321 [19, 3, 2],
322 [19, 20, 3],
323 [20, 4, 3],
324 [20, 5, 4],
325 [20, 6, 5],
326 [20, 7, 6],
327 [20, 8, 7],
328 [20, 9, 8],
330 [20, 21, 9],
332 [21, 10, 9],
333 [21, 11, 10],
334 [21, 12, 11],
335 [21, 13, 12],
336 [21, 14, 13],
337 [21, 15, 14],
339 [21, 22, 15],
340 [22, 16, 15],
341 [22, 17, 16],
342 [22, 18, 17]
344 for i in Lookup:
345 if FLIP:
346 faces.append([OFFSET + i[2], OFFSET + i[1], OFFSET + i[0]])
347 else:
348 faces.append([OFFSET + i[0], OFFSET + i[1], OFFSET + i[2]])
350 return faces
353 def Allen_Bit_Dia(FLAT_DISTANCE):
354 Flat_Radius = (float(FLAT_DISTANCE) / 2.0) / cos(radians(30))
355 return (Flat_Radius * 1.05) * 2.0
358 def Allen_Bit_Dia_To_Flat(DIA):
359 Flat_Radius = (DIA / 2.0) / 1.05
360 return (Flat_Radius * cos(radians(30))) * 2.0
363 def Create_Allen_Bit(FLAT_DISTANCE, HEIGHT):
364 verts = []
365 faces = []
366 DIV_COUNT = 36
368 Flat_Radius = (float(FLAT_DISTANCE) / 2.0) / cos(radians(30))
369 OUTTER_RADIUS = Flat_Radius * 1.05
370 Outter_Radius_Height = Flat_Radius * (0.1 / 5.77)
371 FaceStart_Outside = len(verts)
372 Deg_Step = 360.0 / float(DIV_COUNT)
374 for i in range(int(DIV_COUNT / 2) + 1): # only do half and mirror later
375 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
376 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
377 verts.append([x, y, 0])
379 FaceStart_Inside = len(verts)
381 Deg_Step = 360.0 / float(6)
382 for i in range(int(6 / 2) + 1):
383 x = sin(radians(i * Deg_Step)) * Flat_Radius
384 y = cos(radians(i * Deg_Step)) * Flat_Radius
385 verts.append([x, y, 0 - Outter_Radius_Height])
387 faces.extend(Allen_Fill(FaceStart_Outside, 0))
389 FaceStart_Bottom = len(verts)
391 Deg_Step = 360.0 / float(6)
392 for i in range(int(6 / 2) + 1):
393 x = sin(radians(i * Deg_Step)) * Flat_Radius
394 y = cos(radians(i * Deg_Step)) * Flat_Radius
395 verts.append([x, y, 0 - HEIGHT])
397 faces.extend(Build_Face_List_Quads(FaceStart_Inside, 3, 1, True))
398 faces.extend(Fill_Ring_Face(FaceStart_Bottom, 4))
400 M_Verts, M_Faces = Mirror_Verts_Faces(verts, faces, 'y')
401 verts.extend(M_Verts)
402 faces.extend(M_Faces)
404 return verts, faces, OUTTER_RADIUS * 2.0
405 # ####################################################################
406 # Create Torx Bit
407 # ####################################################################
409 def Torx_Bit_Size_To_Point_Distance(Bit_Size):
410 if Bit_Size == 'bf_Torx_T10':
411 return 2.83
412 elif Bit_Size == 'bf_Torx_T20':
413 return 3.94
414 elif Bit_Size == 'bf_Torx_T25':
415 return 4.52
416 elif Bit_Size == 'bf_Torx_T30':
417 return 5.61
418 elif Bit_Size == 'bf_Torx_T40':
419 return 6.75
420 elif Bit_Size == 'bf_Torx_T50':
421 return 8.94
422 elif Bit_Size == 'bf_Torx_T55':
423 return 8.94
424 else:
425 return 2.83 #default to M3
427 def Torx_Fill(OFFSET, FLIP=0):
428 faces = []
429 Lookup = [[0,10,11],
430 [0,11, 12],
431 [0,12,1],
433 [1, 12, 13],
434 [1, 13, 14],
435 [1, 14, 15],
436 [1, 15, 2],
438 [2, 15, 16],
439 [2, 16, 17],
440 [2, 17, 18],
441 [2, 18, 19],
442 [2, 19, 3],
444 [3, 19, 20],
445 [3, 20, 21],
446 [3, 21, 22],
447 [3, 22, 23],
448 [3, 23, 24],
449 [3, 24, 25],
450 [3, 25, 4],
453 [4, 25, 26],
454 [4, 26, 27],
455 [4, 27, 28],
456 [4, 28, 29],
457 [4, 29, 30],
458 [4, 30, 31],
459 [4, 31, 5],
461 [5, 31, 32],
462 [5, 32, 33],
463 [5, 33, 34],
464 [5, 34, 35],
465 [5, 35, 36],
466 [5, 36, 6],
468 [6, 36, 37],
469 [6, 37, 38],
470 [6, 38, 39],
471 [6, 39, 7],
473 [7, 39, 40],
474 [7, 40, 41],
475 [7, 41, 42],
476 [7, 42, 43],
477 [7, 43, 8],
479 [8, 43, 44],
480 [8, 44, 45],
481 [8, 45, 46],
482 [8, 46, 47],
483 [8, 47, 48],
484 [8, 48, 49],
485 [8, 49, 50],
486 [8, 50, 51],
487 [8, 51, 52],
488 [8, 52, 9],
490 for i in Lookup:
491 if FLIP:
492 faces.append([OFFSET + i[2], OFFSET + i[1], OFFSET + i[0]])
493 else:
494 faces.append([OFFSET + i[0], OFFSET + i[1], OFFSET + i[2]])
496 return faces
500 def Create_Torx_Bit(Point_Distance, HEIGHT):
501 verts = []
502 faces = []
504 POINT_RADIUS = Point_Distance * 0.5
505 OUTTER_RADIUS = POINT_RADIUS * 1.05
507 POINT_1_Y = POINT_RADIUS * 0.816592592592593
508 POINT_2_X = POINT_RADIUS * 0.511111111111111
509 POINT_2_Y = POINT_RADIUS * 0.885274074074074
510 POINT_3_X = POINT_RADIUS * 0.7072
511 POINT_3_Y = POINT_RADIUS * 0.408296296296296
512 POINT_4_X = POINT_RADIUS * 1.02222222222222
513 SMALL_RADIUS = POINT_RADIUS * 0.183407407407407
514 BIG_RADIUS = POINT_RADIUS * 0.333333333333333
515 # Values for T40 # POINT_1_Y = 2.756
516 # POINT_2_X = 1.725
517 # POINT_2_Y = 2.9878
518 # POINT_3_X = 2.3868
519 # POINT_3_Y = 1.378
520 # POINT_4_X = 3.45
522 # SMALL_RADIUS = 0.619
523 # BIG_RADIUS = 1.125
525 def Do_Curve(Curve_Height):
526 for i in range(0, 90, 10):
527 x = sin(radians(i)) * SMALL_RADIUS
528 y = cos(radians(i)) * SMALL_RADIUS
529 verts.append([x, POINT_1_Y + y, Curve_Height])
531 for i in range(260, 150, -10):
532 x = sin(radians(i)) * BIG_RADIUS
533 y = cos(radians(i)) * BIG_RADIUS
534 verts.append([POINT_2_X + x, POINT_2_Y + y, Curve_Height])
536 for i in range(340, 150 + 360, 10):
537 x = sin(radians(i%360)) * SMALL_RADIUS
538 y = cos(radians(i%360)) * SMALL_RADIUS
539 verts.append([POINT_3_X + x, POINT_3_Y + y, Curve_Height])
541 for i in range(320, 260, -10):
542 x = sin(radians(i)) * BIG_RADIUS
543 y = cos(radians(i)) * BIG_RADIUS
544 verts.append([POINT_4_X + x, y, Curve_Height])
546 FaceStart_Outside = len(verts)
548 for i in range(0, 100, 10):
549 x = sin(radians(i)) * OUTTER_RADIUS
550 y = cos(radians(i)) * OUTTER_RADIUS
551 verts.append([x, y, 0])
553 FaceStart_Top_Curve= len(verts)
554 Do_Curve(0)
555 faces.extend(Torx_Fill(FaceStart_Outside, 0))
557 FaceStart_Bottom_Curve= len(verts)
558 Do_Curve(0 - HEIGHT)
560 faces.extend(Build_Face_List_Quads(FaceStart_Top_Curve,42 ,1 , True))
562 verts.append([0,0,0 - HEIGHT]) # add center point for fill Fan
563 faces.extend(Fill_Fan_Face(FaceStart_Bottom_Curve, 44))
565 M_Verts, M_Faces = Mirror_Verts_Faces(verts, faces, 'x')
566 verts.extend(M_Verts)
567 faces.extend(M_Faces)
569 M_Verts, M_Faces = Mirror_Verts_Faces(verts, faces, 'y')
570 verts.extend(M_Verts)
571 faces.extend(M_Faces)
573 return verts, faces, OUTTER_RADIUS * 2.0
575 # ####################################################################
576 # Create Phillips Bit
577 # ####################################################################
579 def Phillips_Fill(OFFSET, FLIP=0):
580 faces = []
581 Lookup = [[0, 1, 10],
582 [1, 11, 10],
583 [1, 2, 11],
584 [2, 12, 11],
586 [2, 3, 12],
587 [3, 4, 12],
588 [4, 5, 12],
589 [5, 6, 12],
590 [6, 7, 12],
592 [7, 13, 12],
593 [7, 8, 13],
594 [8, 14, 13],
595 [8, 9, 14],
597 [10, 11, 16, 15],
598 [11, 12, 16],
599 [12, 13, 16],
600 [13, 14, 17, 16],
601 [15, 16, 17, 18]
603 for i in Lookup:
604 if FLIP:
605 if len(i) == 3:
606 faces.append([OFFSET + i[2], OFFSET + i[1], OFFSET + i[0]])
607 else:
608 faces.append([OFFSET + i[3], OFFSET + i[2], OFFSET + i[1], OFFSET + i[0]])
609 else:
610 if len(i) == 3:
611 faces.append([OFFSET + i[0], OFFSET + i[1], OFFSET + i[2]])
612 else:
613 faces.append([OFFSET + i[0], OFFSET + i[1], OFFSET + i[2], OFFSET + i[3]])
614 return faces
617 def Create_Phillips_Bit(FLAT_DIA, FLAT_WIDTH, HEIGHT):
618 verts = []
619 faces = []
621 DIV_COUNT = 36
622 FLAT_RADIUS = FLAT_DIA * 0.5
623 OUTTER_RADIUS = FLAT_RADIUS * 1.05
625 Flat_Half = float(FLAT_WIDTH) / 2.0
627 FaceStart_Outside = len(verts)
628 Deg_Step = 360.0 / float(DIV_COUNT)
629 for i in range(int(DIV_COUNT / 4) + 1): # only do half and mirror later
630 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
631 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
632 verts.append([x, y, 0])
634 # FaceStart_Inside = len(verts) # UNUSED
635 verts.append([0, FLAT_RADIUS, 0]) # 10
636 verts.append([Flat_Half, FLAT_RADIUS, 0]) # 11
637 verts.append([Flat_Half, Flat_Half, 0]) # 12
638 verts.append([FLAT_RADIUS, Flat_Half, 0]) # 13
639 verts.append([FLAT_RADIUS, 0, 0]) # 14
641 verts.append([0, Flat_Half, 0 - HEIGHT]) # 15
642 verts.append([Flat_Half, Flat_Half, 0 - HEIGHT]) # 16
643 verts.append([Flat_Half, 0, 0 - HEIGHT]) # 17
645 verts.append([0, 0, 0 - HEIGHT]) # 18
647 faces.extend(Phillips_Fill(FaceStart_Outside, True))
649 Spin_Verts, Spin_Face = SpinDup(verts, faces, 360, 4, 'z')
651 return Spin_Verts, Spin_Face, OUTTER_RADIUS * 2
654 # ####################################################################
655 # Create Head Types
656 # ####################################################################
658 def Max_Pan_Bit_Dia(HEAD_DIA):
659 HEAD_RADIUS = HEAD_DIA * 0.5
660 XRad = HEAD_RADIUS * 1.976
661 return (sin(radians(10)) * XRad) * 2.0
664 def Create_Pan_Head(HOLE_DIA, HEAD_DIA, SHANK_DIA, HEIGHT, RAD1, RAD2, FACE_OFFSET, DIV_COUNT):
666 HOLE_RADIUS = HOLE_DIA * 0.5
667 HEAD_RADIUS = HEAD_DIA * 0.5
668 SHANK_RADIUS = SHANK_DIA * 0.5
670 verts = []
671 faces = []
672 Row = 0
674 XRad = HEAD_RADIUS * 1.976
675 ZRad = HEAD_RADIUS * 1.768
676 EndRad = HEAD_RADIUS * 0.284
677 EndZOffset = HEAD_RADIUS * 0.432
678 HEIGHT = HEAD_RADIUS * 0.59
681 Dome_Rad = 5.6
682 RAD_Offset = 4.9
683 OtherRad = 0.8
684 OtherRad_X_Offset = 4.2
685 OtherRad_Z_Offset = 2.52
686 XRad = 9.88
687 ZRad = 8.84
688 EndRad = 1.42
689 EndZOffset = 2.16
690 HEIGHT = 2.95
692 FaceStart = FACE_OFFSET
694 z = cos(radians(10)) * ZRad
695 verts.append([HOLE_RADIUS, 0.0, (0.0 - ZRad) + z])
696 Start_Height = 0 - ((0.0 - ZRad) + z)
697 Row += 1
699 # for i in range(0,30,10): was 0 to 30 more work needed to make this look good.
700 for i in range(10, 30, 10):
701 x = sin(radians(i)) * XRad
702 z = cos(radians(i)) * ZRad
703 verts.append([x, 0.0, (0.0 - ZRad) + z])
704 Row += 1
706 for i in range(20, 140, 10):
707 x = sin(radians(i)) * EndRad
708 z = cos(radians(i)) * EndRad
709 if ((0.0 - EndZOffset) + z) < (0.0 - HEIGHT):
710 verts.append([(HEAD_RADIUS - EndRad) + x, 0.0, 0.0 - HEIGHT])
711 else:
712 verts.append([(HEAD_RADIUS - EndRad) + x, 0.0, (0.0 - EndZOffset) + z])
713 Row += 1
715 verts.append([SHANK_RADIUS, 0.0, (0.0 - HEIGHT)])
716 Row += 1
718 verts.append([SHANK_RADIUS, 0.0, (0.0 - HEIGHT) - Start_Height])
719 Row += 1
721 sVerts, sFaces = SpinDup(verts, faces, 360, DIV_COUNT, 'z')
722 sVerts.extend(verts) # add the start verts to the Spin verts to complete the loop
724 faces.extend(Build_Face_List_Quads(FaceStart, Row - 1, DIV_COUNT))
726 # Global_Head_Height = HEIGHT # UNUSED
728 return Move_Verts_Up_Z(sVerts, Start_Height), faces, HEIGHT
731 def Create_Dome_Head(HOLE_DIA, HEAD_DIA, SHANK_DIA, HEIGHT, RAD1, RAD2, FACE_OFFSET, DIV_COUNT):
732 HOLE_RADIUS = HOLE_DIA * 0.5
733 HEAD_RADIUS = HEAD_DIA * 0.5
734 SHANK_RADIUS = SHANK_DIA * 0.5
736 verts = []
737 faces = []
738 Row = 0
739 # Dome_Rad = HEAD_RADIUS * (1.0/1.75)
741 Dome_Rad = HEAD_RADIUS * 1.12
742 # Head_Height = HEAD_RADIUS * 0.78
743 RAD_Offset = HEAD_RADIUS * 0.98
744 Dome_Height = HEAD_RADIUS * 0.64
745 OtherRad = HEAD_RADIUS * 0.16
746 OtherRad_X_Offset = HEAD_RADIUS * 0.84
747 OtherRad_Z_Offset = HEAD_RADIUS * 0.504
750 Dome_Rad = 5.6
751 RAD_Offset = 4.9
752 Dome_Height = 3.2
753 OtherRad = 0.8
754 OtherRad_X_Offset = 4.2
755 OtherRad_Z_Offset = 2.52
758 FaceStart = FACE_OFFSET
760 verts.append([HOLE_RADIUS, 0.0, 0.0])
761 Row += 1
763 for i in range(0, 60, 10):
764 x = sin(radians(i)) * Dome_Rad
765 z = cos(radians(i)) * Dome_Rad
766 if ((0.0 - RAD_Offset) + z) <= 0:
767 verts.append([x, 0.0, (0.0 - RAD_Offset) + z])
768 Row += 1
770 for i in range(60, 160, 10):
771 x = sin(radians(i)) * OtherRad
772 z = cos(radians(i)) * OtherRad
773 z = (0.0 - OtherRad_Z_Offset) + z
774 if z < (0.0 - Dome_Height):
775 z = (0.0 - Dome_Height)
776 verts.append([OtherRad_X_Offset + x, 0.0, z])
777 Row += 1
779 verts.append([SHANK_RADIUS, 0.0, (0.0 - Dome_Height)])
780 Row += 1
782 sVerts, sFaces = SpinDup(verts, faces, 360, DIV_COUNT, 'z')
783 sVerts.extend(verts) # add the start verts to the Spin verts to complete the loop
785 faces.extend(Build_Face_List_Quads(FaceStart, Row - 1, DIV_COUNT))
787 return sVerts, faces, Dome_Height
790 def Create_CounterSink_Head(HOLE_DIA, HEAD_DIA, SHANK_DIA, HEIGHT, RAD1, DIV_COUNT):
792 HOLE_RADIUS = HOLE_DIA * 0.5
793 HEAD_RADIUS = HEAD_DIA * 0.5
794 SHANK_RADIUS = SHANK_DIA * 0.5
796 verts = []
797 faces = []
798 Row = 0
800 # HEAD_RADIUS = (HEIGHT/tan(radians(60))) + SHANK_RADIUS
801 HEIGHT = tan(radians(60)) * (HEAD_RADIUS - SHANK_RADIUS)
803 FaceStart = len(verts)
805 verts.append([HOLE_RADIUS, 0.0, 0.0])
806 Row += 1
808 # rad
809 for i in range(0, 100, 10):
810 x = sin(radians(i)) * RAD1
811 z = cos(radians(i)) * RAD1
812 verts.append([(HEAD_RADIUS - RAD1) + x, 0.0, (0.0 - RAD1) + z])
813 Row += 1
815 verts.append([SHANK_RADIUS, 0.0, 0.0 - HEIGHT])
816 Row += 1
818 sVerts, sFaces = SpinDup(verts, faces, 360, DIV_COUNT, 'z')
819 sVerts.extend(verts) # add the start verts to the Spin verts to complete the loop
821 faces.extend(Build_Face_List_Quads(FaceStart, Row - 1, DIV_COUNT))
823 return sVerts, faces, HEIGHT
826 def Create_Cap_Head(HOLE_DIA, HEAD_DIA, SHANK_DIA, HEIGHT, RAD1, RAD2, DIV_COUNT):
828 HOLE_RADIUS = HOLE_DIA * 0.5
829 HEAD_RADIUS = HEAD_DIA * 0.5
830 SHANK_RADIUS = SHANK_DIA * 0.5
832 verts = []
833 faces = []
834 Row = 0
835 BEVEL = HEIGHT * 0.01
837 FaceStart = len(verts)
839 verts.append([HOLE_RADIUS, 0.0, 0.0])
840 Row += 1
842 # rad
843 for i in range(0, 100, 10):
844 x = sin(radians(i)) * RAD1
845 z = cos(radians(i)) * RAD1
846 verts.append([(HEAD_RADIUS - RAD1) + x, 0.0, (0.0 - RAD1) + z])
847 Row += 1
849 verts.append([HEAD_RADIUS, 0.0, 0.0 - HEIGHT + BEVEL])
850 Row += 1
852 verts.append([HEAD_RADIUS - BEVEL, 0.0, 0.0 - HEIGHT])
853 Row += 1
855 # rad2
856 for i in range(0, 100, 10):
857 x = sin(radians(i)) * RAD2
858 z = cos(radians(i)) * RAD2
859 verts.append([(SHANK_RADIUS + RAD2) - x, 0.0, (0.0 - HEIGHT - RAD2) + z])
860 Row += 1
862 sVerts, sFaces = SpinDup(verts, faces, 360, DIV_COUNT, 'z')
863 sVerts.extend(verts) # add the start verts to the Spin verts to complete the loop
865 faces.extend(Build_Face_List_Quads(FaceStart, Row - 1, DIV_COUNT))
867 return sVerts, faces, HEIGHT + RAD2
870 def Create_Hex_Head(FLAT, HOLE_DIA, SHANK_DIA, HEIGHT):
872 verts = []
873 faces = []
874 HOLE_RADIUS = HOLE_DIA * 0.5
875 Half_Flat = FLAT / 2
876 TopBevelRadius = Half_Flat - (Half_Flat * (0.05 / 8))
877 Undercut_Height = (Half_Flat * (0.05 / 8))
878 Shank_Bevel = (Half_Flat * (0.05 / 8))
879 Flat_Height = HEIGHT - Undercut_Height - Shank_Bevel
880 # Undercut_Height = 5
881 SHANK_RADIUS = SHANK_DIA / 2
882 Row = 0
884 verts.append([0.0, 0.0, 0.0])
886 FaceStart = len(verts)
888 # inner hole
889 x = sin(radians(0)) * HOLE_RADIUS
890 y = cos(radians(0)) * HOLE_RADIUS
891 verts.append([x, y, 0.0])
893 x = sin(radians(60 / 6)) * HOLE_RADIUS
894 y = cos(radians(60 / 6)) * HOLE_RADIUS
895 verts.append([x, y, 0.0])
897 x = sin(radians(60 / 3)) * HOLE_RADIUS
898 y = cos(radians(60 / 3)) * HOLE_RADIUS
899 verts.append([x, y, 0.0])
901 x = sin(radians(60 / 2)) * HOLE_RADIUS
902 y = cos(radians(60 / 2)) * HOLE_RADIUS
903 verts.append([x, y, 0.0])
904 Row += 1
906 # bevel
907 x = sin(radians(0)) * TopBevelRadius
908 y = cos(radians(0)) * TopBevelRadius
909 vec1 = Vector([x, y, 0.0])
910 verts.append([x, y, 0.0])
912 x = sin(radians(60 / 6)) * TopBevelRadius
913 y = cos(radians(60 / 6)) * TopBevelRadius
914 vec2 = Vector([x, y, 0.0])
915 verts.append([x, y, 0.0])
917 x = sin(radians(60 / 3)) * TopBevelRadius
918 y = cos(radians(60 / 3)) * TopBevelRadius
919 vec3 = Vector([x, y, 0.0])
920 verts.append([x, y, 0.0])
922 x = sin(radians(60 / 2)) * TopBevelRadius
923 y = cos(radians(60 / 2)) * TopBevelRadius
924 vec4 = Vector([x, y, 0.0])
925 verts.append([x, y, 0.0])
926 Row += 1
928 # Flats
929 x = tan(radians(0)) * Half_Flat
930 dvec = vec1 - Vector([x, Half_Flat, 0.0])
931 verts.append([x, Half_Flat, -dvec.length])
933 x = tan(radians(60 / 6)) * Half_Flat
934 dvec = vec2 - Vector([x, Half_Flat, 0.0])
935 verts.append([x, Half_Flat, -dvec.length])
937 x = tan(radians(60 / 3)) * Half_Flat
938 dvec = vec3 - Vector([x, Half_Flat, 0.0])
939 Lowest_Point = -dvec.length
940 verts.append([x, Half_Flat, -dvec.length])
942 x = tan(radians(60 / 2)) * Half_Flat
943 dvec = vec4 - Vector([x, Half_Flat, 0.0])
944 Lowest_Point = -dvec.length
945 verts.append([x, Half_Flat, -dvec.length])
946 Row += 1
948 # down Bits Tri
949 x = tan(radians(0)) * Half_Flat
950 verts.append([x, Half_Flat, Lowest_Point])
952 x = tan(radians(60 / 6)) * Half_Flat
953 verts.append([x, Half_Flat, Lowest_Point])
955 x = tan(radians(60 / 3)) * Half_Flat
956 verts.append([x, Half_Flat, Lowest_Point])
958 x = tan(radians(60 / 2)) * Half_Flat
959 verts.append([x, Half_Flat, Lowest_Point])
960 Row += 1
962 # down Bits
964 x = tan(radians(0)) * Half_Flat
965 verts.append([x, Half_Flat, -Flat_Height])
967 x = tan(radians(60 / 6)) * Half_Flat
968 verts.append([x, Half_Flat, -Flat_Height])
970 x = tan(radians(60 / 3)) * Half_Flat
971 verts.append([x, Half_Flat, -Flat_Height])
973 x = tan(radians(60 / 2)) * Half_Flat
974 verts.append([x, Half_Flat, -Flat_Height])
975 Row += 1
977 # Under cut
978 x = sin(radians(0)) * Half_Flat
979 y = cos(radians(0)) * Half_Flat
980 vec1 = Vector([x, y, 0.0])
981 verts.append([x, y, -Flat_Height])
983 x = sin(radians(60 / 6)) * Half_Flat
984 y = cos(radians(60 / 6)) * Half_Flat
985 vec2 = Vector([x, y, 0.0])
986 verts.append([x, y, -Flat_Height])
988 x = sin(radians(60 / 3)) * Half_Flat
989 y = cos(radians(60 / 3)) * Half_Flat
990 vec3 = Vector([x, y, 0.0])
991 verts.append([x, y, -Flat_Height])
993 x = sin(radians(60 / 2)) * Half_Flat
994 y = cos(radians(60 / 2)) * Half_Flat
995 vec3 = Vector([x, y, 0.0])
996 verts.append([x, y, -Flat_Height])
997 Row += 1
999 # Under cut down bit
1000 x = sin(radians(0)) * Half_Flat
1001 y = cos(radians(0)) * Half_Flat
1002 vec1 = Vector([x, y, 0.0])
1003 verts.append([x, y, -Flat_Height - Undercut_Height])
1005 x = sin(radians(60 / 6)) * Half_Flat
1006 y = cos(radians(60 / 6)) * Half_Flat
1007 vec2 = Vector([x, y, 0.0])
1008 verts.append([x, y, -Flat_Height - Undercut_Height])
1010 x = sin(radians(60 / 3)) * Half_Flat
1011 y = cos(radians(60 / 3)) * Half_Flat
1012 vec3 = Vector([x, y, 0.0])
1013 verts.append([x, y, -Flat_Height - Undercut_Height])
1015 x = sin(radians(60 / 2)) * Half_Flat
1016 y = cos(radians(60 / 2)) * Half_Flat
1017 vec3 = Vector([x, y, 0.0])
1018 verts.append([x, y, -Flat_Height - Undercut_Height])
1019 Row += 1
1021 # Under cut to Shank BEVEL
1022 x = sin(radians(0)) * (SHANK_RADIUS + Shank_Bevel)
1023 y = cos(radians(0)) * (SHANK_RADIUS + Shank_Bevel)
1024 vec1 = Vector([x, y, 0.0])
1025 verts.append([x, y, -Flat_Height - Undercut_Height])
1027 x = sin(radians(60 / 6)) * (SHANK_RADIUS + Shank_Bevel)
1028 y = cos(radians(60 / 6)) * (SHANK_RADIUS + Shank_Bevel)
1029 vec2 = Vector([x, y, 0.0])
1030 verts.append([x, y, -Flat_Height - Undercut_Height])
1032 x = sin(radians(60 / 3)) * (SHANK_RADIUS + Shank_Bevel)
1033 y = cos(radians(60 / 3)) * (SHANK_RADIUS + Shank_Bevel)
1034 vec3 = Vector([x, y, 0.0])
1035 verts.append([x, y, -Flat_Height - Undercut_Height])
1037 x = sin(radians(60 / 2)) * (SHANK_RADIUS + Shank_Bevel)
1038 y = cos(radians(60 / 2)) * (SHANK_RADIUS + Shank_Bevel)
1039 vec3 = Vector([x, y, 0.0])
1040 verts.append([x, y, -Flat_Height - Undercut_Height])
1041 Row += 1
1043 # Under cut to Shank BEVEL
1044 x = sin(radians(0)) * SHANK_RADIUS
1045 y = cos(radians(0)) * SHANK_RADIUS
1046 vec1 = Vector([x, y, 0.0])
1047 verts.append([x, y, -Flat_Height - Undercut_Height - Shank_Bevel])
1049 x = sin(radians(60 / 6)) * SHANK_RADIUS
1050 y = cos(radians(60 / 6)) * SHANK_RADIUS
1051 vec2 = Vector([x, y, 0.0])
1052 verts.append([x, y, -Flat_Height - Undercut_Height - Shank_Bevel])
1054 x = sin(radians(60 / 3)) * SHANK_RADIUS
1055 y = cos(radians(60 / 3)) * SHANK_RADIUS
1056 vec3 = Vector([x, y, 0.0])
1057 verts.append([x, y, -Flat_Height - Undercut_Height - Shank_Bevel])
1059 x = sin(radians(60 / 2)) * SHANK_RADIUS
1060 y = cos(radians(60 / 2)) * SHANK_RADIUS
1061 vec3 = Vector([x, y, 0.0])
1062 verts.append([x, y, -Flat_Height - Undercut_Height - Shank_Bevel])
1063 Row += 1
1065 faces.extend(Build_Face_List_Quads(FaceStart, 3, Row - 1))
1067 Mirror_Verts, Mirror_Faces = Mirror_Verts_Faces(verts, faces, 'y')
1068 verts.extend(Mirror_Verts)
1069 faces.extend(Mirror_Faces)
1071 Spin_Verts, Spin_Faces = SpinDup(verts, faces, 360, 6, 'z')
1073 return Spin_Verts, Spin_Faces, 0 - (-HEIGHT)
1077 def Create_12_Point(FLAT, HOLE_DIA, SHANK_DIA, HEIGHT,FLANGE_DIA):
1078 FLANGE_HEIGHT = (1.89/8.0)*HEIGHT
1079 FLAT_HEIGHT = (4.18/8.0)*HEIGHT
1080 # FLANGE_DIA = (13.27/8.0)*FLAT
1082 FLANGE_RADIUS = FLANGE_DIA * 0.5
1083 FLANGE_TAPPER_HEIGHT = HEIGHT - FLANGE_HEIGHT - FLAT_HEIGHT
1085 # HOLE_DIA = 0.0
1087 verts = []
1088 faces = []
1089 HOLE_RADIUS = HOLE_DIA / 2
1090 Half_Flat = FLAT / 2
1091 TopBevelRadius = Half_Flat - (Half_Flat * (0.05 / 8))
1092 # Undercut_Height = (Half_Flat * (0.05 / 8))
1093 # Shank_Bevel = (Half_Flat * (0.05 / 8))
1094 # Flat_Height = HEIGHT - Undercut_Height - Shank_Bevel
1095 # Undercut_Height = 5
1096 SHANK_RADIUS = SHANK_DIA / 2
1097 Row = 0
1099 verts.append([0.0, 0.0, 0.0])
1101 # print("HOLE_RADIUS" + str(HOLE_RADIUS))
1102 # print("TopBevelRadius" + str(TopBevelRadius))
1104 FaceStart = len(verts)
1106 # inner hole
1107 x = sin(radians(0)) * HOLE_RADIUS
1108 y = cos(radians(0)) * HOLE_RADIUS
1109 verts.append([x, y, 0.0])
1111 x = sin(radians(5)) * HOLE_RADIUS
1112 y = cos(radians(5)) * HOLE_RADIUS
1113 verts.append([x, y, 0.0])
1115 x = sin(radians(10)) * HOLE_RADIUS
1116 y = cos(radians(10)) * HOLE_RADIUS
1117 verts.append([x, y, 0.0])
1119 x = sin(radians(15)) * HOLE_RADIUS
1120 y = cos(radians(15)) * HOLE_RADIUS
1121 verts.append([x, y, 0.0])
1123 x = sin(radians(20)) * HOLE_RADIUS
1124 y = cos(radians(20)) * HOLE_RADIUS
1125 verts.append([x, y, 0.0])
1127 x = sin(radians(25)) * HOLE_RADIUS
1128 y = cos(radians(25)) * HOLE_RADIUS
1129 verts.append([x, y, 0.0])
1131 x = sin(radians(30)) * HOLE_RADIUS
1132 y = cos(radians(30)) * HOLE_RADIUS
1133 verts.append([x, y, 0.0])
1135 Row += 1
1139 # bevel
1140 x = sin(radians(0)) * TopBevelRadius
1141 y = cos(radians(0)) * TopBevelRadius
1142 vec1 = Vector([x, y, 0.0])
1143 verts.append([x, y, 0.0])
1145 x = sin(radians(5)) * TopBevelRadius
1146 y = cos(radians(5)) * TopBevelRadius
1147 vec2 = Vector([x, y, 0.0])
1148 verts.append([x, y, 0.0])
1150 x = sin(radians(10)) * TopBevelRadius
1151 y = cos(radians(10)) * TopBevelRadius
1152 vec3 = Vector([x, y, 0.0])
1153 verts.append([x, y, 0.0])
1155 x = sin(radians(15)) * TopBevelRadius
1156 y = cos(radians(15)) * TopBevelRadius
1157 vec4 = Vector([x, y, 0.0])
1158 verts.append([x, y, 0.0])
1160 x = sin(radians(20)) * TopBevelRadius
1161 y = cos(radians(20)) * TopBevelRadius
1162 vec5 = Vector([x, y, 0.0])
1163 verts.append([x, y, 0.0])
1165 x = sin(radians(25)) * TopBevelRadius
1166 y = cos(radians(25)) * TopBevelRadius
1167 vec6 = Vector([x, y, 0.0])
1168 verts.append([x, y, 0.0])
1170 x = sin(radians(30)) * TopBevelRadius
1171 y = cos(radians(30)) * TopBevelRadius
1172 vec7 = Vector([x, y, 0.0])
1173 verts.append([x, y, 0.0])
1175 Row += 1
1178 #45Deg bevel on the top
1180 #First we work out how far up the Y axis the vert is
1181 v_origin = Vector([0.0,0.0,0.0]) # center of the model
1182 v_15Deg_Point = Vector([tan(radians(15)) * Half_Flat,Half_Flat,0.0]) #Is a know point to work back from
1184 x = tan(radians(0)) * Half_Flat
1185 Point_Distance =(tan(radians(30)) * v_15Deg_Point.x)+Half_Flat
1186 dvec = vec1 - Vector([x, Point_Distance, 0.0])
1187 verts.append([x, Point_Distance, -dvec.length])
1188 v_0_Deg_Top_Point = Vector([x, Point_Distance, -dvec.length])
1190 v_0_Deg_Point = Vector([x, Point_Distance,0.0])
1192 v_5Deg_Line = Vector([tan(radians(5)) * Half_Flat, Half_Flat, 0.0])
1193 v_5Deg_Line.length *= 2 # extende out the line on a 5 deg angle
1195 #We cross 2 lines. One from the origin to the 0 Deg point
1196 #and the second is from the orign extended out past the first line
1197 # This gives the cross point of the
1198 v_Cross = geometry.intersect_line_line_2d(v_0_Deg_Point,v_15Deg_Point,v_origin,v_5Deg_Line)
1199 dvec = vec2 - Vector([v_Cross.x,v_Cross.y,0.0])
1200 verts.append([v_Cross.x,v_Cross.y,-dvec.length])
1201 v_5_Deg_Top_Point = Vector([v_Cross.x,v_Cross.y,-dvec.length])
1203 v_10Deg_Line = Vector([tan(radians(10)) * Half_Flat, Half_Flat, 0.0])
1204 v_10Deg_Line.length *= 2 # extende out the line
1206 v_Cross = geometry.intersect_line_line_2d(v_0_Deg_Point,v_15Deg_Point,v_origin,v_10Deg_Line)
1207 dvec = vec3 - Vector([v_Cross.x,v_Cross.y,0.0])
1208 verts.append([v_Cross.x,v_Cross.y,-dvec.length])
1209 v_10_Deg_Top_Point = Vector([v_Cross.x,v_Cross.y,-dvec.length])
1211 #The remain points are stright forward because y is all the same y height (Half_Flat)
1212 x = tan(radians(15)) * Half_Flat
1213 dvec = vec4 - Vector([x, Half_Flat, 0.0])
1214 Lowest_Point = -dvec.length
1215 verts.append([x, Half_Flat, -dvec.length])
1216 v_15_Deg_Top_Point = Vector([x, Half_Flat, -dvec.length])
1218 x = tan(radians(20)) * Half_Flat
1219 dvec = vec5 - Vector([x, Half_Flat, 0.0])
1220 Lowest_Point = -dvec.length
1221 verts.append([x, Half_Flat, -dvec.length])
1222 v_20_Deg_Top_Point = Vector([x, Half_Flat, -dvec.length])
1224 x = tan(radians(25)) * Half_Flat
1225 dvec = vec6 - Vector([x, Half_Flat, 0.0])
1226 Lowest_Point = -dvec.length
1227 verts.append([x, Half_Flat, -dvec.length])
1228 v_25_Deg_Top_Point = Vector([x, Half_Flat, -dvec.length])
1230 x = tan(radians(30)) * Half_Flat
1231 dvec = vec7 - Vector([x, Half_Flat, 0.0])
1232 Lowest_Point = -dvec.length
1233 verts.append([x, Half_Flat, -dvec.length])
1234 v_30_Deg_Top_Point = Vector([x, Half_Flat, -dvec.length])
1235 Row += 1
1238 #Down Bits
1239 # print ("Point_Distance")
1240 # print (Point_Distance)
1244 Flange_Adjacent = FLANGE_RADIUS - Point_Distance
1245 if (Flange_Adjacent == 0.0):
1246 Flange_Adjacent = 0.000001
1247 Flange_Opposite = FLANGE_TAPPER_HEIGHT
1249 # print ("Flange_Opposite")
1250 # print (Flange_Opposite)
1251 # print ("Flange_Adjacent")
1252 # print (Flange_Adjacent)
1254 FLANGE_ANGLE_RAD = atan(Flange_Opposite/Flange_Adjacent )
1255 # FLANGE_ANGLE_RAD = radians(45)
1256 # print("FLANGE_ANGLE_RAD")
1257 # print (degrees (FLANGE_ANGLE_RAD))
1260 v_Extended_Flange_Edge = Vector([0.0,0.0,-HEIGHT + FLANGE_HEIGHT + (tan(FLANGE_ANGLE_RAD)* FLANGE_RADIUS) ])
1261 # print("v_Extended_Flange_Edge")
1262 # print (v_Extended_Flange_Edge)
1264 #0deg
1265 v_Flange_Edge = Vector([sin(radians(0)) * FLANGE_RADIUS,cos(radians(0)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT ])
1266 v_Cross = geometry.intersect_line_line(v_0_Deg_Top_Point,Vector([v_0_Deg_Top_Point.x,v_0_Deg_Top_Point.y,-HEIGHT]),v_Flange_Edge,v_Extended_Flange_Edge)
1267 verts.append(v_Cross[0])
1269 #5deg
1270 v_Flange_Edge = Vector([sin(radians(5)) * FLANGE_RADIUS,cos(radians(5)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT ])
1271 v_Cross = geometry.intersect_line_line(v_5_Deg_Top_Point,Vector([v_5_Deg_Top_Point.x,v_5_Deg_Top_Point.y,-HEIGHT]),v_Flange_Edge,v_Extended_Flange_Edge)
1272 verts.append(v_Cross[0])
1274 #10deg
1275 v_Flange_Edge = Vector([sin(radians(10)) * FLANGE_RADIUS,cos(radians(10)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT ])
1276 v_Cross = geometry.intersect_line_line(v_10_Deg_Top_Point,Vector([v_10_Deg_Top_Point.x,v_10_Deg_Top_Point.y,-HEIGHT]),v_Flange_Edge,v_Extended_Flange_Edge)
1277 verts.append(v_Cross[0])
1279 #15deg
1280 v_Flange_Edge = Vector([sin(radians(15)) * FLANGE_RADIUS,cos(radians(15)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT ])
1281 v_Cross = geometry.intersect_line_line(v_15_Deg_Top_Point,Vector([v_15_Deg_Top_Point.x,v_15_Deg_Top_Point.y,-HEIGHT]),v_Flange_Edge,v_Extended_Flange_Edge)
1282 verts.append(v_Cross[0])
1285 #20deg
1286 v_Flange_Edge = Vector([sin(radians(20)) * FLANGE_RADIUS,cos(radians(20)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT ])
1287 v_Cross = geometry.intersect_line_line(v_20_Deg_Top_Point,Vector([v_20_Deg_Top_Point.x,v_20_Deg_Top_Point.y,-HEIGHT]),v_Flange_Edge,v_Extended_Flange_Edge)
1288 verts.append(v_Cross[0])
1290 #25deg
1291 v_Flange_Edge = Vector([sin(radians(25)) * FLANGE_RADIUS,cos(radians(25)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT ])
1292 v_Cross = geometry.intersect_line_line(v_25_Deg_Top_Point,Vector([v_25_Deg_Top_Point.x,v_25_Deg_Top_Point.y,-HEIGHT]),v_Flange_Edge,v_Extended_Flange_Edge)
1293 verts.append(v_Cross[0])
1296 #30deg
1297 v_Flange_Edge = Vector([sin(radians(30)) * FLANGE_RADIUS,cos(radians(30)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT ])
1298 v_Cross = geometry.intersect_line_line(v_30_Deg_Top_Point,Vector([v_30_Deg_Top_Point.x,v_30_Deg_Top_Point.y,-HEIGHT]),v_Flange_Edge,v_Extended_Flange_Edge)
1299 verts.append(v_Cross[0])
1301 Row += 1
1305 verts.append([sin(radians(0)) * FLANGE_RADIUS,cos(radians(0)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT ])
1306 verts.append([sin(radians(5)) * FLANGE_RADIUS,cos(radians(5)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT])
1307 verts.append([sin(radians(10)) * FLANGE_RADIUS,cos(radians(10)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT])
1308 verts.append([sin(radians(15)) * FLANGE_RADIUS,cos(radians(15)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT])
1309 verts.append([sin(radians(20)) * FLANGE_RADIUS,cos(radians(20)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT])
1310 verts.append([sin(radians(25)) * FLANGE_RADIUS,cos(radians(25)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT])
1311 verts.append([sin(radians(30)) * FLANGE_RADIUS,cos(radians(30)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT])
1313 Row += 1
1315 verts.append([sin(radians(0)) * FLANGE_RADIUS,cos(radians(0)) * FLANGE_RADIUS,-HEIGHT])
1316 verts.append([sin(radians(5)) * FLANGE_RADIUS,cos(radians(5)) * FLANGE_RADIUS,-HEIGHT])
1317 verts.append([sin(radians(10)) * FLANGE_RADIUS,cos(radians(10)) * FLANGE_RADIUS,-HEIGHT])
1318 verts.append([sin(radians(15)) * FLANGE_RADIUS,cos(radians(15)) * FLANGE_RADIUS,-HEIGHT])
1319 verts.append([sin(radians(20)) * FLANGE_RADIUS,cos(radians(20)) * FLANGE_RADIUS,-HEIGHT])
1320 verts.append([sin(radians(25)) * FLANGE_RADIUS,cos(radians(25)) * FLANGE_RADIUS,-HEIGHT])
1321 verts.append([sin(radians(30)) * FLANGE_RADIUS,cos(radians(30)) * FLANGE_RADIUS,-HEIGHT])
1323 Row += 1
1326 verts.append([sin(radians(0)) * SHANK_RADIUS,cos(radians(0)) * SHANK_RADIUS,-HEIGHT])
1327 verts.append([sin(radians(0)) * SHANK_RADIUS,cos(radians(0)) * SHANK_RADIUS,-HEIGHT])
1328 verts.append([sin(radians(10)) * SHANK_RADIUS,cos(radians(10)) * SHANK_RADIUS,-HEIGHT])
1329 verts.append([sin(radians(10)) * SHANK_RADIUS,cos(radians(10)) * SHANK_RADIUS,-HEIGHT])
1330 verts.append([sin(radians(20)) * SHANK_RADIUS,cos(radians(20)) * SHANK_RADIUS,-HEIGHT])
1331 verts.append([sin(radians(20)) * SHANK_RADIUS,cos(radians(20)) * SHANK_RADIUS,-HEIGHT])
1332 verts.append([sin(radians(30)) * SHANK_RADIUS,cos(radians(30)) * SHANK_RADIUS,-HEIGHT])
1334 Row += 1
1337 faces.extend(Build_Face_List_Quads(FaceStart, 6, Row - 1))
1339 Spin_Verts, Spin_Faces = SpinDup(verts, faces, 360,12, 'z')
1341 return Spin_Verts, Spin_Faces, 0 - (-HEIGHT)
1344 def Create_12_Point_Head(FLAT, HOLE_DIA, SHANK_DIA, HEIGHT,FLANGE_DIA):
1345 #TODO add under head radius
1346 return Create_12_Point(FLAT, HOLE_DIA, SHANK_DIA, HEIGHT,FLANGE_DIA)
1350 # ####################################################################
1351 # Create External Thread
1352 # ####################################################################
1355 def Thread_Start3(verts, INNER_RADIUS, OUTTER_RADIUS, PITCH, DIV_COUNT,
1356 CREST_PERCENT, ROOT_PERCENT, Height_Offset):
1358 Ret_Row = 0
1360 Height_Start = Height_Offset - PITCH
1361 Height_Step = float(PITCH) / float(DIV_COUNT)
1362 Deg_Step = 360.0 / float(DIV_COUNT)
1364 Crest_Height = float(PITCH) * float(CREST_PERCENT) / float(100)
1365 Root_Height = float(PITCH) * float(ROOT_PERCENT) / float(100)
1366 Root_to_Crest_Height = Crest_to_Root_Height = \
1367 (float(PITCH) - (Crest_Height + Root_Height)) / 2.0
1369 # thread start
1370 Rank = float(OUTTER_RADIUS - INNER_RADIUS) / float(DIV_COUNT)
1371 for j in range(4):
1373 for i in range(DIV_COUNT + 1):
1374 z = Height_Offset - (Height_Step * i)
1375 if z > Height_Start:
1376 z = Height_Start
1377 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
1378 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
1379 verts.append([x, y, z])
1380 Height_Offset -= Crest_Height
1381 Ret_Row += 1
1383 for i in range(DIV_COUNT + 1):
1384 z = Height_Offset - (Height_Step * i)
1385 if z > Height_Start:
1386 z = Height_Start
1388 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
1389 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
1390 verts.append([x, y, z])
1391 Height_Offset -= Crest_to_Root_Height
1392 Ret_Row += 1
1394 for i in range(DIV_COUNT + 1):
1395 z = Height_Offset - (Height_Step * i)
1396 if z > Height_Start:
1397 z = Height_Start
1399 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
1400 y = cos(radians(i * Deg_Step)) * INNER_RADIUS
1401 if j == 0:
1402 x = sin(radians(i * Deg_Step)) * (OUTTER_RADIUS - (i * Rank))
1403 y = cos(radians(i * Deg_Step)) * (OUTTER_RADIUS - (i * Rank))
1404 verts.append([x, y, z])
1405 Height_Offset -= Root_Height
1406 Ret_Row += 1
1408 for i in range(DIV_COUNT + 1):
1409 z = Height_Offset - (Height_Step * i)
1410 if z > Height_Start:
1411 z = Height_Start
1413 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
1414 y = cos(radians(i * Deg_Step)) * INNER_RADIUS
1416 if j == 0:
1417 x = sin(radians(i * Deg_Step)) * (OUTTER_RADIUS - (i * Rank))
1418 y = cos(radians(i * Deg_Step)) * (OUTTER_RADIUS - (i * Rank))
1419 verts.append([x, y, z])
1420 Height_Offset -= Root_to_Crest_Height
1421 Ret_Row += 1
1423 return Ret_Row, Height_Offset
1426 def Create_Shank_Verts(START_DIA, OUTTER_DIA, LENGTH, Z_LOCATION, DIV_COUNT):
1428 verts = []
1430 START_RADIUS = START_DIA / 2
1431 OUTTER_RADIUS = OUTTER_DIA / 2
1433 Opp = abs(START_RADIUS - OUTTER_RADIUS)
1434 Taper_Lentgh = Opp / tan(radians(31))
1436 if Taper_Lentgh > LENGTH:
1437 Taper_Lentgh = 0
1439 Stright_Length = LENGTH - Taper_Lentgh
1441 Deg_Step = 360.0 / float(DIV_COUNT)
1443 Row = 0
1445 Lowest_Z_Vert = 0
1447 Height_Offset = Z_LOCATION
1449 # Ring
1450 for i in range(DIV_COUNT + 1):
1451 x = sin(radians(i * Deg_Step)) * START_RADIUS
1452 y = cos(radians(i * Deg_Step)) * START_RADIUS
1453 z = Height_Offset - 0
1454 verts.append([x, y, z])
1455 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1456 Height_Offset -= Stright_Length
1457 Row += 1
1459 for i in range(DIV_COUNT + 1):
1460 x = sin(radians(i * Deg_Step)) * START_RADIUS
1461 y = cos(radians(i * Deg_Step)) * START_RADIUS
1462 z = Height_Offset - 0
1463 verts.append([x, y, z])
1464 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1465 Height_Offset -= Taper_Lentgh
1466 Row += 1
1468 return verts, Row, Height_Offset
1471 def Create_Thread_Start_Verts(INNER_DIA, OUTTER_DIA, PITCH, CREST_PERCENT,
1472 ROOT_PERCENT, Z_LOCATION, DIV_COUNT):
1474 verts = []
1476 INNER_RADIUS = INNER_DIA / 2
1477 OUTTER_RADIUS = OUTTER_DIA / 2
1479 Deg_Step = 360.0 / float(DIV_COUNT)
1480 Height_Step = float(PITCH) / float(DIV_COUNT)
1482 Row = 0
1484 Lowest_Z_Vert = 0
1486 Height_Offset = Z_LOCATION
1488 Height_Start = Height_Offset
1490 Crest_Height = float(PITCH) * float(CREST_PERCENT) / float(100)
1491 Root_Height = float(PITCH) * float(ROOT_PERCENT) / float(100)
1492 Root_to_Crest_Height = Crest_to_Root_Height = \
1493 (float(PITCH) - (Crest_Height + Root_Height)) / 2.0
1495 Rank = float(OUTTER_RADIUS - INNER_RADIUS) / float(DIV_COUNT)
1497 Height_Offset = Z_LOCATION + PITCH
1498 Cut_off = Z_LOCATION
1500 for j in range(1):
1502 for i in range(DIV_COUNT + 1):
1503 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
1504 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
1505 z = Height_Offset - (Height_Step * i)
1506 if z > Cut_off:
1507 z = Cut_off
1508 verts.append([x, y, z])
1509 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1510 Height_Offset -= Crest_Height
1511 Row += 1
1513 for i in range(DIV_COUNT + 1):
1514 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
1515 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
1516 z = Height_Offset - (Height_Step * i)
1517 if z > Cut_off:
1518 z = Cut_off
1519 verts.append([x, y, z])
1520 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1521 Height_Offset -= Crest_to_Root_Height
1522 Row += 1
1524 for i in range(DIV_COUNT + 1):
1525 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
1526 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
1527 z = Height_Offset - (Height_Step * i)
1528 if z > Cut_off:
1529 z = Cut_off
1530 verts.append([x, y, z])
1531 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1532 Height_Offset -= Root_Height
1533 Row += 1
1535 for i in range(DIV_COUNT + 1):
1536 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
1537 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
1538 z = Height_Offset - (Height_Step * i)
1539 if z > Cut_off:
1540 z = Cut_off
1541 verts.append([x, y, z])
1542 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1543 Height_Offset -= Root_to_Crest_Height
1544 Row += 1
1546 for j in range(2):
1547 for i in range(DIV_COUNT + 1):
1548 z = Height_Offset - (Height_Step * i)
1549 if z > Height_Start:
1550 z = Height_Start
1551 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
1552 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
1553 verts.append([x, y, z])
1554 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1555 Height_Offset -= Crest_Height
1556 Row += 1
1558 for i in range(DIV_COUNT + 1):
1559 z = Height_Offset - (Height_Step * i)
1560 if z > Height_Start:
1561 z = Height_Start
1563 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
1564 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
1565 verts.append([x, y, z])
1566 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1567 Height_Offset -= Crest_to_Root_Height
1568 Row += 1
1570 for i in range(DIV_COUNT + 1):
1571 z = Height_Offset - (Height_Step * i)
1572 if z > Height_Start:
1573 z = Height_Start
1575 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
1576 y = cos(radians(i * Deg_Step)) * INNER_RADIUS
1577 if j == 0:
1578 x = sin(radians(i * Deg_Step)) * (OUTTER_RADIUS - (i * Rank))
1579 y = cos(radians(i * Deg_Step)) * (OUTTER_RADIUS - (i * Rank))
1580 verts.append([x, y, z])
1581 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1582 Height_Offset -= Root_Height
1583 Row += 1
1585 for i in range(DIV_COUNT + 1):
1586 z = Height_Offset - (Height_Step * i)
1587 if z > Height_Start:
1588 z = Height_Start
1590 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
1591 y = cos(radians(i * Deg_Step)) * INNER_RADIUS
1593 if j == 0:
1594 x = sin(radians(i * Deg_Step)) * (OUTTER_RADIUS - (i * Rank))
1595 y = cos(radians(i * Deg_Step)) * (OUTTER_RADIUS - (i * Rank))
1596 verts.append([x, y, z])
1597 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1598 Height_Offset -= Root_to_Crest_Height
1599 Row += 1
1601 return verts, Row, Height_Offset
1604 def Create_Thread_Verts(INNER_DIA, OUTTER_DIA, PITCH, HEIGHT,
1605 CREST_PERCENT, ROOT_PERCENT, Z_LOCATION, DIV_COUNT):
1607 verts = []
1609 INNER_RADIUS = INNER_DIA / 2
1610 OUTTER_RADIUS = OUTTER_DIA / 2
1612 Deg_Step = 360.0 / float(DIV_COUNT)
1613 Height_Step = float(PITCH) / float(DIV_COUNT)
1615 NUM_OF_START_THREADS = 4.0
1616 NUM_OF_END_THREADS = 3.0
1617 Num = int((HEIGHT - ((NUM_OF_START_THREADS * PITCH) + (NUM_OF_END_THREADS * PITCH))) / PITCH)
1618 Row = 0
1620 Crest_Height = float(PITCH) * float(CREST_PERCENT) / float(100)
1621 Root_Height = float(PITCH) * float(ROOT_PERCENT) / float(100)
1622 Root_to_Crest_Height = Crest_to_Root_Height = \
1623 (float(PITCH) - (Crest_Height + Root_Height)) / 2.0
1625 Height_Offset = Z_LOCATION
1627 Lowest_Z_Vert = 0
1629 for j in range(Num):
1631 for i in range(DIV_COUNT + 1):
1632 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
1633 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
1634 z = Height_Offset - (Height_Step * i)
1635 verts.append([x, y, z])
1636 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1637 Height_Offset -= Crest_Height
1638 Row += 1
1640 for i in range(DIV_COUNT + 1):
1641 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
1642 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
1643 z = Height_Offset - (Height_Step * i)
1644 verts.append([x, y, z])
1645 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1646 Height_Offset -= Crest_to_Root_Height
1647 Row += 1
1649 for i in range(DIV_COUNT + 1):
1650 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
1651 y = cos(radians(i * Deg_Step)) * INNER_RADIUS
1652 z = Height_Offset - (Height_Step * i)
1653 verts.append([x, y, z])
1654 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1655 Height_Offset -= Root_Height
1656 Row += 1
1658 for i in range(DIV_COUNT + 1):
1659 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
1660 y = cos(radians(i * Deg_Step)) * INNER_RADIUS
1661 z = Height_Offset - (Height_Step * i)
1662 verts.append([x, y, z])
1663 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1664 Height_Offset -= Root_to_Crest_Height
1665 Row += 1
1667 return verts, Row, Height_Offset
1670 def Create_Thread_End_Verts(INNER_DIA, OUTTER_DIA, PITCH, CREST_PERCENT,
1671 ROOT_PERCENT, Z_LOCATION, DIV_COUNT):
1672 verts = []
1674 INNER_RADIUS = INNER_DIA / 2
1675 OUTTER_RADIUS = OUTTER_DIA / 2
1677 Deg_Step = 360.0 / float(DIV_COUNT)
1678 Height_Step = float(PITCH) / float(DIV_COUNT)
1680 Crest_Height = float(PITCH) * float(CREST_PERCENT) / float(100)
1681 Root_Height = float(PITCH) * float(ROOT_PERCENT) / float(100)
1682 Root_to_Crest_Height = Crest_to_Root_Height = \
1683 (float(PITCH) - (Crest_Height + Root_Height)) / 2.0
1685 Row = 0
1687 Height_Offset = Z_LOCATION
1688 Tapper_Height_Start = Height_Offset - PITCH - PITCH
1689 Max_Height = Tapper_Height_Start - PITCH
1690 Lowest_Z_Vert = 0
1692 for j in range(4):
1694 for i in range(DIV_COUNT + 1):
1695 z = Height_Offset - (Height_Step * i)
1696 z = max(z, Max_Height)
1697 Tapper_Radius = OUTTER_RADIUS
1698 if z < Tapper_Height_Start:
1699 Tapper_Radius = OUTTER_RADIUS - (Tapper_Height_Start - z)
1701 x = sin(radians(i * Deg_Step)) * (Tapper_Radius)
1702 y = cos(radians(i * Deg_Step)) * (Tapper_Radius)
1703 verts.append([x, y, z])
1704 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1705 Height_Offset -= Crest_Height
1706 Row += 1
1708 for i in range(DIV_COUNT + 1):
1709 z = Height_Offset - (Height_Step * i)
1710 z = max(z, Max_Height)
1711 Tapper_Radius = OUTTER_RADIUS
1712 if z < Tapper_Height_Start:
1713 Tapper_Radius = OUTTER_RADIUS - (Tapper_Height_Start - z)
1715 x = sin(radians(i * Deg_Step)) * (Tapper_Radius)
1716 y = cos(radians(i * Deg_Step)) * (Tapper_Radius)
1717 verts.append([x, y, z])
1718 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1719 Height_Offset -= Crest_to_Root_Height
1720 Row += 1
1722 for i in range(DIV_COUNT + 1):
1723 z = Height_Offset - (Height_Step * i)
1724 z = max(z, Max_Height)
1725 Tapper_Radius = OUTTER_RADIUS - (Tapper_Height_Start - z)
1726 if Tapper_Radius > INNER_RADIUS:
1727 Tapper_Radius = INNER_RADIUS
1729 x = sin(radians(i * Deg_Step)) * (Tapper_Radius)
1730 y = cos(radians(i * Deg_Step)) * (Tapper_Radius)
1731 verts.append([x, y, z])
1732 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1733 Height_Offset -= Root_Height
1734 Row += 1
1736 for i in range(DIV_COUNT + 1):
1737 z = Height_Offset - (Height_Step * i)
1738 z = max(z, Max_Height)
1739 Tapper_Radius = OUTTER_RADIUS - (Tapper_Height_Start - z)
1740 if Tapper_Radius > INNER_RADIUS:
1741 Tapper_Radius = INNER_RADIUS
1743 x = sin(radians(i * Deg_Step)) * (Tapper_Radius)
1744 y = cos(radians(i * Deg_Step)) * (Tapper_Radius)
1745 verts.append([x, y, z])
1746 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1747 Height_Offset -= Root_to_Crest_Height
1748 Row += 1
1750 return verts, Row, Height_Offset, Lowest_Z_Vert
1753 def Create_External_Thread(SHANK_DIA, SHANK_LENGTH, INNER_DIA, OUTTER_DIA,
1754 PITCH, LENGTH, CREST_PERCENT, ROOT_PERCENT, DIV_COUNT):
1756 verts = []
1757 faces = []
1759 Total_Row = 0
1760 # Thread_Len = 0 # UNUSED
1762 Face_Start = len(verts)
1763 Offset = 0.0
1765 Shank_Verts, Shank_Row, Offset = Create_Shank_Verts(
1766 SHANK_DIA, OUTTER_DIA, SHANK_LENGTH,
1767 Offset, DIV_COUNT
1769 Total_Row += Shank_Row
1771 Thread_Start_Verts, Thread_Start_Row, Offset = Create_Thread_Start_Verts(
1772 INNER_DIA, OUTTER_DIA, PITCH, CREST_PERCENT,
1773 ROOT_PERCENT, Offset, DIV_COUNT
1775 Total_Row += Thread_Start_Row
1777 Thread_Verts, Thread_Row, Offset = Create_Thread_Verts(
1778 INNER_DIA, OUTTER_DIA, PITCH, LENGTH,
1779 CREST_PERCENT, ROOT_PERCENT, Offset, DIV_COUNT
1781 Total_Row += Thread_Row
1783 Thread_End_Verts, Thread_End_Row, Offset, Lowest_Z_Vert = Create_Thread_End_Verts(
1784 INNER_DIA, OUTTER_DIA, PITCH, CREST_PERCENT,
1785 ROOT_PERCENT, Offset, DIV_COUNT
1787 Total_Row += Thread_End_Row
1789 verts.extend(Shank_Verts)
1790 verts.extend(Thread_Start_Verts)
1791 verts.extend(Thread_Verts)
1792 verts.extend(Thread_End_Verts)
1794 faces.extend(Build_Face_List_Quads(Face_Start, DIV_COUNT, Total_Row - 1, 0))
1795 faces.extend(Fill_Ring_Face(len(verts) - DIV_COUNT, DIV_COUNT, 1))
1797 return verts, faces, 0.0 - Lowest_Z_Vert
1800 # ####################################################################
1801 # Create Nut
1802 # ####################################################################
1804 def add_Hex_Nut(FLAT, HOLE_DIA, HEIGHT):
1805 global Global_Head_Height
1806 global Global_NutRad
1808 verts = []
1809 faces = []
1810 HOLE_RADIUS = HOLE_DIA * 0.5
1811 Half_Flat = FLAT / 2
1812 Half_Height = HEIGHT / 2
1813 TopBevelRadius = Half_Flat - 0.05
1815 Global_NutRad = TopBevelRadius
1817 Row = 0
1818 Lowest_Z_Vert = 0.0
1820 verts.append([0.0, 0.0, 0.0])
1822 FaceStart = len(verts)
1823 # inner hole
1825 x = sin(radians(0)) * HOLE_RADIUS
1826 y = cos(radians(0)) * HOLE_RADIUS
1827 # print ("rad 0 x;", x, "y:" ,y )
1828 verts.append([x, y, 0.0])
1830 x = sin(radians(60 / 6)) * HOLE_RADIUS
1831 y = cos(radians(60 / 6)) * HOLE_RADIUS
1832 # print ("rad 60/6x;", x, "y:" ,y )
1833 verts.append([x, y, 0.0])
1835 x = sin(radians(60 / 3)) * HOLE_RADIUS
1836 y = cos(radians(60 / 3)) * HOLE_RADIUS
1837 # print ("rad 60/3x;", x, "y:" ,y )
1838 verts.append([x, y, 0.0])
1840 x = sin(radians(60 / 2)) * HOLE_RADIUS
1841 y = cos(radians(60 / 2)) * HOLE_RADIUS
1842 # print ("rad 60/2x;", x, "y:" ,y )
1843 verts.append([x, y, 0.0])
1844 Row += 1
1846 # Bevel
1848 x = sin(radians(0)) * TopBevelRadius
1849 y = cos(radians(0)) * TopBevelRadius
1850 vec1 = Vector([x, y, 0.0])
1851 verts.append([x, y, 0.0])
1853 x = sin(radians(60 / 6)) * TopBevelRadius
1854 y = cos(radians(60 / 6)) * TopBevelRadius
1855 vec2 = Vector([x, y, 0.0])
1856 verts.append([x, y, 0.0])
1858 x = sin(radians(60 / 3)) * TopBevelRadius
1859 y = cos(radians(60 / 3)) * TopBevelRadius
1860 vec3 = Vector([x, y, 0.0])
1861 verts.append([x, y, 0.0])
1863 x = sin(radians(60 / 2)) * TopBevelRadius
1864 y = cos(radians(60 / 2)) * TopBevelRadius
1865 vec4 = Vector([x, y, 0.0])
1866 verts.append([x, y, 0.0])
1867 Row += 1
1869 # Flats
1870 x = tan(radians(0)) * Half_Flat
1871 dvec = vec1 - Vector([x, Half_Flat, 0.0])
1872 verts.append([x, Half_Flat, -dvec.length])
1873 Lowest_Z_Vert = min(Lowest_Z_Vert, -dvec.length)
1875 x = tan(radians(60 / 6)) * Half_Flat
1876 dvec = vec2 - Vector([x, Half_Flat, 0.0])
1877 verts.append([x, Half_Flat, -dvec.length])
1878 Lowest_Z_Vert = min(Lowest_Z_Vert, -dvec.length)
1880 x = tan(radians(60 / 3)) * Half_Flat
1881 dvec = vec3 - Vector([x, Half_Flat, 0.0])
1882 Lowest_Point = -dvec.length
1883 verts.append([x, Half_Flat, -dvec.length])
1884 Lowest_Z_Vert = min(Lowest_Z_Vert, -dvec.length)
1886 x = tan(radians(60 / 2)) * Half_Flat
1887 dvec = vec4 - Vector([x, Half_Flat, 0.0])
1888 Lowest_Point = -dvec.length
1889 verts.append([x, Half_Flat, -dvec.length])
1890 Lowest_Z_Vert = min(Lowest_Z_Vert, -dvec.length)
1891 Row += 1
1893 # down Bits Tri
1894 x = tan(radians(0)) * Half_Flat
1895 verts.append([x, Half_Flat, Lowest_Point])
1897 x = tan(radians(60 / 6)) * Half_Flat
1898 verts.append([x, Half_Flat, Lowest_Point])
1899 x = tan(radians(60 / 3)) * Half_Flat
1900 verts.append([x, Half_Flat, Lowest_Point])
1902 x = tan(radians(60 / 2)) * Half_Flat
1903 verts.append([x, Half_Flat, Lowest_Point])
1904 Lowest_Z_Vert = min(Lowest_Z_Vert, Lowest_Point)
1905 Row += 1
1907 # down Bits
1909 x = tan(radians(0)) * Half_Flat
1910 verts.append([x, Half_Flat, -Half_Height])
1912 x = tan(radians(60 / 6)) * Half_Flat
1913 verts.append([x, Half_Flat, -Half_Height])
1915 x = tan(radians(60 / 3)) * Half_Flat
1916 verts.append([x, Half_Flat, -Half_Height])
1918 x = tan(radians(60 / 2)) * Half_Flat
1919 verts.append([x, Half_Flat, -Half_Height])
1920 Lowest_Z_Vert = min(Lowest_Z_Vert, -Half_Height)
1921 Row += 1
1923 faces.extend(Build_Face_List_Quads(FaceStart, 3, Row - 1))
1925 Global_Head_Height = HEIGHT
1927 Tvert, tface = Mirror_Verts_Faces(verts, faces, 'z', Lowest_Z_Vert)
1928 verts.extend(Tvert)
1929 faces.extend(tface)
1931 Tvert, tface = Mirror_Verts_Faces(verts, faces, 'y')
1932 verts.extend(Tvert)
1933 faces.extend(tface)
1935 S_verts, S_faces = SpinDup(verts, faces, 360, 6, 'z')
1937 # return verts, faces, TopBevelRadius
1938 return S_verts, S_faces, TopBevelRadius
1941 def add_Nylon_Head(OUTSIDE_RADIUS, Z_LOCATION, DIV_COUNT):
1942 verts = []
1943 faces = []
1944 Row = 0
1946 INNER_HOLE = OUTSIDE_RADIUS - (OUTSIDE_RADIUS * (1.25 / 4.75))
1947 EDGE_THICKNESS = (OUTSIDE_RADIUS * (0.4 / 4.75))
1948 RAD1 = (OUTSIDE_RADIUS * (0.5 / 4.75))
1949 OVER_ALL_HEIGHT = (OUTSIDE_RADIUS * (2.0 / 4.75))
1951 FaceStart = len(verts)
1953 # Start_Height = 0 - 3 # UNUSED
1954 Height_Offset = Z_LOCATION
1955 Lowest_Z_Vert = 0
1957 x = INNER_HOLE
1958 z = (Height_Offset - OVER_ALL_HEIGHT) + EDGE_THICKNESS
1959 verts.append([x, 0.0, z])
1960 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1961 Row += 1
1963 x = INNER_HOLE
1964 z = (Height_Offset - OVER_ALL_HEIGHT)
1965 verts.append([x, 0.0, z])
1966 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1967 Row += 1
1969 for i in range(180, 80, -10):
1970 x = sin(radians(i)) * RAD1
1971 z = cos(radians(i)) * RAD1
1972 verts.append([(OUTSIDE_RADIUS - RAD1) + x, 0.0, ((Height_Offset - OVER_ALL_HEIGHT) + RAD1) + z])
1973 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1974 Row += 1
1976 x = OUTSIDE_RADIUS - 0
1977 z = Height_Offset
1978 verts.append([x, 0.0, z])
1979 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1980 Row += 1
1982 sVerts, sFaces = SpinDup(verts, faces, 360, DIV_COUNT, 'z')
1983 sVerts.extend(verts) # add the start verts to the Spin verts to complete the loop
1985 faces.extend(Build_Face_List_Quads(FaceStart, Row - 1, DIV_COUNT,1))
1987 return Move_Verts_Up_Z(sVerts, 0), faces, Lowest_Z_Vert
1990 def add_Nylon_Part(OUTSIDE_RADIUS, Z_LOCATION, DIV_COUNT):
1991 verts = []
1992 faces = []
1993 Row = 0
1995 INNER_HOLE = OUTSIDE_RADIUS - (OUTSIDE_RADIUS * (1.5 / 4.75))
1996 EDGE_THICKNESS = (OUTSIDE_RADIUS * (0.4 / 4.75))
1997 OVER_ALL_HEIGHT = (OUTSIDE_RADIUS * (2.0 / 4.75))
1998 PART_THICKNESS = OVER_ALL_HEIGHT - EDGE_THICKNESS
1999 PART_INNER_HOLE = (OUTSIDE_RADIUS * (2.5 / 4.75))
2001 FaceStart = len(verts)
2003 Height_Offset = Z_LOCATION
2004 Lowest_Z_Vert = 0
2006 x = INNER_HOLE + EDGE_THICKNESS
2007 z = Height_Offset
2008 verts.append([x, 0.0, z])
2009 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
2010 Row += 1
2012 x = PART_INNER_HOLE
2013 z = Height_Offset
2014 verts.append([x, 0.0, z])
2015 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
2016 Row += 1
2018 x = PART_INNER_HOLE
2019 z = Height_Offset - PART_THICKNESS
2020 verts.append([x, 0.0, z])
2021 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
2022 Row += 1
2024 x = INNER_HOLE + EDGE_THICKNESS
2025 z = Height_Offset - PART_THICKNESS
2026 verts.append([x, 0.0, z])
2027 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
2028 Row += 1
2030 sVerts, sFaces = SpinDup(verts, faces, 360, DIV_COUNT, 'z')
2031 sVerts.extend(verts) # add the start verts to the Spin verts to complete the loop
2033 faces.extend(Build_Face_List_Quads(FaceStart, Row - 1, DIV_COUNT, 1))
2035 return sVerts, faces, 0 - Lowest_Z_Vert
2038 def add_12_Point_Nut(FLAT, HOLE_DIA, HEIGHT,FLANGE_DIA):
2039 return Create_12_Point(FLAT, HOLE_DIA,HOLE_DIA, HEIGHT,FLANGE_DIA)
2043 # ####################################################################
2044 # Create Internal Thread
2045 # ####################################################################
2047 def Create_Internal_Thread_Start_Verts(verts, INNER_RADIUS, OUTTER_RADIUS, PITCH, DIV,
2048 CREST_PERCENT, ROOT_PERCENT, Height_Offset):
2050 Ret_Row = 0
2051 # Move the offset up so that the verts start at
2052 # at the correct place (Height_Start)
2053 Height_Offset = Height_Offset + PITCH
2055 Height_Start = Height_Offset - PITCH
2056 Height_Step = float(PITCH) / float(DIV)
2057 Deg_Step = 360.0 / float(DIV)
2059 Crest_Height = float(PITCH) * float(CREST_PERCENT) / float(100)
2060 Root_Height = float(PITCH) * float(ROOT_PERCENT) / float(100)
2061 Root_to_Crest_Height = Crest_to_Root_Height = \
2062 (float(PITCH) - (Crest_Height + Root_Height)) / 2.0
2064 Rank = float(OUTTER_RADIUS - INNER_RADIUS) / float(DIV)
2066 for i in range(DIV + 1):
2067 z = Height_Offset - (Height_Step * i)
2068 if z > Height_Start:
2069 z = Height_Start
2070 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
2071 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
2073 verts.append([x, y, z])
2074 Height_Offset -= Crest_Height
2075 Ret_Row += 1
2077 for i in range(DIV + 1):
2078 z = Height_Offset - (Height_Step * i)
2079 if z > Height_Start:
2080 z = Height_Start
2082 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
2083 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
2085 verts.append([x, y, z])
2086 Height_Offset -= Crest_to_Root_Height
2087 Ret_Row += 1
2089 for i in range(DIV + 1):
2090 z = Height_Offset - (Height_Step * i)
2091 if z > Height_Start:
2092 z = Height_Start
2094 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
2095 y = cos(radians(i * Deg_Step)) * INNER_RADIUS
2097 x = sin(radians(i * Deg_Step)) * (OUTTER_RADIUS - (i * Rank))
2098 y = cos(radians(i * Deg_Step)) * (OUTTER_RADIUS - (i * Rank))
2100 verts.append([x, y, z])
2101 Height_Offset -= Root_Height
2102 Ret_Row += 1
2104 for i in range(DIV + 1):
2105 z = Height_Offset - (Height_Step * i)
2106 if z > Height_Start:
2107 z = Height_Start
2109 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
2110 y = cos(radians(i * Deg_Step)) * INNER_RADIUS
2112 x = sin(radians(i * Deg_Step)) * (OUTTER_RADIUS - (i * Rank))
2113 y = cos(radians(i * Deg_Step)) * (OUTTER_RADIUS - (i * Rank))
2115 verts.append([x, y, z])
2116 Height_Offset -= Root_to_Crest_Height
2117 Ret_Row += 1
2119 return Ret_Row, Height_Offset
2122 def Create_Internal_Thread_End_Verts(verts, INNER_RADIUS, OUTTER_RADIUS, PITCH,
2123 CREST_PERCENT, ROOT_PERCENT, Height_Offset,
2124 DIV_COUNT):
2125 Ret_Row = 0
2126 Height_End = Height_Offset - PITCH
2127 Height_Step = float(PITCH) / float(DIV_COUNT)
2128 Deg_Step = 360.0 / float(DIV_COUNT)
2130 Crest_Height = float(PITCH) * float(CREST_PERCENT) / float(100)
2131 Root_Height = float(PITCH) * float(ROOT_PERCENT) / float(100)
2132 Root_to_Crest_Height = Crest_to_Root_Height = \
2133 (float(PITCH) - (Crest_Height + Root_Height)) / 2.0
2135 Rank = float(OUTTER_RADIUS - INNER_RADIUS) / float(DIV_COUNT)
2137 Num = 0
2139 for j in range(2):
2140 for i in range(DIV_COUNT + 1):
2141 z = Height_Offset - (Height_Step * i)
2142 if z < Height_End:
2143 z = Height_End
2144 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
2145 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
2146 verts.append([x, y, z])
2148 Height_Offset -= Crest_Height
2149 Ret_Row += 1
2151 for i in range(DIV_COUNT + 1):
2152 z = Height_Offset - (Height_Step * i)
2153 if z < Height_End:
2154 z = Height_End
2156 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
2157 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
2158 verts.append([x, y, z])
2160 Height_Offset -= Crest_to_Root_Height
2161 Ret_Row += 1
2163 for i in range(DIV_COUNT + 1):
2164 z = Height_Offset - (Height_Step * i)
2165 if z < Height_End:
2166 z = Height_End
2168 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
2169 y = cos(radians(i * Deg_Step)) * INNER_RADIUS
2171 if j == Num:
2172 # Fix T51338 - seems that the placing a small random offset makes the mesh valid
2173 rand_offset = triangular(0.0001, 0.009)
2174 x = sin(radians(i * Deg_Step)) * (INNER_RADIUS + (i * Rank + rand_offset))
2175 y = cos(radians(i * Deg_Step)) * (INNER_RADIUS + (i * Rank + rand_offset))
2177 if j > Num:
2178 x = sin(radians(i * Deg_Step)) * (OUTTER_RADIUS)
2179 y = cos(radians(i * Deg_Step)) * (OUTTER_RADIUS)
2181 verts.append([x, y, z])
2183 Height_Offset -= Root_Height
2184 Ret_Row += 1
2186 for i in range(DIV_COUNT + 1):
2187 z = Height_Offset - (Height_Step * i)
2188 if z < Height_End:
2189 z = Height_End
2191 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
2192 y = cos(radians(i * Deg_Step)) * INNER_RADIUS
2194 if j == Num:
2195 x = sin(radians(i * Deg_Step)) * (INNER_RADIUS + (i * Rank))
2196 y = cos(radians(i * Deg_Step)) * (INNER_RADIUS + (i * Rank))
2197 if j > Num:
2198 x = sin(radians(i * Deg_Step)) * (OUTTER_RADIUS)
2199 y = cos(radians(i * Deg_Step)) * (OUTTER_RADIUS)
2201 verts.append([x, y, z])
2203 Height_Offset -= Root_to_Crest_Height
2204 Ret_Row += 1
2206 return Ret_Row, Height_End # send back Height End as this is the lowest point
2209 def Create_Internal_Thread(INNER_DIA, OUTTER_DIA, PITCH, HEIGHT,
2210 CREST_PERCENT, ROOT_PERCENT, INTERNAL, DIV_COUNT):
2211 verts = []
2212 faces = []
2214 INNER_RADIUS = INNER_DIA / 2
2215 OUTTER_RADIUS = OUTTER_DIA / 2
2217 Deg_Step = 360.0 / float(DIV_COUNT)
2218 Height_Step = float(PITCH) / float(DIV_COUNT)
2220 # less one pitch for the start and end that is 1/2 pitch high
2221 Num = int(round((HEIGHT - PITCH) / PITCH))
2223 Row = 0
2225 Crest_Height = float(PITCH) * float(CREST_PERCENT) / float(100)
2226 Root_Height = float(PITCH) * float(ROOT_PERCENT) / float(100)
2227 Root_to_Crest_Height = Crest_to_Root_Height = \
2228 (float(PITCH) - (Crest_Height + Root_Height)) / 2.0
2230 Height_Offset = 0
2231 FaceStart = len(verts)
2233 Row_Inc, Height_Offset = Create_Internal_Thread_Start_Verts(
2234 verts, INNER_RADIUS, OUTTER_RADIUS, PITCH,
2235 DIV_COUNT, CREST_PERCENT, ROOT_PERCENT,
2236 Height_Offset
2238 Row += Row_Inc
2240 for j in range(Num):
2242 for i in range(DIV_COUNT + 1):
2243 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
2244 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
2245 verts.append([x, y, Height_Offset - (Height_Step * i)])
2246 Height_Offset -= Crest_Height
2247 Row += 1
2249 for i in range(DIV_COUNT + 1):
2250 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
2251 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
2252 verts.append([x, y, Height_Offset - (Height_Step * i)])
2253 Height_Offset -= Crest_to_Root_Height
2254 Row += 1
2256 for i in range(DIV_COUNT + 1):
2257 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
2258 y = cos(radians(i * Deg_Step)) * INNER_RADIUS
2259 verts.append([x, y, Height_Offset - (Height_Step * i)])
2260 Height_Offset -= Root_Height
2261 Row += 1
2263 for i in range(DIV_COUNT + 1):
2264 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
2265 y = cos(radians(i * Deg_Step)) * INNER_RADIUS
2266 verts.append([x, y, Height_Offset - (Height_Step * i)])
2267 Height_Offset -= Root_to_Crest_Height
2268 Row += 1
2270 Row_Inc, Height_Offset = Create_Internal_Thread_End_Verts(
2271 verts, INNER_RADIUS, OUTTER_RADIUS,
2272 PITCH, CREST_PERCENT,
2273 ROOT_PERCENT, Height_Offset, DIV_COUNT
2276 Row += Row_Inc
2277 faces.extend(Build_Face_List_Quads(FaceStart, DIV_COUNT, Row - 1, FLIP=1))
2279 return verts, faces, 0 - Height_Offset
2282 def Nut_Mesh(props, context):
2284 verts = []
2285 faces = []
2286 Head_Verts = []
2287 Head_Faces = []
2290 Face_Start = len(verts)
2293 if props.bf_Nut_Type == 'bf_Nut_12Pnt':
2294 Nut_Height = props.bf_12_Point_Nut_Height
2295 else:
2296 Nut_Height = props.bf_Hex_Nut_Height
2298 Thread_Verts, Thread_Faces, New_Nut_Height = Create_Internal_Thread(
2299 props.bf_Minor_Dia, props.bf_Major_Dia,
2300 props.bf_Pitch, Nut_Height,
2301 props.bf_Crest_Percent, props.bf_Root_Percent,
2302 1, props.bf_Div_Count
2304 verts.extend(Thread_Verts)
2305 faces.extend(Copy_Faces(Thread_Faces, Face_Start))
2307 Face_Start = len(verts)
2309 if props.bf_Nut_Type == 'bf_Nut_12Pnt':
2310 Head_Verts, Head_Faces, Lock_Nut_Rad = add_12_Point_Nut(
2311 props.bf_12_Point_Nut_Flat_Distance,
2312 props.bf_Major_Dia, New_Nut_Height,
2313 #Limit the size of the Flange to avoid calculation error
2314 max(props.bf_12_Point_Nut_Flange_Dia,props.bf_12_Point_Nut_Flat_Distance)
2316 else:
2317 Head_Verts, Head_Faces, Lock_Nut_Rad = add_Hex_Nut(
2318 props.bf_Hex_Nut_Flat_Distance,
2319 props.bf_Major_Dia, New_Nut_Height
2321 verts.extend((Head_Verts))
2322 faces.extend(Copy_Faces(Head_Faces, Face_Start))
2324 LowZ = 0 - New_Nut_Height
2326 if props.bf_Nut_Type == 'bf_Nut_Lock':
2327 Face_Start = len(verts)
2328 Nylon_Head_Verts, Nylon_Head_faces, LowZ = add_Nylon_Head(
2329 Lock_Nut_Rad, 0 - New_Nut_Height,
2330 props.bf_Div_Count
2332 verts.extend((Nylon_Head_Verts))
2333 faces.extend(Copy_Faces(Nylon_Head_faces, Face_Start))
2335 Face_Start = len(verts)
2336 Nylon_Verts, Nylon_faces, Temp_LowZ = add_Nylon_Part(
2337 Lock_Nut_Rad, 0 - New_Nut_Height,
2338 props.bf_Div_Count
2340 verts.extend((Nylon_Verts))
2341 faces.extend(Copy_Faces(Nylon_faces, Face_Start))
2343 return Move_Verts_Up_Z(verts, 0 - LowZ), faces
2346 # ####################################################################
2347 # Create Bolt
2348 # ####################################################################
2350 def Bolt_Mesh(props, context):
2352 verts = []
2353 faces = []
2354 Bit_Verts = []
2355 Bit_Faces = []
2356 Bit_Dia = 0.001
2357 Head_Verts = []
2358 Head_Faces = []
2359 Head_Height = 0.0
2361 ReSized_Allen_Bit_Flat_Distance = props.bf_Allen_Bit_Flat_Distance # set default
2363 Head_Height = props.bf_Hex_Head_Height # will be changed by the Head Functions
2365 if props.bf_Bit_Type == 'bf_Bit_Allen' and props.bf_Head_Type == 'bf_Head_Pan':
2366 # need to size Allen bit if it is too big.
2367 if Allen_Bit_Dia(props.bf_Allen_Bit_Flat_Distance) > Max_Pan_Bit_Dia(props.bf_Pan_Head_Dia):
2368 ReSized_Allen_Bit_Flat_Distance = Allen_Bit_Dia_To_Flat(
2369 Max_Pan_Bit_Dia(props.bf_Pan_Head_Dia)
2371 ReSized_Allen_Bit_Flat_Distance -= ReSized_Allen_Bit_Flat_Distance * 0.05 # It looks better if it is just a bit smaller
2372 # print ("Resized Allen Bit Flat Distance to ",ReSized_Allen_Bit_Flat_Distance)
2374 # Bit Mesh
2375 if props.bf_Bit_Type == 'bf_Bit_Allen':
2376 Bit_Verts, Bit_Faces, Bit_Dia = Create_Allen_Bit(
2377 ReSized_Allen_Bit_Flat_Distance,
2378 props.bf_Allen_Bit_Depth
2381 if props.bf_Bit_Type == 'bf_Bit_Torx':
2382 Bit_Verts, Bit_Faces, Bit_Dia = Create_Torx_Bit(
2383 Torx_Bit_Size_To_Point_Distance(props.bf_Torx_Size_Type),
2384 props.bf_Torx_Bit_Depth
2388 if props.bf_Bit_Type == 'bf_Bit_Philips':
2389 Bit_Verts, Bit_Faces, Bit_Dia = Create_Phillips_Bit(
2390 props.bf_Philips_Bit_Dia,
2391 props.bf_Philips_Bit_Dia * (0.5 / 1.82),
2392 props.bf_Phillips_Bit_Depth
2394 # Head Mesh
2395 if props.bf_Head_Type == 'bf_Head_Hex':
2396 Head_Verts, Head_Faces, Head_Height = Create_Hex_Head(
2397 props.bf_Hex_Head_Flat_Distance, Bit_Dia,
2398 props.bf_Shank_Dia, props.bf_Hex_Head_Height
2401 elif props.bf_Head_Type == 'bf_Head_12Pnt':
2402 Head_Verts, Head_Faces, Head_Height = Create_12_Point_Head(
2403 props.bf_12_Point_Head_Flat_Distance, Bit_Dia,
2404 props.bf_Shank_Dia, props.bf_12_Point_Head_Height,
2405 #Limit the size of the Flange to avoid calculation error
2406 max(props.bf_12_Point_Head_Flange_Dia,props.bf_12_Point_Head_Flat_Distance)
2408 elif props.bf_Head_Type == 'bf_Head_Cap':
2409 Head_Verts, Head_Faces, Head_Height = Create_Cap_Head(
2410 Bit_Dia, props.bf_Cap_Head_Dia,
2411 props.bf_Shank_Dia, props.bf_Cap_Head_Height,
2412 props.bf_Cap_Head_Dia * (1.0 / 19.0),
2413 props.bf_Cap_Head_Dia * (1.0 / 19.0),
2414 props.bf_Div_Count
2416 elif props.bf_Head_Type == 'bf_Head_Dome':
2417 Head_Verts, Head_Faces, Head_Height = Create_Dome_Head(
2418 Bit_Dia, props.bf_Dome_Head_Dia,
2419 props.bf_Shank_Dia, props.bf_Hex_Head_Height,
2420 1, 1, 0, props.bf_Div_Count
2423 elif props.bf_Head_Type == 'bf_Head_Pan':
2424 Head_Verts, Head_Faces, Head_Height = Create_Pan_Head(
2425 Bit_Dia, props.bf_Pan_Head_Dia,
2426 props.bf_Shank_Dia,
2427 props.bf_Hex_Head_Height, 1, 1, 0,
2428 props.bf_Div_Count
2430 elif props.bf_Head_Type == 'bf_Head_CounterSink':
2431 Head_Verts, Head_Faces, Head_Height = Create_CounterSink_Head(
2432 Bit_Dia, props.bf_CounterSink_Head_Dia,
2433 props.bf_Shank_Dia, props.bf_CounterSink_Head_Dia,
2434 props.bf_CounterSink_Head_Dia * (0.09 / 6.31),
2435 props.bf_Div_Count
2438 Face_Start = len(verts)
2439 verts.extend(Move_Verts_Up_Z(Bit_Verts, Head_Height))
2440 faces.extend(Copy_Faces(Bit_Faces, Face_Start))
2442 Face_Start = len(verts)
2443 verts.extend(Move_Verts_Up_Z(Head_Verts, Head_Height))
2444 faces.extend(Copy_Faces(Head_Faces, Face_Start))
2446 Face_Start = len(verts)
2447 Thread_Verts, Thread_Faces, Thread_Height = Create_External_Thread(
2448 props.bf_Shank_Dia, props.bf_Shank_Length,
2449 props.bf_Minor_Dia, props.bf_Major_Dia,
2450 props.bf_Pitch, props.bf_Thread_Length,
2451 props.bf_Crest_Percent,
2452 props.bf_Root_Percent, props.bf_Div_Count
2455 verts.extend(Move_Verts_Up_Z(Thread_Verts, 0))
2456 faces.extend(Copy_Faces(Thread_Faces, Face_Start))
2458 return Move_Verts_Up_Z(verts, Thread_Height), faces
2467 def Create_New_Mesh(props, context):
2469 verts = []
2470 faces = []
2471 edges = []
2472 sObjName = ''
2474 if props.bf_Model_Type == 'bf_Model_Bolt':
2475 # print('Create Bolt')
2476 verts, faces = Bolt_Mesh(props, context)
2477 sObjName = 'Bolt'
2479 if props.bf_Model_Type == 'bf_Model_Nut':
2480 # print('Create Nut')
2481 verts, faces = Nut_Mesh(props, context)
2482 sObjName = 'Nut'
2484 verts, faces = RemoveDoubles(verts, faces)
2486 verts = Scale_Mesh_Verts(verts, GLOBAL_SCALE)
2488 mesh = bpy.data.meshes.new(name=sObjName)
2489 mesh.from_pydata(verts, edges, faces)
2491 # useful for development when the mesh may be invalid.
2492 # Fix T51338 : Validate the mesh (the internal thread generator for the Nut
2493 # should be more reliable now, however there could be other possible errors)
2494 is_not_mesh_valid = mesh.validate()
2496 if is_not_mesh_valid:
2497 props.report({'INFO'}, "Mesh is not Valid, correcting")
2499 return mesh