File headers: use SPDX license identifiers
[blender-addons.git] / add_mesh_BoltFactory / createMesh.py
blob1da617ea8e03d82f60a6b9a23c145600f5651ba6
1 # SPDX-License-Identifier: GPL-2.0-or-later
3 import bpy
4 from mathutils import (
5 Matrix,
6 Vector,
7 geometry,
9 from math import (
10 sin, cos,
11 tan, radians,atan,degrees
13 from random import triangular
14 from bpy_extras.object_utils import AddObjectHelper, object_data_add
16 NARROW_UI = 180
17 MAX_INPUT_NUMBER = 50
19 GLOBAL_SCALE = 1 # 1 blender unit = X mm
22 # next two utility functions are stolen from import_obj.py
24 def unpack_list(list_of_tuples):
25 l = []
26 for t in list_of_tuples:
27 l.extend(t)
28 return l
31 def unpack_face_list(list_of_tuples):
32 l = []
33 for t in list_of_tuples:
34 face = [i for i in t]
36 if len(face) != 3 and len(face) != 4:
37 raise RuntimeError("{0} vertices in face".format(len(face)))
39 # rotate indices if the 4th is 0
40 if len(face) == 4 and face[3] == 0:
41 face = [face[3], face[0], face[1], face[2]]
43 if len(face) == 3:
44 face.append(0)
46 l.extend(face)
48 return l
51 """
52 Remove Doubles takes a list on Verts and a list of Faces and
53 removes the doubles, much like Blender does in edit mode.
54 It doesn't have the range function but it will round the coordinates
55 and remove verts that are very close together. The function
56 is useful because you can perform a "Remove Doubles" with out
57 having to enter Edit Mode. Having to enter edit mode has the
58 disadvantage of not being able to interactively change the properties.
59 """
62 def RemoveDoubles(verts, faces, Decimal_Places=4):
64 new_verts = []
65 new_faces = []
66 dict_verts = {}
67 Rounded_Verts = []
69 for v in verts:
70 Rounded_Verts.append([round(v[0], Decimal_Places),
71 round(v[1], Decimal_Places),
72 round(v[2], Decimal_Places)])
74 for face in faces:
75 new_face = []
76 for vert_index in face:
77 Real_co = tuple(verts[vert_index])
78 Rounded_co = tuple(Rounded_Verts[vert_index])
80 if Rounded_co not in dict_verts:
81 dict_verts[Rounded_co] = len(dict_verts)
82 new_verts.append(Real_co)
83 if dict_verts[Rounded_co] not in new_face:
84 new_face.append(dict_verts[Rounded_co])
85 if len(new_face) == 3 or len(new_face) == 4:
86 new_faces.append(new_face)
88 return new_verts, new_faces
91 def Scale_Mesh_Verts(verts, scale_factor):
92 Ret_verts = []
93 for v in verts:
94 Ret_verts.append([v[0] * scale_factor, v[1] * scale_factor, v[2] * scale_factor])
95 return Ret_verts
98 # Create a matrix representing a rotation.
100 # Parameters:
102 # * angle (float) - The angle of rotation desired.
103 # * matSize (int) - The size of the rotation matrix to construct. Can be 2d, 3d, or 4d.
104 # * axisFlag (string (optional)) - Possible values:
105 # o "x - x-axis rotation"
106 # o "y - y-axis rotation"
107 # o "z - z-axis rotation"
108 # o "r - arbitrary rotation around vector"
109 # * axis (Vector object. (optional)) - The arbitrary axis of rotation used with "R"
111 # Returns: Matrix object.
112 # A new rotation matrix.
114 def Simple_RotationMatrix(angle, matSize, axisFlag):
115 if matSize != 4:
116 print("Simple_RotationMatrix can only do 4x4")
118 q = radians(angle) # make the rotation go clockwise
120 if axisFlag == 'x':
121 matrix = Matrix.Rotation(q, 4, 'X')
122 elif axisFlag == 'y':
123 matrix = Matrix.Rotation(q, 4, 'Y')
124 elif axisFlag == 'z':
125 matrix = Matrix.Rotation(q, 4, 'Z')
126 else:
127 print("Simple_RotationMatrix can only do x y z axis")
128 return matrix
131 # ####################################################################
132 # Converter Functions For Bolt Factory
133 # ####################################################################
135 def Flat_To_Radius(FLAT):
136 h = (float(FLAT) / 2) / cos(radians(30))
137 return h
140 def Get_Phillips_Bit_Height(Bit_Dia):
141 Flat_Width_half = (Bit_Dia * (0.5 / 1.82)) / 2.0
142 Bit_Rad = Bit_Dia / 2.0
143 x = Bit_Rad - Flat_Width_half
144 y = tan(radians(60)) * x
145 return float(y)
148 # ####################################################################
149 # Miscellaneous Utilities
150 # ####################################################################
152 # Returns a list of verts rotated by the given matrix. Used by SpinDup
153 def Rot_Mesh(verts, matrix):
154 from mathutils import Vector
155 return [(matrix @ Vector(v))[:] for v in verts]
158 # Returns a list of faces that has there index incremented by offset
159 def Copy_Faces(faces, offset):
160 return [[(i + offset) for i in f] for f in faces]
163 # Much like Blenders built in SpinDup
164 def SpinDup(VERTS, FACES, DEGREE, DIVISIONS, AXIS):
165 verts = []
166 faces = []
168 if DIVISIONS == 0:
169 DIVISIONS = 1
171 step = DEGREE / DIVISIONS # set step so pieces * step = degrees in arc
173 for i in range(int(DIVISIONS)):
174 rotmat = Simple_RotationMatrix(step * i, 4, AXIS) # 4x4 rotation matrix, 30d about the x axis.
175 Rot = Rot_Mesh(VERTS, rotmat)
176 faces.extend(Copy_Faces(FACES, len(verts)))
177 verts.extend(Rot)
178 return verts, faces
181 # Returns a list of verts that have been moved up the z axis by DISTANCE
182 def Move_Verts_Up_Z(VERTS, DISTANCE):
183 ret = []
184 for v in VERTS:
185 ret.append([v[0], v[1], v[2] + DISTANCE])
186 return ret
189 # Returns a list of verts and faces that has been mirrored in the AXIS
190 def Mirror_Verts_Faces(VERTS, FACES, AXIS, FLIP_POINT=0):
191 ret_vert = []
192 ret_face = []
193 offset = len(VERTS)
194 if AXIS == 'y':
195 for v in VERTS:
196 Delta = v[0] - FLIP_POINT
197 ret_vert.append([FLIP_POINT - Delta, v[1], v[2]])
198 if AXIS == 'x':
199 for v in VERTS:
200 Delta = v[1] - FLIP_POINT
201 ret_vert.append([v[0], FLIP_POINT - Delta, v[2]])
202 if AXIS == 'z':
203 for v in VERTS:
204 Delta = v[2] - FLIP_POINT
205 ret_vert.append([v[0], v[1], FLIP_POINT - Delta])
207 for f in FACES:
208 fsub = []
209 for i in range(len(f)):
210 fsub.append(f[i] + offset)
211 fsub.reverse() # flip the order to make norm point out
212 ret_face.append(fsub)
214 return ret_vert, ret_face
217 # Returns a list of faces that
218 # make up an array of 4 point polygon.
219 def Build_Face_List_Quads(OFFSET, COLUMN, ROW, FLIP=0):
220 Ret = []
221 RowStart = 0
222 for j in range(ROW):
223 for i in range(COLUMN):
224 Res1 = RowStart + i
225 Res2 = RowStart + i + (COLUMN + 1)
226 Res3 = RowStart + i + (COLUMN + 1) + 1
227 Res4 = RowStart + i + 1
228 if FLIP:
229 Ret.append([OFFSET + Res1, OFFSET + Res2, OFFSET + Res3, OFFSET + Res4])
230 else:
231 Ret.append([OFFSET + Res4, OFFSET + Res3, OFFSET + Res2, OFFSET + Res1])
232 RowStart += COLUMN + 1
233 return Ret
236 # Returns a list of faces that makes up a fill pattern for a
237 # circle
238 def Fill_Ring_Face(OFFSET, NUM, FACE_DOWN=0):
239 Ret = []
240 Face = [1, 2, 0]
241 TempFace = [0, 0, 0]
242 # A = 0 # UNUSED
243 B = 1
244 C = 2
245 if NUM < 3:
246 return None
247 for i in range(NUM - 2):
248 if (i % 2):
249 TempFace[0] = Face[C]
250 TempFace[1] = Face[C] + 1
251 TempFace[2] = Face[B]
252 if FACE_DOWN:
253 Ret.append([OFFSET + Face[2], OFFSET + Face[1], OFFSET + Face[0]])
254 else:
255 Ret.append([OFFSET + Face[0], OFFSET + Face[1], OFFSET + Face[2]])
256 else:
257 TempFace[0] = Face[C]
258 if Face[C] == 0:
259 TempFace[1] = NUM - 1
260 else:
261 TempFace[1] = Face[C] - 1
262 TempFace[2] = Face[B]
263 if FACE_DOWN:
264 Ret.append([OFFSET + Face[0], OFFSET + Face[1], OFFSET + Face[2]])
265 else:
266 Ret.append([OFFSET + Face[2], OFFSET + Face[1], OFFSET + Face[0]])
268 Face[0] = TempFace[0]
269 Face[1] = TempFace[1]
270 Face[2] = TempFace[2]
271 return Ret
273 # Returns a list of faces that makes up a fill pattern around the last vert
274 def Fill_Fan_Face(OFFSET, NUM, FACE_DOWN=0):
275 Ret = []
276 Face = [NUM-1,0,1]
277 TempFace = [0, 0, 0]
278 A = 0
279 #B = 1 unused
280 C = 2
281 if NUM < 3:
282 return None
283 for _i in range(NUM - 2):
284 TempFace[0] = Face[A]
285 TempFace[1] = Face[C]
286 TempFace[2] = Face[C]+1
287 if FACE_DOWN:
288 Ret.append([OFFSET + Face[2], OFFSET + Face[1], OFFSET + Face[0]])
289 else:
290 Ret.append([OFFSET + Face[2], OFFSET + Face[1], OFFSET + Face[0]])
292 Face[0] = TempFace[0]
293 Face[1] = TempFace[1]
294 Face[2] = TempFace[2]
295 return Ret
297 # ####################################################################
298 # Create Allen Bit
299 # ####################################################################
301 def Allen_Fill(OFFSET, FLIP=0):
302 faces = []
303 Lookup = [[19, 1, 0],
304 [19, 2, 1],
305 [19, 3, 2],
306 [19, 20, 3],
307 [20, 4, 3],
308 [20, 5, 4],
309 [20, 6, 5],
310 [20, 7, 6],
311 [20, 8, 7],
312 [20, 9, 8],
314 [20, 21, 9],
316 [21, 10, 9],
317 [21, 11, 10],
318 [21, 12, 11],
319 [21, 13, 12],
320 [21, 14, 13],
321 [21, 15, 14],
323 [21, 22, 15],
324 [22, 16, 15],
325 [22, 17, 16],
326 [22, 18, 17]
328 for i in Lookup:
329 if FLIP:
330 faces.append([OFFSET + i[2], OFFSET + i[1], OFFSET + i[0]])
331 else:
332 faces.append([OFFSET + i[0], OFFSET + i[1], OFFSET + i[2]])
334 return faces
337 def Allen_Bit_Dia(FLAT_DISTANCE):
338 Flat_Radius = (float(FLAT_DISTANCE) / 2.0) / cos(radians(30))
339 return (Flat_Radius * 1.05) * 2.0
342 def Allen_Bit_Dia_To_Flat(DIA):
343 Flat_Radius = (DIA / 2.0) / 1.05
344 return (Flat_Radius * cos(radians(30))) * 2.0
347 def Create_Allen_Bit(FLAT_DISTANCE, HEIGHT):
348 verts = []
349 faces = []
350 DIV_COUNT = 36
352 Flat_Radius = (float(FLAT_DISTANCE) / 2.0) / cos(radians(30))
353 OUTTER_RADIUS = Flat_Radius * 1.05
354 Outter_Radius_Height = Flat_Radius * (0.1 / 5.77)
355 FaceStart_Outside = len(verts)
356 Deg_Step = 360.0 / float(DIV_COUNT)
358 for i in range(int(DIV_COUNT / 2) + 1): # only do half and mirror later
359 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
360 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
361 verts.append([x, y, 0])
363 FaceStart_Inside = len(verts)
365 Deg_Step = 360.0 / float(6)
366 for i in range(int(6 / 2) + 1):
367 x = sin(radians(i * Deg_Step)) * Flat_Radius
368 y = cos(radians(i * Deg_Step)) * Flat_Radius
369 verts.append([x, y, 0 - Outter_Radius_Height])
371 faces.extend(Allen_Fill(FaceStart_Outside, 0))
373 FaceStart_Bottom = len(verts)
375 Deg_Step = 360.0 / float(6)
376 for i in range(int(6 / 2) + 1):
377 x = sin(radians(i * Deg_Step)) * Flat_Radius
378 y = cos(radians(i * Deg_Step)) * Flat_Radius
379 verts.append([x, y, 0 - HEIGHT])
381 faces.extend(Build_Face_List_Quads(FaceStart_Inside, 3, 1, True))
382 faces.extend(Fill_Ring_Face(FaceStart_Bottom, 4))
384 M_Verts, M_Faces = Mirror_Verts_Faces(verts, faces, 'y')
385 verts.extend(M_Verts)
386 faces.extend(M_Faces)
388 return verts, faces, OUTTER_RADIUS * 2.0
389 # ####################################################################
390 # Create Torx Bit
391 # ####################################################################
393 def Torx_Bit_Size_To_Point_Distance(Bit_Size):
394 if Bit_Size == 'bf_Torx_T10':
395 return 2.83
396 elif Bit_Size == 'bf_Torx_T20':
397 return 3.94
398 elif Bit_Size == 'bf_Torx_T25':
399 return 4.52
400 elif Bit_Size == 'bf_Torx_T30':
401 return 5.61
402 elif Bit_Size == 'bf_Torx_T40':
403 return 6.75
404 elif Bit_Size == 'bf_Torx_T50':
405 return 8.94
406 elif Bit_Size == 'bf_Torx_T55':
407 return 8.94
408 else:
409 return 2.83 #default to M3
411 def Torx_Fill(OFFSET, FLIP=0):
412 faces = []
413 Lookup = [[0,10,11],
414 [0,11, 12],
415 [0,12,1],
417 [1, 12, 13],
418 [1, 13, 14],
419 [1, 14, 15],
420 [1, 15, 2],
422 [2, 15, 16],
423 [2, 16, 17],
424 [2, 17, 18],
425 [2, 18, 19],
426 [2, 19, 3],
428 [3, 19, 20],
429 [3, 20, 21],
430 [3, 21, 22],
431 [3, 22, 23],
432 [3, 23, 24],
433 [3, 24, 25],
434 [3, 25, 4],
437 [4, 25, 26],
438 [4, 26, 27],
439 [4, 27, 28],
440 [4, 28, 29],
441 [4, 29, 30],
442 [4, 30, 31],
443 [4, 31, 5],
445 [5, 31, 32],
446 [5, 32, 33],
447 [5, 33, 34],
448 [5, 34, 35],
449 [5, 35, 36],
450 [5, 36, 6],
452 [6, 36, 37],
453 [6, 37, 38],
454 [6, 38, 39],
455 [6, 39, 7],
457 [7, 39, 40],
458 [7, 40, 41],
459 [7, 41, 42],
460 [7, 42, 43],
461 [7, 43, 8],
463 [8, 43, 44],
464 [8, 44, 45],
465 [8, 45, 46],
466 [8, 46, 47],
467 [8, 47, 48],
468 [8, 48, 49],
469 [8, 49, 50],
470 [8, 50, 51],
471 [8, 51, 52],
472 [8, 52, 9],
474 for i in Lookup:
475 if FLIP:
476 faces.append([OFFSET + i[2], OFFSET + i[1], OFFSET + i[0]])
477 else:
478 faces.append([OFFSET + i[0], OFFSET + i[1], OFFSET + i[2]])
480 return faces
484 def Create_Torx_Bit(Point_Distance, HEIGHT):
485 verts = []
486 faces = []
488 POINT_RADIUS = Point_Distance * 0.5
489 OUTTER_RADIUS = POINT_RADIUS * 1.05
491 POINT_1_Y = POINT_RADIUS * 0.816592592592593
492 POINT_2_X = POINT_RADIUS * 0.511111111111111
493 POINT_2_Y = POINT_RADIUS * 0.885274074074074
494 POINT_3_X = POINT_RADIUS * 0.7072
495 POINT_3_Y = POINT_RADIUS * 0.408296296296296
496 POINT_4_X = POINT_RADIUS * 1.02222222222222
497 SMALL_RADIUS = POINT_RADIUS * 0.183407407407407
498 BIG_RADIUS = POINT_RADIUS * 0.333333333333333
499 # Values for T40 # POINT_1_Y = 2.756
500 # POINT_2_X = 1.725
501 # POINT_2_Y = 2.9878
502 # POINT_3_X = 2.3868
503 # POINT_3_Y = 1.378
504 # POINT_4_X = 3.45
506 # SMALL_RADIUS = 0.619
507 # BIG_RADIUS = 1.125
509 def Do_Curve(Curve_Height):
510 for i in range(0, 90, 10):
511 x = sin(radians(i)) * SMALL_RADIUS
512 y = cos(radians(i)) * SMALL_RADIUS
513 verts.append([x, POINT_1_Y + y, Curve_Height])
515 for i in range(260, 150, -10):
516 x = sin(radians(i)) * BIG_RADIUS
517 y = cos(radians(i)) * BIG_RADIUS
518 verts.append([POINT_2_X + x, POINT_2_Y + y, Curve_Height])
520 for i in range(340, 150 + 360, 10):
521 x = sin(radians(i%360)) * SMALL_RADIUS
522 y = cos(radians(i%360)) * SMALL_RADIUS
523 verts.append([POINT_3_X + x, POINT_3_Y + y, Curve_Height])
525 for i in range(320, 260, -10):
526 x = sin(radians(i)) * BIG_RADIUS
527 y = cos(radians(i)) * BIG_RADIUS
528 verts.append([POINT_4_X + x, y, Curve_Height])
530 FaceStart_Outside = len(verts)
532 for i in range(0, 100, 10):
533 x = sin(radians(i)) * OUTTER_RADIUS
534 y = cos(radians(i)) * OUTTER_RADIUS
535 verts.append([x, y, 0])
537 FaceStart_Top_Curve= len(verts)
538 Do_Curve(0)
539 faces.extend(Torx_Fill(FaceStart_Outside, 0))
541 FaceStart_Bottom_Curve= len(verts)
542 Do_Curve(0 - HEIGHT)
544 faces.extend(Build_Face_List_Quads(FaceStart_Top_Curve,42 ,1 , True))
546 verts.append([0,0,0 - HEIGHT]) # add center point for fill Fan
547 faces.extend(Fill_Fan_Face(FaceStart_Bottom_Curve, 44))
549 M_Verts, M_Faces = Mirror_Verts_Faces(verts, faces, 'x')
550 verts.extend(M_Verts)
551 faces.extend(M_Faces)
553 M_Verts, M_Faces = Mirror_Verts_Faces(verts, faces, 'y')
554 verts.extend(M_Verts)
555 faces.extend(M_Faces)
557 return verts, faces, OUTTER_RADIUS * 2.0
559 # ####################################################################
560 # Create Phillips Bit
561 # ####################################################################
563 def Phillips_Fill(OFFSET, FLIP=0):
564 faces = []
565 Lookup = [[0, 1, 10],
566 [1, 11, 10],
567 [1, 2, 11],
568 [2, 12, 11],
570 [2, 3, 12],
571 [3, 4, 12],
572 [4, 5, 12],
573 [5, 6, 12],
574 [6, 7, 12],
576 [7, 13, 12],
577 [7, 8, 13],
578 [8, 14, 13],
579 [8, 9, 14],
581 [10, 11, 16, 15],
582 [11, 12, 16],
583 [12, 13, 16],
584 [13, 14, 17, 16],
585 [15, 16, 17, 18]
587 for i in Lookup:
588 if FLIP:
589 if len(i) == 3:
590 faces.append([OFFSET + i[2], OFFSET + i[1], OFFSET + i[0]])
591 else:
592 faces.append([OFFSET + i[3], OFFSET + i[2], OFFSET + i[1], OFFSET + i[0]])
593 else:
594 if len(i) == 3:
595 faces.append([OFFSET + i[0], OFFSET + i[1], OFFSET + i[2]])
596 else:
597 faces.append([OFFSET + i[0], OFFSET + i[1], OFFSET + i[2], OFFSET + i[3]])
598 return faces
601 def Create_Phillips_Bit(FLAT_DIA, FLAT_WIDTH, HEIGHT):
602 verts = []
603 faces = []
605 DIV_COUNT = 36
606 FLAT_RADIUS = FLAT_DIA * 0.5
607 OUTTER_RADIUS = FLAT_RADIUS * 1.05
609 Flat_Half = float(FLAT_WIDTH) / 2.0
611 FaceStart_Outside = len(verts)
612 Deg_Step = 360.0 / float(DIV_COUNT)
613 for i in range(int(DIV_COUNT / 4) + 1): # only do half and mirror later
614 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
615 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
616 verts.append([x, y, 0])
618 # FaceStart_Inside = len(verts) # UNUSED
619 verts.append([0, FLAT_RADIUS, 0]) # 10
620 verts.append([Flat_Half, FLAT_RADIUS, 0]) # 11
621 verts.append([Flat_Half, Flat_Half, 0]) # 12
622 verts.append([FLAT_RADIUS, Flat_Half, 0]) # 13
623 verts.append([FLAT_RADIUS, 0, 0]) # 14
625 verts.append([0, Flat_Half, 0 - HEIGHT]) # 15
626 verts.append([Flat_Half, Flat_Half, 0 - HEIGHT]) # 16
627 verts.append([Flat_Half, 0, 0 - HEIGHT]) # 17
629 verts.append([0, 0, 0 - HEIGHT]) # 18
631 faces.extend(Phillips_Fill(FaceStart_Outside, True))
633 Spin_Verts, Spin_Face = SpinDup(verts, faces, 360, 4, 'z')
635 return Spin_Verts, Spin_Face, OUTTER_RADIUS * 2
638 # ####################################################################
639 # Create Head Types
640 # ####################################################################
642 def Max_Pan_Bit_Dia(HEAD_DIA):
643 HEAD_RADIUS = HEAD_DIA * 0.5
644 XRad = HEAD_RADIUS * 1.976
645 return (sin(radians(10)) * XRad) * 2.0
648 def Create_Pan_Head(HOLE_DIA, HEAD_DIA, SHANK_DIA, HEIGHT, RAD1, RAD2, FACE_OFFSET, DIV_COUNT):
650 HOLE_RADIUS = HOLE_DIA * 0.5
651 HEAD_RADIUS = HEAD_DIA * 0.5
652 SHANK_RADIUS = SHANK_DIA * 0.5
654 verts = []
655 faces = []
656 Row = 0
658 XRad = HEAD_RADIUS * 1.976
659 ZRad = HEAD_RADIUS * 1.768
660 EndRad = HEAD_RADIUS * 0.284
661 EndZOffset = HEAD_RADIUS * 0.432
662 HEIGHT = HEAD_RADIUS * 0.59
665 Dome_Rad = 5.6
666 RAD_Offset = 4.9
667 OtherRad = 0.8
668 OtherRad_X_Offset = 4.2
669 OtherRad_Z_Offset = 2.52
670 XRad = 9.88
671 ZRad = 8.84
672 EndRad = 1.42
673 EndZOffset = 2.16
674 HEIGHT = 2.95
676 FaceStart = FACE_OFFSET
678 z = cos(radians(10)) * ZRad
679 verts.append([HOLE_RADIUS, 0.0, (0.0 - ZRad) + z])
680 Start_Height = 0 - ((0.0 - ZRad) + z)
681 Row += 1
683 # for i in range(0,30,10): was 0 to 30 more work needed to make this look good.
684 for i in range(10, 30, 10):
685 x = sin(radians(i)) * XRad
686 z = cos(radians(i)) * ZRad
687 verts.append([x, 0.0, (0.0 - ZRad) + z])
688 Row += 1
690 for i in range(20, 140, 10):
691 x = sin(radians(i)) * EndRad
692 z = cos(radians(i)) * EndRad
693 if ((0.0 - EndZOffset) + z) < (0.0 - HEIGHT):
694 verts.append([(HEAD_RADIUS - EndRad) + x, 0.0, 0.0 - HEIGHT])
695 else:
696 verts.append([(HEAD_RADIUS - EndRad) + x, 0.0, (0.0 - EndZOffset) + z])
697 Row += 1
699 verts.append([SHANK_RADIUS, 0.0, (0.0 - HEIGHT)])
700 Row += 1
702 verts.append([SHANK_RADIUS, 0.0, (0.0 - HEIGHT) - Start_Height])
703 Row += 1
705 sVerts, sFaces = SpinDup(verts, faces, 360, DIV_COUNT, 'z')
706 sVerts.extend(verts) # add the start verts to the Spin verts to complete the loop
708 faces.extend(Build_Face_List_Quads(FaceStart, Row - 1, DIV_COUNT))
710 # Global_Head_Height = HEIGHT # UNUSED
712 return Move_Verts_Up_Z(sVerts, Start_Height), faces, HEIGHT
715 def Create_Dome_Head(HOLE_DIA, HEAD_DIA, SHANK_DIA, HEIGHT, RAD1, RAD2, FACE_OFFSET, DIV_COUNT):
716 HOLE_RADIUS = HOLE_DIA * 0.5
717 HEAD_RADIUS = HEAD_DIA * 0.5
718 SHANK_RADIUS = SHANK_DIA * 0.5
720 verts = []
721 faces = []
722 Row = 0
723 # Dome_Rad = HEAD_RADIUS * (1.0/1.75)
725 Dome_Rad = HEAD_RADIUS * 1.12
726 # Head_Height = HEAD_RADIUS * 0.78
727 RAD_Offset = HEAD_RADIUS * 0.98
728 Dome_Height = HEAD_RADIUS * 0.64
729 OtherRad = HEAD_RADIUS * 0.16
730 OtherRad_X_Offset = HEAD_RADIUS * 0.84
731 OtherRad_Z_Offset = HEAD_RADIUS * 0.504
734 Dome_Rad = 5.6
735 RAD_Offset = 4.9
736 Dome_Height = 3.2
737 OtherRad = 0.8
738 OtherRad_X_Offset = 4.2
739 OtherRad_Z_Offset = 2.52
742 FaceStart = FACE_OFFSET
744 verts.append([HOLE_RADIUS, 0.0, 0.0])
745 Row += 1
747 for i in range(0, 60, 10):
748 x = sin(radians(i)) * Dome_Rad
749 z = cos(radians(i)) * Dome_Rad
750 if ((0.0 - RAD_Offset) + z) <= 0:
751 verts.append([x, 0.0, (0.0 - RAD_Offset) + z])
752 Row += 1
754 for i in range(60, 160, 10):
755 x = sin(radians(i)) * OtherRad
756 z = cos(radians(i)) * OtherRad
757 z = (0.0 - OtherRad_Z_Offset) + z
758 if z < (0.0 - Dome_Height):
759 z = (0.0 - Dome_Height)
760 verts.append([OtherRad_X_Offset + x, 0.0, z])
761 Row += 1
763 verts.append([SHANK_RADIUS, 0.0, (0.0 - Dome_Height)])
764 Row += 1
766 sVerts, sFaces = SpinDup(verts, faces, 360, DIV_COUNT, 'z')
767 sVerts.extend(verts) # add the start verts to the Spin verts to complete the loop
769 faces.extend(Build_Face_List_Quads(FaceStart, Row - 1, DIV_COUNT))
771 return sVerts, faces, Dome_Height
774 def Create_CounterSink_Head(HOLE_DIA, HEAD_DIA, SHANK_DIA, HEIGHT, RAD1, DIV_COUNT):
776 HOLE_RADIUS = HOLE_DIA * 0.5
777 HEAD_RADIUS = HEAD_DIA * 0.5
778 SHANK_RADIUS = SHANK_DIA * 0.5
780 verts = []
781 faces = []
782 Row = 0
784 # HEAD_RADIUS = (HEIGHT/tan(radians(60))) + SHANK_RADIUS
785 HEIGHT = tan(radians(60)) * (HEAD_RADIUS - SHANK_RADIUS)
787 FaceStart = len(verts)
789 verts.append([HOLE_RADIUS, 0.0, 0.0])
790 Row += 1
792 # rad
793 for i in range(0, 100, 10):
794 x = sin(radians(i)) * RAD1
795 z = cos(radians(i)) * RAD1
796 verts.append([(HEAD_RADIUS - RAD1) + x, 0.0, (0.0 - RAD1) + z])
797 Row += 1
799 verts.append([SHANK_RADIUS, 0.0, 0.0 - HEIGHT])
800 Row += 1
802 sVerts, sFaces = SpinDup(verts, faces, 360, DIV_COUNT, 'z')
803 sVerts.extend(verts) # add the start verts to the Spin verts to complete the loop
805 faces.extend(Build_Face_List_Quads(FaceStart, Row - 1, DIV_COUNT))
807 return sVerts, faces, HEIGHT
810 def Create_Cap_Head(HOLE_DIA, HEAD_DIA, SHANK_DIA, HEIGHT, RAD1, RAD2, DIV_COUNT):
812 HOLE_RADIUS = HOLE_DIA * 0.5
813 HEAD_RADIUS = HEAD_DIA * 0.5
814 SHANK_RADIUS = SHANK_DIA * 0.5
816 verts = []
817 faces = []
818 Row = 0
819 BEVEL = HEIGHT * 0.01
821 FaceStart = len(verts)
823 verts.append([HOLE_RADIUS, 0.0, 0.0])
824 Row += 1
826 # rad
827 for i in range(0, 100, 10):
828 x = sin(radians(i)) * RAD1
829 z = cos(radians(i)) * RAD1
830 verts.append([(HEAD_RADIUS - RAD1) + x, 0.0, (0.0 - RAD1) + z])
831 Row += 1
833 verts.append([HEAD_RADIUS, 0.0, 0.0 - HEIGHT + BEVEL])
834 Row += 1
836 verts.append([HEAD_RADIUS - BEVEL, 0.0, 0.0 - HEIGHT])
837 Row += 1
839 # rad2
840 for i in range(0, 100, 10):
841 x = sin(radians(i)) * RAD2
842 z = cos(radians(i)) * RAD2
843 verts.append([(SHANK_RADIUS + RAD2) - x, 0.0, (0.0 - HEIGHT - RAD2) + z])
844 Row += 1
846 sVerts, sFaces = SpinDup(verts, faces, 360, DIV_COUNT, 'z')
847 sVerts.extend(verts) # add the start verts to the Spin verts to complete the loop
849 faces.extend(Build_Face_List_Quads(FaceStart, Row - 1, DIV_COUNT))
851 return sVerts, faces, HEIGHT + RAD2
854 def Create_Hex_Head(FLAT, HOLE_DIA, SHANK_DIA, HEIGHT):
856 verts = []
857 faces = []
858 HOLE_RADIUS = HOLE_DIA * 0.5
859 Half_Flat = FLAT / 2
860 TopBevelRadius = Half_Flat - (Half_Flat * (0.05 / 8))
861 Undercut_Height = (Half_Flat * (0.05 / 8))
862 Shank_Bevel = (Half_Flat * (0.05 / 8))
863 Flat_Height = HEIGHT - Undercut_Height - Shank_Bevel
864 # Undercut_Height = 5
865 SHANK_RADIUS = SHANK_DIA / 2
866 Row = 0
868 verts.append([0.0, 0.0, 0.0])
870 FaceStart = len(verts)
872 # inner hole
873 x = sin(radians(0)) * HOLE_RADIUS
874 y = cos(radians(0)) * HOLE_RADIUS
875 verts.append([x, y, 0.0])
877 x = sin(radians(60 / 6)) * HOLE_RADIUS
878 y = cos(radians(60 / 6)) * HOLE_RADIUS
879 verts.append([x, y, 0.0])
881 x = sin(radians(60 / 3)) * HOLE_RADIUS
882 y = cos(radians(60 / 3)) * HOLE_RADIUS
883 verts.append([x, y, 0.0])
885 x = sin(radians(60 / 2)) * HOLE_RADIUS
886 y = cos(radians(60 / 2)) * HOLE_RADIUS
887 verts.append([x, y, 0.0])
888 Row += 1
890 # bevel
891 x = sin(radians(0)) * TopBevelRadius
892 y = cos(radians(0)) * TopBevelRadius
893 vec1 = Vector([x, y, 0.0])
894 verts.append([x, y, 0.0])
896 x = sin(radians(60 / 6)) * TopBevelRadius
897 y = cos(radians(60 / 6)) * TopBevelRadius
898 vec2 = Vector([x, y, 0.0])
899 verts.append([x, y, 0.0])
901 x = sin(radians(60 / 3)) * TopBevelRadius
902 y = cos(radians(60 / 3)) * TopBevelRadius
903 vec3 = Vector([x, y, 0.0])
904 verts.append([x, y, 0.0])
906 x = sin(radians(60 / 2)) * TopBevelRadius
907 y = cos(radians(60 / 2)) * TopBevelRadius
908 vec4 = Vector([x, y, 0.0])
909 verts.append([x, y, 0.0])
910 Row += 1
912 # Flats
913 x = tan(radians(0)) * Half_Flat
914 dvec = vec1 - Vector([x, Half_Flat, 0.0])
915 verts.append([x, Half_Flat, -dvec.length])
917 x = tan(radians(60 / 6)) * Half_Flat
918 dvec = vec2 - Vector([x, Half_Flat, 0.0])
919 verts.append([x, Half_Flat, -dvec.length])
921 x = tan(radians(60 / 3)) * Half_Flat
922 dvec = vec3 - Vector([x, Half_Flat, 0.0])
923 Lowest_Point = -dvec.length
924 verts.append([x, Half_Flat, -dvec.length])
926 x = tan(radians(60 / 2)) * Half_Flat
927 dvec = vec4 - Vector([x, Half_Flat, 0.0])
928 Lowest_Point = -dvec.length
929 verts.append([x, Half_Flat, -dvec.length])
930 Row += 1
932 # down Bits Tri
933 x = tan(radians(0)) * Half_Flat
934 verts.append([x, Half_Flat, Lowest_Point])
936 x = tan(radians(60 / 6)) * Half_Flat
937 verts.append([x, Half_Flat, Lowest_Point])
939 x = tan(radians(60 / 3)) * Half_Flat
940 verts.append([x, Half_Flat, Lowest_Point])
942 x = tan(radians(60 / 2)) * Half_Flat
943 verts.append([x, Half_Flat, Lowest_Point])
944 Row += 1
946 # down Bits
948 x = tan(radians(0)) * Half_Flat
949 verts.append([x, Half_Flat, -Flat_Height])
951 x = tan(radians(60 / 6)) * Half_Flat
952 verts.append([x, Half_Flat, -Flat_Height])
954 x = tan(radians(60 / 3)) * Half_Flat
955 verts.append([x, Half_Flat, -Flat_Height])
957 x = tan(radians(60 / 2)) * Half_Flat
958 verts.append([x, Half_Flat, -Flat_Height])
959 Row += 1
961 # Under cut
962 x = sin(radians(0)) * Half_Flat
963 y = cos(radians(0)) * Half_Flat
964 vec1 = Vector([x, y, 0.0])
965 verts.append([x, y, -Flat_Height])
967 x = sin(radians(60 / 6)) * Half_Flat
968 y = cos(radians(60 / 6)) * Half_Flat
969 vec2 = Vector([x, y, 0.0])
970 verts.append([x, y, -Flat_Height])
972 x = sin(radians(60 / 3)) * Half_Flat
973 y = cos(radians(60 / 3)) * Half_Flat
974 vec3 = Vector([x, y, 0.0])
975 verts.append([x, y, -Flat_Height])
977 x = sin(radians(60 / 2)) * Half_Flat
978 y = cos(radians(60 / 2)) * Half_Flat
979 vec3 = Vector([x, y, 0.0])
980 verts.append([x, y, -Flat_Height])
981 Row += 1
983 # Under cut down bit
984 x = sin(radians(0)) * Half_Flat
985 y = cos(radians(0)) * Half_Flat
986 vec1 = Vector([x, y, 0.0])
987 verts.append([x, y, -Flat_Height - Undercut_Height])
989 x = sin(radians(60 / 6)) * Half_Flat
990 y = cos(radians(60 / 6)) * Half_Flat
991 vec2 = Vector([x, y, 0.0])
992 verts.append([x, y, -Flat_Height - Undercut_Height])
994 x = sin(radians(60 / 3)) * Half_Flat
995 y = cos(radians(60 / 3)) * Half_Flat
996 vec3 = Vector([x, y, 0.0])
997 verts.append([x, y, -Flat_Height - Undercut_Height])
999 x = sin(radians(60 / 2)) * Half_Flat
1000 y = cos(radians(60 / 2)) * Half_Flat
1001 vec3 = Vector([x, y, 0.0])
1002 verts.append([x, y, -Flat_Height - Undercut_Height])
1003 Row += 1
1005 # Under cut to Shank BEVEL
1006 x = sin(radians(0)) * (SHANK_RADIUS + Shank_Bevel)
1007 y = cos(radians(0)) * (SHANK_RADIUS + Shank_Bevel)
1008 vec1 = Vector([x, y, 0.0])
1009 verts.append([x, y, -Flat_Height - Undercut_Height])
1011 x = sin(radians(60 / 6)) * (SHANK_RADIUS + Shank_Bevel)
1012 y = cos(radians(60 / 6)) * (SHANK_RADIUS + Shank_Bevel)
1013 vec2 = Vector([x, y, 0.0])
1014 verts.append([x, y, -Flat_Height - Undercut_Height])
1016 x = sin(radians(60 / 3)) * (SHANK_RADIUS + Shank_Bevel)
1017 y = cos(radians(60 / 3)) * (SHANK_RADIUS + Shank_Bevel)
1018 vec3 = Vector([x, y, 0.0])
1019 verts.append([x, y, -Flat_Height - Undercut_Height])
1021 x = sin(radians(60 / 2)) * (SHANK_RADIUS + Shank_Bevel)
1022 y = cos(radians(60 / 2)) * (SHANK_RADIUS + Shank_Bevel)
1023 vec3 = Vector([x, y, 0.0])
1024 verts.append([x, y, -Flat_Height - Undercut_Height])
1025 Row += 1
1027 # Under cut to Shank BEVEL
1028 x = sin(radians(0)) * SHANK_RADIUS
1029 y = cos(radians(0)) * SHANK_RADIUS
1030 vec1 = Vector([x, y, 0.0])
1031 verts.append([x, y, -Flat_Height - Undercut_Height - Shank_Bevel])
1033 x = sin(radians(60 / 6)) * SHANK_RADIUS
1034 y = cos(radians(60 / 6)) * SHANK_RADIUS
1035 vec2 = Vector([x, y, 0.0])
1036 verts.append([x, y, -Flat_Height - Undercut_Height - Shank_Bevel])
1038 x = sin(radians(60 / 3)) * SHANK_RADIUS
1039 y = cos(radians(60 / 3)) * SHANK_RADIUS
1040 vec3 = Vector([x, y, 0.0])
1041 verts.append([x, y, -Flat_Height - Undercut_Height - Shank_Bevel])
1043 x = sin(radians(60 / 2)) * SHANK_RADIUS
1044 y = cos(radians(60 / 2)) * SHANK_RADIUS
1045 vec3 = Vector([x, y, 0.0])
1046 verts.append([x, y, -Flat_Height - Undercut_Height - Shank_Bevel])
1047 Row += 1
1049 faces.extend(Build_Face_List_Quads(FaceStart, 3, Row - 1))
1051 Mirror_Verts, Mirror_Faces = Mirror_Verts_Faces(verts, faces, 'y')
1052 verts.extend(Mirror_Verts)
1053 faces.extend(Mirror_Faces)
1055 Spin_Verts, Spin_Faces = SpinDup(verts, faces, 360, 6, 'z')
1057 return Spin_Verts, Spin_Faces, 0 - (-HEIGHT)
1061 def Create_12_Point(FLAT, HOLE_DIA, SHANK_DIA, HEIGHT,FLANGE_DIA):
1062 FLANGE_HEIGHT = (1.89/8.0)*HEIGHT
1063 FLAT_HEIGHT = (4.18/8.0)*HEIGHT
1064 # FLANGE_DIA = (13.27/8.0)*FLAT
1066 FLANGE_RADIUS = FLANGE_DIA * 0.5
1067 FLANGE_TAPPER_HEIGHT = HEIGHT - FLANGE_HEIGHT - FLAT_HEIGHT
1069 # HOLE_DIA = 0.0
1071 verts = []
1072 faces = []
1073 HOLE_RADIUS = HOLE_DIA / 2
1074 Half_Flat = FLAT / 2
1075 TopBevelRadius = Half_Flat - (Half_Flat * (0.05 / 8))
1076 # Undercut_Height = (Half_Flat * (0.05 / 8))
1077 # Shank_Bevel = (Half_Flat * (0.05 / 8))
1078 # Flat_Height = HEIGHT - Undercut_Height - Shank_Bevel
1079 # Undercut_Height = 5
1080 SHANK_RADIUS = SHANK_DIA / 2
1081 Row = 0
1083 verts.append([0.0, 0.0, 0.0])
1085 # print("HOLE_RADIUS" + str(HOLE_RADIUS))
1086 # print("TopBevelRadius" + str(TopBevelRadius))
1088 FaceStart = len(verts)
1090 # inner hole
1091 x = sin(radians(0)) * HOLE_RADIUS
1092 y = cos(radians(0)) * HOLE_RADIUS
1093 verts.append([x, y, 0.0])
1095 x = sin(radians(5)) * HOLE_RADIUS
1096 y = cos(radians(5)) * HOLE_RADIUS
1097 verts.append([x, y, 0.0])
1099 x = sin(radians(10)) * HOLE_RADIUS
1100 y = cos(radians(10)) * HOLE_RADIUS
1101 verts.append([x, y, 0.0])
1103 x = sin(radians(15)) * HOLE_RADIUS
1104 y = cos(radians(15)) * HOLE_RADIUS
1105 verts.append([x, y, 0.0])
1107 x = sin(radians(20)) * HOLE_RADIUS
1108 y = cos(radians(20)) * HOLE_RADIUS
1109 verts.append([x, y, 0.0])
1111 x = sin(radians(25)) * HOLE_RADIUS
1112 y = cos(radians(25)) * HOLE_RADIUS
1113 verts.append([x, y, 0.0])
1115 x = sin(radians(30)) * HOLE_RADIUS
1116 y = cos(radians(30)) * HOLE_RADIUS
1117 verts.append([x, y, 0.0])
1119 Row += 1
1123 # bevel
1124 x = sin(radians(0)) * TopBevelRadius
1125 y = cos(radians(0)) * TopBevelRadius
1126 vec1 = Vector([x, y, 0.0])
1127 verts.append([x, y, 0.0])
1129 x = sin(radians(5)) * TopBevelRadius
1130 y = cos(radians(5)) * TopBevelRadius
1131 vec2 = Vector([x, y, 0.0])
1132 verts.append([x, y, 0.0])
1134 x = sin(radians(10)) * TopBevelRadius
1135 y = cos(radians(10)) * TopBevelRadius
1136 vec3 = Vector([x, y, 0.0])
1137 verts.append([x, y, 0.0])
1139 x = sin(radians(15)) * TopBevelRadius
1140 y = cos(radians(15)) * TopBevelRadius
1141 vec4 = Vector([x, y, 0.0])
1142 verts.append([x, y, 0.0])
1144 x = sin(radians(20)) * TopBevelRadius
1145 y = cos(radians(20)) * TopBevelRadius
1146 vec5 = Vector([x, y, 0.0])
1147 verts.append([x, y, 0.0])
1149 x = sin(radians(25)) * TopBevelRadius
1150 y = cos(radians(25)) * TopBevelRadius
1151 vec6 = Vector([x, y, 0.0])
1152 verts.append([x, y, 0.0])
1154 x = sin(radians(30)) * TopBevelRadius
1155 y = cos(radians(30)) * TopBevelRadius
1156 vec7 = Vector([x, y, 0.0])
1157 verts.append([x, y, 0.0])
1159 Row += 1
1162 #45Deg bevel on the top
1164 #First we work out how far up the Y axis the vert is
1165 v_origin = Vector([0.0,0.0,0.0]) # center of the model
1166 v_15Deg_Point = Vector([tan(radians(15)) * Half_Flat,Half_Flat,0.0]) #Is a know point to work back from
1168 x = tan(radians(0)) * Half_Flat
1169 Point_Distance =(tan(radians(30)) * v_15Deg_Point.x)+Half_Flat
1170 dvec = vec1 - Vector([x, Point_Distance, 0.0])
1171 verts.append([x, Point_Distance, -dvec.length])
1172 v_0_Deg_Top_Point = Vector([x, Point_Distance, -dvec.length])
1174 v_0_Deg_Point = Vector([x, Point_Distance,0.0])
1176 v_5Deg_Line = Vector([tan(radians(5)) * Half_Flat, Half_Flat, 0.0])
1177 v_5Deg_Line.length *= 2 # extende out the line on a 5 deg angle
1179 #We cross 2 lines. One from the origin to the 0 Deg point
1180 #and the second is from the origin extended out past the first line
1181 # This gives the cross point of the
1182 v_Cross = geometry.intersect_line_line_2d(v_0_Deg_Point,v_15Deg_Point,v_origin,v_5Deg_Line)
1183 dvec = vec2 - Vector([v_Cross.x,v_Cross.y,0.0])
1184 verts.append([v_Cross.x,v_Cross.y,-dvec.length])
1185 v_5_Deg_Top_Point = Vector([v_Cross.x,v_Cross.y,-dvec.length])
1187 v_10Deg_Line = Vector([tan(radians(10)) * Half_Flat, Half_Flat, 0.0])
1188 v_10Deg_Line.length *= 2 # extende out the line
1190 v_Cross = geometry.intersect_line_line_2d(v_0_Deg_Point,v_15Deg_Point,v_origin,v_10Deg_Line)
1191 dvec = vec3 - Vector([v_Cross.x,v_Cross.y,0.0])
1192 verts.append([v_Cross.x,v_Cross.y,-dvec.length])
1193 v_10_Deg_Top_Point = Vector([v_Cross.x,v_Cross.y,-dvec.length])
1195 #The remain points are stright forward because y is all the same y height (Half_Flat)
1196 x = tan(radians(15)) * Half_Flat
1197 dvec = vec4 - Vector([x, Half_Flat, 0.0])
1198 Lowest_Point = -dvec.length
1199 verts.append([x, Half_Flat, -dvec.length])
1200 v_15_Deg_Top_Point = Vector([x, Half_Flat, -dvec.length])
1202 x = tan(radians(20)) * Half_Flat
1203 dvec = vec5 - Vector([x, Half_Flat, 0.0])
1204 Lowest_Point = -dvec.length
1205 verts.append([x, Half_Flat, -dvec.length])
1206 v_20_Deg_Top_Point = Vector([x, Half_Flat, -dvec.length])
1208 x = tan(radians(25)) * Half_Flat
1209 dvec = vec6 - Vector([x, Half_Flat, 0.0])
1210 Lowest_Point = -dvec.length
1211 verts.append([x, Half_Flat, -dvec.length])
1212 v_25_Deg_Top_Point = Vector([x, Half_Flat, -dvec.length])
1214 x = tan(radians(30)) * Half_Flat
1215 dvec = vec7 - Vector([x, Half_Flat, 0.0])
1216 Lowest_Point = -dvec.length
1217 verts.append([x, Half_Flat, -dvec.length])
1218 v_30_Deg_Top_Point = Vector([x, Half_Flat, -dvec.length])
1219 Row += 1
1222 #Down Bits
1223 # print ("Point_Distance")
1224 # print (Point_Distance)
1228 Flange_Adjacent = FLANGE_RADIUS - Point_Distance
1229 if (Flange_Adjacent == 0.0):
1230 Flange_Adjacent = 0.000001
1231 Flange_Opposite = FLANGE_TAPPER_HEIGHT
1233 # print ("Flange_Opposite")
1234 # print (Flange_Opposite)
1235 # print ("Flange_Adjacent")
1236 # print (Flange_Adjacent)
1238 FLANGE_ANGLE_RAD = atan(Flange_Opposite/Flange_Adjacent )
1239 # FLANGE_ANGLE_RAD = radians(45)
1240 # print("FLANGE_ANGLE_RAD")
1241 # print (degrees (FLANGE_ANGLE_RAD))
1244 v_Extended_Flange_Edge = Vector([0.0,0.0,-HEIGHT + FLANGE_HEIGHT + (tan(FLANGE_ANGLE_RAD)* FLANGE_RADIUS) ])
1245 # print("v_Extended_Flange_Edge")
1246 # print (v_Extended_Flange_Edge)
1248 #0deg
1249 v_Flange_Edge = Vector([sin(radians(0)) * FLANGE_RADIUS,cos(radians(0)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT ])
1250 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)
1251 verts.append(v_Cross[0])
1253 #5deg
1254 v_Flange_Edge = Vector([sin(radians(5)) * FLANGE_RADIUS,cos(radians(5)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT ])
1255 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)
1256 verts.append(v_Cross[0])
1258 #10deg
1259 v_Flange_Edge = Vector([sin(radians(10)) * FLANGE_RADIUS,cos(radians(10)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT ])
1260 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)
1261 verts.append(v_Cross[0])
1263 #15deg
1264 v_Flange_Edge = Vector([sin(radians(15)) * FLANGE_RADIUS,cos(radians(15)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT ])
1265 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)
1266 verts.append(v_Cross[0])
1269 #20deg
1270 v_Flange_Edge = Vector([sin(radians(20)) * FLANGE_RADIUS,cos(radians(20)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT ])
1271 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)
1272 verts.append(v_Cross[0])
1274 #25deg
1275 v_Flange_Edge = Vector([sin(radians(25)) * FLANGE_RADIUS,cos(radians(25)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT ])
1276 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)
1277 verts.append(v_Cross[0])
1280 #30deg
1281 v_Flange_Edge = Vector([sin(radians(30)) * FLANGE_RADIUS,cos(radians(30)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT ])
1282 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)
1283 verts.append(v_Cross[0])
1285 Row += 1
1289 verts.append([sin(radians(0)) * FLANGE_RADIUS,cos(radians(0)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT ])
1290 verts.append([sin(radians(5)) * FLANGE_RADIUS,cos(radians(5)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT])
1291 verts.append([sin(radians(10)) * FLANGE_RADIUS,cos(radians(10)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT])
1292 verts.append([sin(radians(15)) * FLANGE_RADIUS,cos(radians(15)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT])
1293 verts.append([sin(radians(20)) * FLANGE_RADIUS,cos(radians(20)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT])
1294 verts.append([sin(radians(25)) * FLANGE_RADIUS,cos(radians(25)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT])
1295 verts.append([sin(radians(30)) * FLANGE_RADIUS,cos(radians(30)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT])
1297 Row += 1
1299 verts.append([sin(radians(0)) * FLANGE_RADIUS,cos(radians(0)) * FLANGE_RADIUS,-HEIGHT])
1300 verts.append([sin(radians(5)) * FLANGE_RADIUS,cos(radians(5)) * FLANGE_RADIUS,-HEIGHT])
1301 verts.append([sin(radians(10)) * FLANGE_RADIUS,cos(radians(10)) * FLANGE_RADIUS,-HEIGHT])
1302 verts.append([sin(radians(15)) * FLANGE_RADIUS,cos(radians(15)) * FLANGE_RADIUS,-HEIGHT])
1303 verts.append([sin(radians(20)) * FLANGE_RADIUS,cos(radians(20)) * FLANGE_RADIUS,-HEIGHT])
1304 verts.append([sin(radians(25)) * FLANGE_RADIUS,cos(radians(25)) * FLANGE_RADIUS,-HEIGHT])
1305 verts.append([sin(radians(30)) * FLANGE_RADIUS,cos(radians(30)) * FLANGE_RADIUS,-HEIGHT])
1307 Row += 1
1310 verts.append([sin(radians(0)) * SHANK_RADIUS,cos(radians(0)) * SHANK_RADIUS,-HEIGHT])
1311 verts.append([sin(radians(0)) * SHANK_RADIUS,cos(radians(0)) * SHANK_RADIUS,-HEIGHT])
1312 verts.append([sin(radians(10)) * SHANK_RADIUS,cos(radians(10)) * SHANK_RADIUS,-HEIGHT])
1313 verts.append([sin(radians(10)) * SHANK_RADIUS,cos(radians(10)) * SHANK_RADIUS,-HEIGHT])
1314 verts.append([sin(radians(20)) * SHANK_RADIUS,cos(radians(20)) * SHANK_RADIUS,-HEIGHT])
1315 verts.append([sin(radians(20)) * SHANK_RADIUS,cos(radians(20)) * SHANK_RADIUS,-HEIGHT])
1316 verts.append([sin(radians(30)) * SHANK_RADIUS,cos(radians(30)) * SHANK_RADIUS,-HEIGHT])
1318 Row += 1
1321 faces.extend(Build_Face_List_Quads(FaceStart, 6, Row - 1))
1323 Spin_Verts, Spin_Faces = SpinDup(verts, faces, 360,12, 'z')
1325 return Spin_Verts, Spin_Faces, 0 - (-HEIGHT)
1328 def Create_12_Point_Head(FLAT, HOLE_DIA, SHANK_DIA, HEIGHT,FLANGE_DIA):
1329 #TODO add under head radius
1330 return Create_12_Point(FLAT, HOLE_DIA, SHANK_DIA, HEIGHT,FLANGE_DIA)
1334 # ####################################################################
1335 # Create External Thread
1336 # ####################################################################
1339 def Thread_Start3(verts, INNER_RADIUS, OUTTER_RADIUS, PITCH, DIV_COUNT,
1340 CREST_PERCENT, ROOT_PERCENT, Height_Offset):
1342 Ret_Row = 0
1344 Height_Start = Height_Offset - PITCH
1345 Height_Step = float(PITCH) / float(DIV_COUNT)
1346 Deg_Step = 360.0 / float(DIV_COUNT)
1348 Crest_Height = float(PITCH) * float(CREST_PERCENT) / float(100)
1349 Root_Height = float(PITCH) * float(ROOT_PERCENT) / float(100)
1350 Root_to_Crest_Height = Crest_to_Root_Height = \
1351 (float(PITCH) - (Crest_Height + Root_Height)) / 2.0
1353 # thread start
1354 Rank = float(OUTTER_RADIUS - INNER_RADIUS) / float(DIV_COUNT)
1355 for j in range(4):
1357 for i in range(DIV_COUNT + 1):
1358 z = Height_Offset - (Height_Step * i)
1359 if z > Height_Start:
1360 z = Height_Start
1361 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
1362 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
1363 verts.append([x, y, z])
1364 Height_Offset -= Crest_Height
1365 Ret_Row += 1
1367 for i in range(DIV_COUNT + 1):
1368 z = Height_Offset - (Height_Step * i)
1369 if z > Height_Start:
1370 z = Height_Start
1372 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
1373 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
1374 verts.append([x, y, z])
1375 Height_Offset -= Crest_to_Root_Height
1376 Ret_Row += 1
1378 for i in range(DIV_COUNT + 1):
1379 z = Height_Offset - (Height_Step * i)
1380 if z > Height_Start:
1381 z = Height_Start
1383 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
1384 y = cos(radians(i * Deg_Step)) * INNER_RADIUS
1385 if j == 0:
1386 x = sin(radians(i * Deg_Step)) * (OUTTER_RADIUS - (i * Rank))
1387 y = cos(radians(i * Deg_Step)) * (OUTTER_RADIUS - (i * Rank))
1388 verts.append([x, y, z])
1389 Height_Offset -= Root_Height
1390 Ret_Row += 1
1392 for i in range(DIV_COUNT + 1):
1393 z = Height_Offset - (Height_Step * i)
1394 if z > Height_Start:
1395 z = Height_Start
1397 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
1398 y = cos(radians(i * Deg_Step)) * INNER_RADIUS
1400 if j == 0:
1401 x = sin(radians(i * Deg_Step)) * (OUTTER_RADIUS - (i * Rank))
1402 y = cos(radians(i * Deg_Step)) * (OUTTER_RADIUS - (i * Rank))
1403 verts.append([x, y, z])
1404 Height_Offset -= Root_to_Crest_Height
1405 Ret_Row += 1
1407 return Ret_Row, Height_Offset
1410 def Create_Shank_Verts(START_DIA, OUTTER_DIA, LENGTH, Z_LOCATION, DIV_COUNT):
1412 verts = []
1414 START_RADIUS = START_DIA / 2
1415 OUTTER_RADIUS = OUTTER_DIA / 2
1417 Opp = abs(START_RADIUS - OUTTER_RADIUS)
1418 Taper_Lentgh = Opp / tan(radians(31))
1420 if Taper_Lentgh > LENGTH:
1421 Taper_Lentgh = 0
1423 Stright_Length = LENGTH - Taper_Lentgh
1425 Deg_Step = 360.0 / float(DIV_COUNT)
1427 Row = 0
1429 Lowest_Z_Vert = 0
1431 Height_Offset = Z_LOCATION
1433 # Ring
1434 for i in range(DIV_COUNT + 1):
1435 x = sin(radians(i * Deg_Step)) * START_RADIUS
1436 y = cos(radians(i * Deg_Step)) * START_RADIUS
1437 z = Height_Offset - 0
1438 verts.append([x, y, z])
1439 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1440 Height_Offset -= Stright_Length
1441 Row += 1
1443 for i in range(DIV_COUNT + 1):
1444 x = sin(radians(i * Deg_Step)) * START_RADIUS
1445 y = cos(radians(i * Deg_Step)) * START_RADIUS
1446 z = Height_Offset - 0
1447 verts.append([x, y, z])
1448 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1449 Height_Offset -= Taper_Lentgh
1450 Row += 1
1452 return verts, Row, Height_Offset
1455 def Create_Thread_Start_Verts(INNER_DIA, OUTTER_DIA, PITCH, CREST_PERCENT,
1456 ROOT_PERCENT, Z_LOCATION, DIV_COUNT):
1458 verts = []
1460 INNER_RADIUS = INNER_DIA / 2
1461 OUTTER_RADIUS = OUTTER_DIA / 2
1463 Deg_Step = 360.0 / float(DIV_COUNT)
1464 Height_Step = float(PITCH) / float(DIV_COUNT)
1466 Row = 0
1468 Lowest_Z_Vert = 0
1470 Height_Offset = Z_LOCATION
1472 Height_Start = Height_Offset
1474 Crest_Height = float(PITCH) * float(CREST_PERCENT) / float(100)
1475 Root_Height = float(PITCH) * float(ROOT_PERCENT) / float(100)
1476 Root_to_Crest_Height = Crest_to_Root_Height = \
1477 (float(PITCH) - (Crest_Height + Root_Height)) / 2.0
1479 Rank = float(OUTTER_RADIUS - INNER_RADIUS) / float(DIV_COUNT)
1481 Height_Offset = Z_LOCATION + PITCH
1482 Cut_off = Z_LOCATION
1484 for j in range(1):
1486 for i in range(DIV_COUNT + 1):
1487 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
1488 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
1489 z = Height_Offset - (Height_Step * i)
1490 if z > Cut_off:
1491 z = Cut_off
1492 verts.append([x, y, z])
1493 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1494 Height_Offset -= Crest_Height
1495 Row += 1
1497 for i in range(DIV_COUNT + 1):
1498 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
1499 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
1500 z = Height_Offset - (Height_Step * i)
1501 if z > Cut_off:
1502 z = Cut_off
1503 verts.append([x, y, z])
1504 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1505 Height_Offset -= Crest_to_Root_Height
1506 Row += 1
1508 for i in range(DIV_COUNT + 1):
1509 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
1510 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
1511 z = Height_Offset - (Height_Step * i)
1512 if z > Cut_off:
1513 z = Cut_off
1514 verts.append([x, y, z])
1515 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1516 Height_Offset -= Root_Height
1517 Row += 1
1519 for i in range(DIV_COUNT + 1):
1520 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
1521 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
1522 z = Height_Offset - (Height_Step * i)
1523 if z > Cut_off:
1524 z = Cut_off
1525 verts.append([x, y, z])
1526 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1527 Height_Offset -= Root_to_Crest_Height
1528 Row += 1
1530 for j in range(2):
1531 for i in range(DIV_COUNT + 1):
1532 z = Height_Offset - (Height_Step * i)
1533 if z > Height_Start:
1534 z = Height_Start
1535 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
1536 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
1537 verts.append([x, y, z])
1538 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1539 Height_Offset -= Crest_Height
1540 Row += 1
1542 for i in range(DIV_COUNT + 1):
1543 z = Height_Offset - (Height_Step * i)
1544 if z > Height_Start:
1545 z = Height_Start
1547 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
1548 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
1549 verts.append([x, y, z])
1550 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1551 Height_Offset -= Crest_to_Root_Height
1552 Row += 1
1554 for i in range(DIV_COUNT + 1):
1555 z = Height_Offset - (Height_Step * i)
1556 if z > Height_Start:
1557 z = Height_Start
1559 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
1560 y = cos(radians(i * Deg_Step)) * INNER_RADIUS
1561 if j == 0:
1562 x = sin(radians(i * Deg_Step)) * (OUTTER_RADIUS - (i * Rank))
1563 y = cos(radians(i * Deg_Step)) * (OUTTER_RADIUS - (i * Rank))
1564 verts.append([x, y, z])
1565 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1566 Height_Offset -= Root_Height
1567 Row += 1
1569 for i in range(DIV_COUNT + 1):
1570 z = Height_Offset - (Height_Step * i)
1571 if z > Height_Start:
1572 z = Height_Start
1574 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
1575 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_to_Crest_Height
1583 Row += 1
1585 return verts, Row, Height_Offset
1588 def Create_Thread_Verts(INNER_DIA, OUTTER_DIA, PITCH, HEIGHT,
1589 CREST_PERCENT, ROOT_PERCENT, Z_LOCATION, DIV_COUNT):
1591 verts = []
1593 INNER_RADIUS = INNER_DIA / 2
1594 OUTTER_RADIUS = OUTTER_DIA / 2
1596 Deg_Step = 360.0 / float(DIV_COUNT)
1597 Height_Step = float(PITCH) / float(DIV_COUNT)
1599 NUM_OF_START_THREADS = 4.0
1600 NUM_OF_END_THREADS = 3.0
1601 Num = int((HEIGHT - ((NUM_OF_START_THREADS * PITCH) + (NUM_OF_END_THREADS * PITCH))) / PITCH)
1602 Row = 0
1604 Crest_Height = float(PITCH) * float(CREST_PERCENT) / float(100)
1605 Root_Height = float(PITCH) * float(ROOT_PERCENT) / float(100)
1606 Root_to_Crest_Height = Crest_to_Root_Height = \
1607 (float(PITCH) - (Crest_Height + Root_Height)) / 2.0
1609 Height_Offset = Z_LOCATION
1611 Lowest_Z_Vert = 0
1613 for j in range(Num):
1615 for i in range(DIV_COUNT + 1):
1616 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
1617 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
1618 z = Height_Offset - (Height_Step * i)
1619 verts.append([x, y, z])
1620 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1621 Height_Offset -= Crest_Height
1622 Row += 1
1624 for i in range(DIV_COUNT + 1):
1625 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
1626 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
1627 z = Height_Offset - (Height_Step * i)
1628 verts.append([x, y, z])
1629 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1630 Height_Offset -= Crest_to_Root_Height
1631 Row += 1
1633 for i in range(DIV_COUNT + 1):
1634 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
1635 y = cos(radians(i * Deg_Step)) * INNER_RADIUS
1636 z = Height_Offset - (Height_Step * i)
1637 verts.append([x, y, z])
1638 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1639 Height_Offset -= Root_Height
1640 Row += 1
1642 for i in range(DIV_COUNT + 1):
1643 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
1644 y = cos(radians(i * Deg_Step)) * INNER_RADIUS
1645 z = Height_Offset - (Height_Step * i)
1646 verts.append([x, y, z])
1647 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1648 Height_Offset -= Root_to_Crest_Height
1649 Row += 1
1651 return verts, Row, Height_Offset
1654 def Create_Thread_End_Verts(INNER_DIA, OUTTER_DIA, PITCH, CREST_PERCENT,
1655 ROOT_PERCENT, Z_LOCATION, DIV_COUNT):
1656 verts = []
1658 INNER_RADIUS = INNER_DIA / 2
1659 OUTTER_RADIUS = OUTTER_DIA / 2
1661 Deg_Step = 360.0 / float(DIV_COUNT)
1662 Height_Step = float(PITCH) / float(DIV_COUNT)
1664 Crest_Height = float(PITCH) * float(CREST_PERCENT) / float(100)
1665 Root_Height = float(PITCH) * float(ROOT_PERCENT) / float(100)
1666 Root_to_Crest_Height = Crest_to_Root_Height = \
1667 (float(PITCH) - (Crest_Height + Root_Height)) / 2.0
1669 Row = 0
1671 Height_Offset = Z_LOCATION
1672 Tapper_Height_Start = Height_Offset - PITCH - PITCH
1673 Max_Height = Tapper_Height_Start - PITCH
1674 Lowest_Z_Vert = 0
1676 for j in range(4):
1678 for i in range(DIV_COUNT + 1):
1679 z = Height_Offset - (Height_Step * i)
1680 z = max(z, Max_Height)
1681 Tapper_Radius = OUTTER_RADIUS
1682 if z < Tapper_Height_Start:
1683 Tapper_Radius = OUTTER_RADIUS - (Tapper_Height_Start - z)
1685 x = sin(radians(i * Deg_Step)) * (Tapper_Radius)
1686 y = cos(radians(i * Deg_Step)) * (Tapper_Radius)
1687 verts.append([x, y, z])
1688 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1689 Height_Offset -= Crest_Height
1690 Row += 1
1692 for i in range(DIV_COUNT + 1):
1693 z = Height_Offset - (Height_Step * i)
1694 z = max(z, Max_Height)
1695 Tapper_Radius = OUTTER_RADIUS
1696 if z < Tapper_Height_Start:
1697 Tapper_Radius = OUTTER_RADIUS - (Tapper_Height_Start - z)
1699 x = sin(radians(i * Deg_Step)) * (Tapper_Radius)
1700 y = cos(radians(i * Deg_Step)) * (Tapper_Radius)
1701 verts.append([x, y, z])
1702 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1703 Height_Offset -= Crest_to_Root_Height
1704 Row += 1
1706 for i in range(DIV_COUNT + 1):
1707 z = Height_Offset - (Height_Step * i)
1708 z = max(z, Max_Height)
1709 Tapper_Radius = OUTTER_RADIUS - (Tapper_Height_Start - z)
1710 if Tapper_Radius > INNER_RADIUS:
1711 Tapper_Radius = INNER_RADIUS
1713 x = sin(radians(i * Deg_Step)) * (Tapper_Radius)
1714 y = cos(radians(i * Deg_Step)) * (Tapper_Radius)
1715 verts.append([x, y, z])
1716 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1717 Height_Offset -= Root_Height
1718 Row += 1
1720 for i in range(DIV_COUNT + 1):
1721 z = Height_Offset - (Height_Step * i)
1722 z = max(z, Max_Height)
1723 Tapper_Radius = OUTTER_RADIUS - (Tapper_Height_Start - z)
1724 if Tapper_Radius > INNER_RADIUS:
1725 Tapper_Radius = INNER_RADIUS
1727 x = sin(radians(i * Deg_Step)) * (Tapper_Radius)
1728 y = cos(radians(i * Deg_Step)) * (Tapper_Radius)
1729 verts.append([x, y, z])
1730 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1731 Height_Offset -= Root_to_Crest_Height
1732 Row += 1
1734 return verts, Row, Height_Offset, Lowest_Z_Vert
1737 def Create_External_Thread(SHANK_DIA, SHANK_LENGTH, INNER_DIA, OUTTER_DIA,
1738 PITCH, LENGTH, CREST_PERCENT, ROOT_PERCENT, DIV_COUNT):
1740 verts = []
1741 faces = []
1743 Total_Row = 0
1744 # Thread_Len = 0 # UNUSED
1746 Face_Start = len(verts)
1747 Offset = 0.0
1749 Shank_Verts, Shank_Row, Offset = Create_Shank_Verts(
1750 SHANK_DIA, OUTTER_DIA, SHANK_LENGTH,
1751 Offset, DIV_COUNT
1753 Total_Row += Shank_Row
1755 Thread_Start_Verts, Thread_Start_Row, Offset = Create_Thread_Start_Verts(
1756 INNER_DIA, OUTTER_DIA, PITCH, CREST_PERCENT,
1757 ROOT_PERCENT, Offset, DIV_COUNT
1759 Total_Row += Thread_Start_Row
1761 Thread_Verts, Thread_Row, Offset = Create_Thread_Verts(
1762 INNER_DIA, OUTTER_DIA, PITCH, LENGTH,
1763 CREST_PERCENT, ROOT_PERCENT, Offset, DIV_COUNT
1765 Total_Row += Thread_Row
1767 Thread_End_Verts, Thread_End_Row, Offset, Lowest_Z_Vert = Create_Thread_End_Verts(
1768 INNER_DIA, OUTTER_DIA, PITCH, CREST_PERCENT,
1769 ROOT_PERCENT, Offset, DIV_COUNT
1771 Total_Row += Thread_End_Row
1773 verts.extend(Shank_Verts)
1774 verts.extend(Thread_Start_Verts)
1775 verts.extend(Thread_Verts)
1776 verts.extend(Thread_End_Verts)
1778 faces.extend(Build_Face_List_Quads(Face_Start, DIV_COUNT, Total_Row - 1, 0))
1779 faces.extend(Fill_Ring_Face(len(verts) - DIV_COUNT, DIV_COUNT, 1))
1781 return verts, faces, 0.0 - Lowest_Z_Vert
1784 # ####################################################################
1785 # Create Nut
1786 # ####################################################################
1788 def add_Hex_Nut(FLAT, HOLE_DIA, HEIGHT):
1789 global Global_Head_Height
1790 global Global_NutRad
1792 verts = []
1793 faces = []
1794 HOLE_RADIUS = HOLE_DIA * 0.5
1795 Half_Flat = FLAT / 2
1796 Half_Height = HEIGHT / 2
1797 TopBevelRadius = Half_Flat - 0.05
1799 Global_NutRad = TopBevelRadius
1801 Row = 0
1802 Lowest_Z_Vert = 0.0
1804 verts.append([0.0, 0.0, 0.0])
1806 FaceStart = len(verts)
1807 # inner hole
1809 x = sin(radians(0)) * HOLE_RADIUS
1810 y = cos(radians(0)) * HOLE_RADIUS
1811 # print ("rad 0 x;", x, "y:" ,y )
1812 verts.append([x, y, 0.0])
1814 x = sin(radians(60 / 6)) * HOLE_RADIUS
1815 y = cos(radians(60 / 6)) * HOLE_RADIUS
1816 # print ("rad 60/6x;", x, "y:" ,y )
1817 verts.append([x, y, 0.0])
1819 x = sin(radians(60 / 3)) * HOLE_RADIUS
1820 y = cos(radians(60 / 3)) * HOLE_RADIUS
1821 # print ("rad 60/3x;", x, "y:" ,y )
1822 verts.append([x, y, 0.0])
1824 x = sin(radians(60 / 2)) * HOLE_RADIUS
1825 y = cos(radians(60 / 2)) * HOLE_RADIUS
1826 # print ("rad 60/2x;", x, "y:" ,y )
1827 verts.append([x, y, 0.0])
1828 Row += 1
1830 # Bevel
1832 x = sin(radians(0)) * TopBevelRadius
1833 y = cos(radians(0)) * TopBevelRadius
1834 vec1 = Vector([x, y, 0.0])
1835 verts.append([x, y, 0.0])
1837 x = sin(radians(60 / 6)) * TopBevelRadius
1838 y = cos(radians(60 / 6)) * TopBevelRadius
1839 vec2 = Vector([x, y, 0.0])
1840 verts.append([x, y, 0.0])
1842 x = sin(radians(60 / 3)) * TopBevelRadius
1843 y = cos(radians(60 / 3)) * TopBevelRadius
1844 vec3 = Vector([x, y, 0.0])
1845 verts.append([x, y, 0.0])
1847 x = sin(radians(60 / 2)) * TopBevelRadius
1848 y = cos(radians(60 / 2)) * TopBevelRadius
1849 vec4 = Vector([x, y, 0.0])
1850 verts.append([x, y, 0.0])
1851 Row += 1
1853 # Flats
1854 x = tan(radians(0)) * Half_Flat
1855 dvec = vec1 - Vector([x, Half_Flat, 0.0])
1856 verts.append([x, Half_Flat, -dvec.length])
1857 Lowest_Z_Vert = min(Lowest_Z_Vert, -dvec.length)
1859 x = tan(radians(60 / 6)) * Half_Flat
1860 dvec = vec2 - Vector([x, Half_Flat, 0.0])
1861 verts.append([x, Half_Flat, -dvec.length])
1862 Lowest_Z_Vert = min(Lowest_Z_Vert, -dvec.length)
1864 x = tan(radians(60 / 3)) * Half_Flat
1865 dvec = vec3 - Vector([x, Half_Flat, 0.0])
1866 Lowest_Point = -dvec.length
1867 verts.append([x, Half_Flat, -dvec.length])
1868 Lowest_Z_Vert = min(Lowest_Z_Vert, -dvec.length)
1870 x = tan(radians(60 / 2)) * Half_Flat
1871 dvec = vec4 - Vector([x, Half_Flat, 0.0])
1872 Lowest_Point = -dvec.length
1873 verts.append([x, Half_Flat, -dvec.length])
1874 Lowest_Z_Vert = min(Lowest_Z_Vert, -dvec.length)
1875 Row += 1
1877 # down Bits Tri
1878 x = tan(radians(0)) * Half_Flat
1879 verts.append([x, Half_Flat, Lowest_Point])
1881 x = tan(radians(60 / 6)) * Half_Flat
1882 verts.append([x, Half_Flat, Lowest_Point])
1883 x = tan(radians(60 / 3)) * Half_Flat
1884 verts.append([x, Half_Flat, Lowest_Point])
1886 x = tan(radians(60 / 2)) * Half_Flat
1887 verts.append([x, Half_Flat, Lowest_Point])
1888 Lowest_Z_Vert = min(Lowest_Z_Vert, Lowest_Point)
1889 Row += 1
1891 # down Bits
1893 x = tan(radians(0)) * Half_Flat
1894 verts.append([x, Half_Flat, -Half_Height])
1896 x = tan(radians(60 / 6)) * Half_Flat
1897 verts.append([x, Half_Flat, -Half_Height])
1899 x = tan(radians(60 / 3)) * Half_Flat
1900 verts.append([x, Half_Flat, -Half_Height])
1902 x = tan(radians(60 / 2)) * Half_Flat
1903 verts.append([x, Half_Flat, -Half_Height])
1904 Lowest_Z_Vert = min(Lowest_Z_Vert, -Half_Height)
1905 Row += 1
1907 faces.extend(Build_Face_List_Quads(FaceStart, 3, Row - 1))
1909 Global_Head_Height = HEIGHT
1911 Tvert, tface = Mirror_Verts_Faces(verts, faces, 'z', Lowest_Z_Vert)
1912 verts.extend(Tvert)
1913 faces.extend(tface)
1915 Tvert, tface = Mirror_Verts_Faces(verts, faces, 'y')
1916 verts.extend(Tvert)
1917 faces.extend(tface)
1919 S_verts, S_faces = SpinDup(verts, faces, 360, 6, 'z')
1921 # return verts, faces, TopBevelRadius
1922 return S_verts, S_faces, TopBevelRadius
1925 def add_Nylon_Head(OUTSIDE_RADIUS, Z_LOCATION, DIV_COUNT):
1926 verts = []
1927 faces = []
1928 Row = 0
1930 INNER_HOLE = OUTSIDE_RADIUS - (OUTSIDE_RADIUS * (1.25 / 4.75))
1931 EDGE_THICKNESS = (OUTSIDE_RADIUS * (0.4 / 4.75))
1932 RAD1 = (OUTSIDE_RADIUS * (0.5 / 4.75))
1933 OVER_ALL_HEIGHT = (OUTSIDE_RADIUS * (2.0 / 4.75))
1935 FaceStart = len(verts)
1937 # Start_Height = 0 - 3 # UNUSED
1938 Height_Offset = Z_LOCATION
1939 Lowest_Z_Vert = 0
1941 x = INNER_HOLE
1942 z = (Height_Offset - OVER_ALL_HEIGHT) + EDGE_THICKNESS
1943 verts.append([x, 0.0, z])
1944 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1945 Row += 1
1947 x = INNER_HOLE
1948 z = (Height_Offset - OVER_ALL_HEIGHT)
1949 verts.append([x, 0.0, z])
1950 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1951 Row += 1
1953 for i in range(180, 80, -10):
1954 x = sin(radians(i)) * RAD1
1955 z = cos(radians(i)) * RAD1
1956 verts.append([(OUTSIDE_RADIUS - RAD1) + x, 0.0, ((Height_Offset - OVER_ALL_HEIGHT) + RAD1) + z])
1957 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1958 Row += 1
1960 x = OUTSIDE_RADIUS - 0
1961 z = Height_Offset
1962 verts.append([x, 0.0, z])
1963 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1964 Row += 1
1966 sVerts, sFaces = SpinDup(verts, faces, 360, DIV_COUNT, 'z')
1967 sVerts.extend(verts) # add the start verts to the Spin verts to complete the loop
1969 faces.extend(Build_Face_List_Quads(FaceStart, Row - 1, DIV_COUNT,1))
1971 return Move_Verts_Up_Z(sVerts, 0), faces, Lowest_Z_Vert
1974 def add_Nylon_Part(OUTSIDE_RADIUS, Z_LOCATION, DIV_COUNT):
1975 verts = []
1976 faces = []
1977 Row = 0
1979 INNER_HOLE = OUTSIDE_RADIUS - (OUTSIDE_RADIUS * (1.5 / 4.75))
1980 EDGE_THICKNESS = (OUTSIDE_RADIUS * (0.4 / 4.75))
1981 OVER_ALL_HEIGHT = (OUTSIDE_RADIUS * (2.0 / 4.75))
1982 PART_THICKNESS = OVER_ALL_HEIGHT - EDGE_THICKNESS
1983 PART_INNER_HOLE = (OUTSIDE_RADIUS * (2.5 / 4.75))
1985 FaceStart = len(verts)
1987 Height_Offset = Z_LOCATION
1988 Lowest_Z_Vert = 0
1990 x = INNER_HOLE + EDGE_THICKNESS
1991 z = Height_Offset
1992 verts.append([x, 0.0, z])
1993 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1994 Row += 1
1996 x = PART_INNER_HOLE
1997 z = Height_Offset
1998 verts.append([x, 0.0, z])
1999 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
2000 Row += 1
2002 x = PART_INNER_HOLE
2003 z = Height_Offset - PART_THICKNESS
2004 verts.append([x, 0.0, z])
2005 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
2006 Row += 1
2008 x = INNER_HOLE + EDGE_THICKNESS
2009 z = Height_Offset - PART_THICKNESS
2010 verts.append([x, 0.0, z])
2011 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
2012 Row += 1
2014 sVerts, sFaces = SpinDup(verts, faces, 360, DIV_COUNT, 'z')
2015 sVerts.extend(verts) # add the start verts to the Spin verts to complete the loop
2017 faces.extend(Build_Face_List_Quads(FaceStart, Row - 1, DIV_COUNT, 1))
2019 return sVerts, faces, 0 - Lowest_Z_Vert
2022 def add_12_Point_Nut(FLAT, HOLE_DIA, HEIGHT,FLANGE_DIA):
2023 return Create_12_Point(FLAT, HOLE_DIA,HOLE_DIA, HEIGHT,FLANGE_DIA)
2027 # ####################################################################
2028 # Create Internal Thread
2029 # ####################################################################
2031 def Create_Internal_Thread_Start_Verts(verts, INNER_RADIUS, OUTTER_RADIUS, PITCH, DIV,
2032 CREST_PERCENT, ROOT_PERCENT, Height_Offset):
2034 Ret_Row = 0
2035 # Move the offset up so that the verts start at
2036 # at the correct place (Height_Start)
2037 Height_Offset = Height_Offset + PITCH
2039 Height_Start = Height_Offset - PITCH
2040 Height_Step = float(PITCH) / float(DIV)
2041 Deg_Step = 360.0 / float(DIV)
2043 Crest_Height = float(PITCH) * float(CREST_PERCENT) / float(100)
2044 Root_Height = float(PITCH) * float(ROOT_PERCENT) / float(100)
2045 Root_to_Crest_Height = Crest_to_Root_Height = \
2046 (float(PITCH) - (Crest_Height + Root_Height)) / 2.0
2048 Rank = float(OUTTER_RADIUS - INNER_RADIUS) / float(DIV)
2050 for i in range(DIV + 1):
2051 z = Height_Offset - (Height_Step * i)
2052 if z > Height_Start:
2053 z = Height_Start
2054 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
2055 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
2057 verts.append([x, y, z])
2058 Height_Offset -= Crest_Height
2059 Ret_Row += 1
2061 for i in range(DIV + 1):
2062 z = Height_Offset - (Height_Step * i)
2063 if z > Height_Start:
2064 z = Height_Start
2066 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
2067 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
2069 verts.append([x, y, z])
2070 Height_Offset -= Crest_to_Root_Height
2071 Ret_Row += 1
2073 for i in range(DIV + 1):
2074 z = Height_Offset - (Height_Step * i)
2075 if z > Height_Start:
2076 z = Height_Start
2078 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
2079 y = cos(radians(i * Deg_Step)) * INNER_RADIUS
2081 x = sin(radians(i * Deg_Step)) * (OUTTER_RADIUS - (i * Rank))
2082 y = cos(radians(i * Deg_Step)) * (OUTTER_RADIUS - (i * Rank))
2084 verts.append([x, y, z])
2085 Height_Offset -= Root_Height
2086 Ret_Row += 1
2088 for i in range(DIV + 1):
2089 z = Height_Offset - (Height_Step * i)
2090 if z > Height_Start:
2091 z = Height_Start
2093 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
2094 y = cos(radians(i * Deg_Step)) * INNER_RADIUS
2096 x = sin(radians(i * Deg_Step)) * (OUTTER_RADIUS - (i * Rank))
2097 y = cos(radians(i * Deg_Step)) * (OUTTER_RADIUS - (i * Rank))
2099 verts.append([x, y, z])
2100 Height_Offset -= Root_to_Crest_Height
2101 Ret_Row += 1
2103 return Ret_Row, Height_Offset
2106 def Create_Internal_Thread_End_Verts(verts, INNER_RADIUS, OUTTER_RADIUS, PITCH,
2107 CREST_PERCENT, ROOT_PERCENT, Height_Offset,
2108 DIV_COUNT):
2109 Ret_Row = 0
2110 Height_End = Height_Offset - PITCH
2111 Height_Step = float(PITCH) / float(DIV_COUNT)
2112 Deg_Step = 360.0 / float(DIV_COUNT)
2114 Crest_Height = float(PITCH) * float(CREST_PERCENT) / float(100)
2115 Root_Height = float(PITCH) * float(ROOT_PERCENT) / float(100)
2116 Root_to_Crest_Height = Crest_to_Root_Height = \
2117 (float(PITCH) - (Crest_Height + Root_Height)) / 2.0
2119 Rank = float(OUTTER_RADIUS - INNER_RADIUS) / float(DIV_COUNT)
2121 Num = 0
2123 for j in range(2):
2124 for i in range(DIV_COUNT + 1):
2125 z = Height_Offset - (Height_Step * i)
2126 if z < Height_End:
2127 z = Height_End
2128 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
2129 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
2130 verts.append([x, y, z])
2132 Height_Offset -= Crest_Height
2133 Ret_Row += 1
2135 for i in range(DIV_COUNT + 1):
2136 z = Height_Offset - (Height_Step * i)
2137 if z < Height_End:
2138 z = Height_End
2140 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
2141 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
2142 verts.append([x, y, z])
2144 Height_Offset -= Crest_to_Root_Height
2145 Ret_Row += 1
2147 for i in range(DIV_COUNT + 1):
2148 z = Height_Offset - (Height_Step * i)
2149 if z < Height_End:
2150 z = Height_End
2152 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
2153 y = cos(radians(i * Deg_Step)) * INNER_RADIUS
2155 if j == Num:
2156 # Fix T51338 - seems that the placing a small random offset makes the mesh valid
2157 rand_offset = triangular(0.0001, 0.009)
2158 x = sin(radians(i * Deg_Step)) * (INNER_RADIUS + (i * Rank + rand_offset))
2159 y = cos(radians(i * Deg_Step)) * (INNER_RADIUS + (i * Rank + rand_offset))
2161 if j > Num:
2162 x = sin(radians(i * Deg_Step)) * (OUTTER_RADIUS)
2163 y = cos(radians(i * Deg_Step)) * (OUTTER_RADIUS)
2165 verts.append([x, y, z])
2167 Height_Offset -= Root_Height
2168 Ret_Row += 1
2170 for i in range(DIV_COUNT + 1):
2171 z = Height_Offset - (Height_Step * i)
2172 if z < Height_End:
2173 z = Height_End
2175 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
2176 y = cos(radians(i * Deg_Step)) * INNER_RADIUS
2178 if j == Num:
2179 x = sin(radians(i * Deg_Step)) * (INNER_RADIUS + (i * Rank))
2180 y = cos(radians(i * Deg_Step)) * (INNER_RADIUS + (i * Rank))
2181 if j > Num:
2182 x = sin(radians(i * Deg_Step)) * (OUTTER_RADIUS)
2183 y = cos(radians(i * Deg_Step)) * (OUTTER_RADIUS)
2185 verts.append([x, y, z])
2187 Height_Offset -= Root_to_Crest_Height
2188 Ret_Row += 1
2190 return Ret_Row, Height_End # send back Height End as this is the lowest point
2193 def Create_Internal_Thread(INNER_DIA, OUTTER_DIA, PITCH, HEIGHT,
2194 CREST_PERCENT, ROOT_PERCENT, INTERNAL, DIV_COUNT):
2195 verts = []
2196 faces = []
2198 INNER_RADIUS = INNER_DIA / 2
2199 OUTTER_RADIUS = OUTTER_DIA / 2
2201 Deg_Step = 360.0 / float(DIV_COUNT)
2202 Height_Step = float(PITCH) / float(DIV_COUNT)
2204 # less one pitch for the start and end that is 1/2 pitch high
2205 Num = int(round((HEIGHT - PITCH) / PITCH))
2207 Row = 0
2209 Crest_Height = float(PITCH) * float(CREST_PERCENT) / float(100)
2210 Root_Height = float(PITCH) * float(ROOT_PERCENT) / float(100)
2211 Root_to_Crest_Height = Crest_to_Root_Height = \
2212 (float(PITCH) - (Crest_Height + Root_Height)) / 2.0
2214 Height_Offset = 0
2215 FaceStart = len(verts)
2217 Row_Inc, Height_Offset = Create_Internal_Thread_Start_Verts(
2218 verts, INNER_RADIUS, OUTTER_RADIUS, PITCH,
2219 DIV_COUNT, CREST_PERCENT, ROOT_PERCENT,
2220 Height_Offset
2222 Row += Row_Inc
2224 for j in range(Num):
2226 for i in range(DIV_COUNT + 1):
2227 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
2228 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
2229 verts.append([x, y, Height_Offset - (Height_Step * i)])
2230 Height_Offset -= Crest_Height
2231 Row += 1
2233 for i in range(DIV_COUNT + 1):
2234 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
2235 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
2236 verts.append([x, y, Height_Offset - (Height_Step * i)])
2237 Height_Offset -= Crest_to_Root_Height
2238 Row += 1
2240 for i in range(DIV_COUNT + 1):
2241 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
2242 y = cos(radians(i * Deg_Step)) * INNER_RADIUS
2243 verts.append([x, y, Height_Offset - (Height_Step * i)])
2244 Height_Offset -= Root_Height
2245 Row += 1
2247 for i in range(DIV_COUNT + 1):
2248 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
2249 y = cos(radians(i * Deg_Step)) * INNER_RADIUS
2250 verts.append([x, y, Height_Offset - (Height_Step * i)])
2251 Height_Offset -= Root_to_Crest_Height
2252 Row += 1
2254 Row_Inc, Height_Offset = Create_Internal_Thread_End_Verts(
2255 verts, INNER_RADIUS, OUTTER_RADIUS,
2256 PITCH, CREST_PERCENT,
2257 ROOT_PERCENT, Height_Offset, DIV_COUNT
2260 Row += Row_Inc
2261 faces.extend(Build_Face_List_Quads(FaceStart, DIV_COUNT, Row - 1, FLIP=1))
2263 return verts, faces, 0 - Height_Offset
2266 def Nut_Mesh(props, context):
2268 verts = []
2269 faces = []
2270 Head_Verts = []
2271 Head_Faces = []
2274 Face_Start = len(verts)
2277 if props.bf_Nut_Type == 'bf_Nut_12Pnt':
2278 Nut_Height = props.bf_12_Point_Nut_Height
2279 else:
2280 Nut_Height = props.bf_Hex_Nut_Height
2282 Thread_Verts, Thread_Faces, New_Nut_Height = Create_Internal_Thread(
2283 props.bf_Minor_Dia, props.bf_Major_Dia,
2284 props.bf_Pitch, Nut_Height,
2285 props.bf_Crest_Percent, props.bf_Root_Percent,
2286 1, props.bf_Div_Count
2288 verts.extend(Thread_Verts)
2289 faces.extend(Copy_Faces(Thread_Faces, Face_Start))
2291 Face_Start = len(verts)
2293 if props.bf_Nut_Type == 'bf_Nut_12Pnt':
2294 Head_Verts, Head_Faces, Lock_Nut_Rad = add_12_Point_Nut(
2295 props.bf_12_Point_Nut_Flat_Distance,
2296 props.bf_Major_Dia, New_Nut_Height,
2297 #Limit the size of the Flange to avoid calculation error
2298 max(props.bf_12_Point_Nut_Flange_Dia,props.bf_12_Point_Nut_Flat_Distance)
2300 else:
2301 Head_Verts, Head_Faces, Lock_Nut_Rad = add_Hex_Nut(
2302 props.bf_Hex_Nut_Flat_Distance,
2303 props.bf_Major_Dia, New_Nut_Height
2305 verts.extend((Head_Verts))
2306 faces.extend(Copy_Faces(Head_Faces, Face_Start))
2308 LowZ = 0 - New_Nut_Height
2310 if props.bf_Nut_Type == 'bf_Nut_Lock':
2311 Face_Start = len(verts)
2312 Nylon_Head_Verts, Nylon_Head_faces, LowZ = add_Nylon_Head(
2313 Lock_Nut_Rad, 0 - New_Nut_Height,
2314 props.bf_Div_Count
2316 verts.extend((Nylon_Head_Verts))
2317 faces.extend(Copy_Faces(Nylon_Head_faces, Face_Start))
2319 Face_Start = len(verts)
2320 Nylon_Verts, Nylon_faces, Temp_LowZ = add_Nylon_Part(
2321 Lock_Nut_Rad, 0 - New_Nut_Height,
2322 props.bf_Div_Count
2324 verts.extend((Nylon_Verts))
2325 faces.extend(Copy_Faces(Nylon_faces, Face_Start))
2327 return Move_Verts_Up_Z(verts, 0 - LowZ), faces
2330 # ####################################################################
2331 # Create Bolt
2332 # ####################################################################
2334 def Bolt_Mesh(props, context):
2336 verts = []
2337 faces = []
2338 Bit_Verts = []
2339 Bit_Faces = []
2340 Bit_Dia = 0.001
2341 Head_Verts = []
2342 Head_Faces = []
2343 Head_Height = 0.0
2345 ReSized_Allen_Bit_Flat_Distance = props.bf_Allen_Bit_Flat_Distance # set default
2347 Head_Height = props.bf_Hex_Head_Height # will be changed by the Head Functions
2349 if props.bf_Bit_Type == 'bf_Bit_Allen' and props.bf_Head_Type == 'bf_Head_Pan':
2350 # need to size Allen bit if it is too big.
2351 if Allen_Bit_Dia(props.bf_Allen_Bit_Flat_Distance) > Max_Pan_Bit_Dia(props.bf_Pan_Head_Dia):
2352 ReSized_Allen_Bit_Flat_Distance = Allen_Bit_Dia_To_Flat(
2353 Max_Pan_Bit_Dia(props.bf_Pan_Head_Dia)
2355 ReSized_Allen_Bit_Flat_Distance -= ReSized_Allen_Bit_Flat_Distance * 0.05 # It looks better if it is just a bit smaller
2356 # print ("Resized Allen Bit Flat Distance to ",ReSized_Allen_Bit_Flat_Distance)
2358 # Bit Mesh
2359 if props.bf_Bit_Type == 'bf_Bit_Allen':
2360 Bit_Verts, Bit_Faces, Bit_Dia = Create_Allen_Bit(
2361 ReSized_Allen_Bit_Flat_Distance,
2362 props.bf_Allen_Bit_Depth
2365 if props.bf_Bit_Type == 'bf_Bit_Torx':
2366 Bit_Verts, Bit_Faces, Bit_Dia = Create_Torx_Bit(
2367 Torx_Bit_Size_To_Point_Distance(props.bf_Torx_Size_Type),
2368 props.bf_Torx_Bit_Depth
2372 if props.bf_Bit_Type == 'bf_Bit_Philips':
2373 Bit_Verts, Bit_Faces, Bit_Dia = Create_Phillips_Bit(
2374 props.bf_Philips_Bit_Dia,
2375 props.bf_Philips_Bit_Dia * (0.5 / 1.82),
2376 props.bf_Phillips_Bit_Depth
2378 # Head Mesh
2379 if props.bf_Head_Type == 'bf_Head_Hex':
2380 Head_Verts, Head_Faces, Head_Height = Create_Hex_Head(
2381 props.bf_Hex_Head_Flat_Distance, Bit_Dia,
2382 props.bf_Shank_Dia, props.bf_Hex_Head_Height
2385 elif props.bf_Head_Type == 'bf_Head_12Pnt':
2386 Head_Verts, Head_Faces, Head_Height = Create_12_Point_Head(
2387 props.bf_12_Point_Head_Flat_Distance, Bit_Dia,
2388 props.bf_Shank_Dia, props.bf_12_Point_Head_Height,
2389 #Limit the size of the Flange to avoid calculation error
2390 max(props.bf_12_Point_Head_Flange_Dia,props.bf_12_Point_Head_Flat_Distance)
2392 elif props.bf_Head_Type == 'bf_Head_Cap':
2393 Head_Verts, Head_Faces, Head_Height = Create_Cap_Head(
2394 Bit_Dia, props.bf_Cap_Head_Dia,
2395 props.bf_Shank_Dia, props.bf_Cap_Head_Height,
2396 props.bf_Cap_Head_Dia * (1.0 / 19.0),
2397 props.bf_Cap_Head_Dia * (1.0 / 19.0),
2398 props.bf_Div_Count
2400 elif props.bf_Head_Type == 'bf_Head_Dome':
2401 Head_Verts, Head_Faces, Head_Height = Create_Dome_Head(
2402 Bit_Dia, props.bf_Dome_Head_Dia,
2403 props.bf_Shank_Dia, props.bf_Hex_Head_Height,
2404 1, 1, 0, props.bf_Div_Count
2407 elif props.bf_Head_Type == 'bf_Head_Pan':
2408 Head_Verts, Head_Faces, Head_Height = Create_Pan_Head(
2409 Bit_Dia, props.bf_Pan_Head_Dia,
2410 props.bf_Shank_Dia,
2411 props.bf_Hex_Head_Height, 1, 1, 0,
2412 props.bf_Div_Count
2414 elif props.bf_Head_Type == 'bf_Head_CounterSink':
2415 Head_Verts, Head_Faces, Head_Height = Create_CounterSink_Head(
2416 Bit_Dia, props.bf_CounterSink_Head_Dia,
2417 props.bf_Shank_Dia, props.bf_CounterSink_Head_Dia,
2418 props.bf_CounterSink_Head_Dia * (0.09 / 6.31),
2419 props.bf_Div_Count
2422 Face_Start = len(verts)
2423 verts.extend(Move_Verts_Up_Z(Bit_Verts, Head_Height))
2424 faces.extend(Copy_Faces(Bit_Faces, Face_Start))
2426 Face_Start = len(verts)
2427 verts.extend(Move_Verts_Up_Z(Head_Verts, Head_Height))
2428 faces.extend(Copy_Faces(Head_Faces, Face_Start))
2430 Face_Start = len(verts)
2431 Thread_Verts, Thread_Faces, Thread_Height = Create_External_Thread(
2432 props.bf_Shank_Dia, props.bf_Shank_Length,
2433 props.bf_Minor_Dia, props.bf_Major_Dia,
2434 props.bf_Pitch, props.bf_Thread_Length,
2435 props.bf_Crest_Percent,
2436 props.bf_Root_Percent, props.bf_Div_Count
2439 verts.extend(Move_Verts_Up_Z(Thread_Verts, 0))
2440 faces.extend(Copy_Faces(Thread_Faces, Face_Start))
2442 return Move_Verts_Up_Z(verts, Thread_Height), faces
2451 def Create_New_Mesh(props, context):
2453 verts = []
2454 faces = []
2455 edges = []
2456 sObjName = ''
2458 if props.bf_Model_Type == 'bf_Model_Bolt':
2459 # print('Create Bolt')
2460 verts, faces = Bolt_Mesh(props, context)
2461 sObjName = 'Bolt'
2463 if props.bf_Model_Type == 'bf_Model_Nut':
2464 # print('Create Nut')
2465 verts, faces = Nut_Mesh(props, context)
2466 sObjName = 'Nut'
2468 verts, faces = RemoveDoubles(verts, faces)
2470 verts = Scale_Mesh_Verts(verts, GLOBAL_SCALE)
2472 mesh = bpy.data.meshes.new(name=sObjName)
2473 mesh.from_pydata(verts, edges, faces)
2475 # useful for development when the mesh may be invalid.
2476 # Fix T51338 : Validate the mesh (the internal thread generator for the Nut
2477 # should be more reliable now, however there could be other possible errors)
2478 is_not_mesh_valid = mesh.validate()
2480 if is_not_mesh_valid:
2481 props.report({'INFO'}, "Mesh is not Valid, correcting")
2483 return mesh