Fix #105067: Node Wrangler: cannot preview multi-user material group
[blender-addons.git] / add_mesh_BoltFactory / createMesh.py
blob8ef9b87659299639791050639163ae547f4eefec
1 # SPDX-FileCopyrightText: 2010-2022 Blender Foundation
3 # SPDX-License-Identifier: GPL-2.0-or-later
5 import bpy
6 from mathutils import (
7 Matrix,
8 Vector,
9 geometry,
11 from math import (
12 sin, cos,
13 tan, radians,atan,degrees
15 from random import triangular
16 from bpy_extras.object_utils import AddObjectHelper, object_data_add
18 NARROW_UI = 180
19 MAX_INPUT_NUMBER = 50
21 GLOBAL_SCALE = 1 # 1 blender unit = X mm
24 # next two utility functions are stolen from import_obj.py
26 def unpack_list(list_of_tuples):
27 l = []
28 for t in list_of_tuples:
29 l.extend(t)
30 return l
33 def unpack_face_list(list_of_tuples):
34 l = []
35 for t in list_of_tuples:
36 face = [i for i in t]
38 if len(face) != 3 and len(face) != 4:
39 raise RuntimeError("{0} vertices in face".format(len(face)))
41 # rotate indices if the 4th is 0
42 if len(face) == 4 and face[3] == 0:
43 face = [face[3], face[0], face[1], face[2]]
45 if len(face) == 3:
46 face.append(0)
48 l.extend(face)
50 return l
53 """
54 Remove Doubles takes a list on Verts and a list of Faces and
55 removes the doubles, much like Blender does in edit mode.
56 It doesn't have the range function but it will round the coordinates
57 and remove verts that are very close together. The function
58 is useful because you can perform a "Remove Doubles" with out
59 having to enter Edit Mode. Having to enter edit mode has the
60 disadvantage of not being able to interactively change the properties.
61 """
64 def RemoveDoubles(verts, faces, Decimal_Places=4):
66 new_verts = []
67 new_faces = []
68 dict_verts = {}
69 Rounded_Verts = []
71 for v in verts:
72 Rounded_Verts.append([round(v[0], Decimal_Places),
73 round(v[1], Decimal_Places),
74 round(v[2], Decimal_Places)])
76 for face in faces:
77 new_face = []
78 for vert_index in face:
79 Real_co = tuple(verts[vert_index])
80 Rounded_co = tuple(Rounded_Verts[vert_index])
82 if Rounded_co not in dict_verts:
83 dict_verts[Rounded_co] = len(dict_verts)
84 new_verts.append(Real_co)
85 if dict_verts[Rounded_co] not in new_face:
86 new_face.append(dict_verts[Rounded_co])
87 if len(new_face) == 3 or len(new_face) == 4:
88 new_faces.append(new_face)
90 return new_verts, new_faces
93 def Scale_Mesh_Verts(verts, scale_factor):
94 Ret_verts = []
95 for v in verts:
96 Ret_verts.append([v[0] * scale_factor, v[1] * scale_factor, v[2] * scale_factor])
97 return Ret_verts
100 # Create a matrix representing a rotation.
102 # Parameters:
104 # * angle (float) - The angle of rotation desired.
105 # * matSize (int) - The size of the rotation matrix to construct. Can be 2d, 3d, or 4d.
106 # * axisFlag (string (optional)) - Possible values:
107 # o "x - x-axis rotation"
108 # o "y - y-axis rotation"
109 # o "z - z-axis rotation"
110 # o "r - arbitrary rotation around vector"
111 # * axis (Vector object. (optional)) - The arbitrary axis of rotation used with "R"
113 # Returns: Matrix object.
114 # A new rotation matrix.
116 def Simple_RotationMatrix(angle, matSize, axisFlag):
117 if matSize != 4:
118 print("Simple_RotationMatrix can only do 4x4")
120 q = radians(angle) # make the rotation go clockwise
122 if axisFlag == 'x':
123 matrix = Matrix.Rotation(q, 4, 'X')
124 elif axisFlag == 'y':
125 matrix = Matrix.Rotation(q, 4, 'Y')
126 elif axisFlag == 'z':
127 matrix = Matrix.Rotation(q, 4, 'Z')
128 else:
129 print("Simple_RotationMatrix can only do x y z axis")
130 return matrix
133 # ####################################################################
134 # Converter Functions For Bolt Factory
135 # ####################################################################
137 def Flat_To_Radius(FLAT):
138 h = (float(FLAT) / 2) / cos(radians(30))
139 return h
142 def Get_Phillips_Bit_Height(Bit_Dia):
143 Flat_Width_half = (Bit_Dia * (0.5 / 1.82)) / 2.0
144 Bit_Rad = Bit_Dia / 2.0
145 x = Bit_Rad - Flat_Width_half
146 y = tan(radians(60)) * x
147 return float(y)
150 # ####################################################################
151 # Miscellaneous Utilities
152 # ####################################################################
154 # Returns a list of verts rotated by the given matrix. Used by SpinDup
155 def Rot_Mesh(verts, matrix):
156 from mathutils import Vector
157 return [(matrix @ Vector(v))[:] for v in verts]
160 # Returns a list of faces that has there index incremented by offset
161 def Copy_Faces(faces, offset):
162 return [[(i + offset) for i in f] for f in faces]
165 # Much like Blenders built in SpinDup
166 def SpinDup(VERTS, FACES, DEGREE, DIVISIONS, AXIS):
167 verts = []
168 faces = []
170 if DIVISIONS == 0:
171 DIVISIONS = 1
173 step = DEGREE / DIVISIONS # set step so pieces * step = degrees in arc
175 for i in range(int(DIVISIONS)):
176 rotmat = Simple_RotationMatrix(step * i, 4, AXIS) # 4x4 rotation matrix, 30d about the x axis.
177 Rot = Rot_Mesh(VERTS, rotmat)
178 faces.extend(Copy_Faces(FACES, len(verts)))
179 verts.extend(Rot)
180 return verts, faces
183 # Returns a list of verts that have been moved up the z axis by DISTANCE
184 def Move_Verts_Up_Z(VERTS, DISTANCE):
185 ret = []
186 for v in VERTS:
187 ret.append([v[0], v[1], v[2] + DISTANCE])
188 return ret
191 # Returns a list of verts and faces that has been mirrored in the AXIS
192 def Mirror_Verts_Faces(VERTS, FACES, AXIS, FLIP_POINT=0):
193 ret_vert = []
194 ret_face = []
195 offset = len(VERTS)
196 if AXIS == 'y':
197 for v in VERTS:
198 Delta = v[0] - FLIP_POINT
199 ret_vert.append([FLIP_POINT - Delta, v[1], v[2]])
200 if AXIS == 'x':
201 for v in VERTS:
202 Delta = v[1] - FLIP_POINT
203 ret_vert.append([v[0], FLIP_POINT - Delta, v[2]])
204 if AXIS == 'z':
205 for v in VERTS:
206 Delta = v[2] - FLIP_POINT
207 ret_vert.append([v[0], v[1], FLIP_POINT - Delta])
209 for f in FACES:
210 fsub = []
211 for i in range(len(f)):
212 fsub.append(f[i] + offset)
213 fsub.reverse() # flip the order to make norm point out
214 ret_face.append(fsub)
216 return ret_vert, ret_face
219 # Returns a list of faces that
220 # make up an array of 4 point polygon.
221 def Build_Face_List_Quads(OFFSET, COLUMN, ROW, FLIP=0):
222 Ret = []
223 RowStart = 0
224 for j in range(ROW):
225 for i in range(COLUMN):
226 Res1 = RowStart + i
227 Res2 = RowStart + i + (COLUMN + 1)
228 Res3 = RowStart + i + (COLUMN + 1) + 1
229 Res4 = RowStart + i + 1
230 if FLIP:
231 Ret.append([OFFSET + Res1, OFFSET + Res2, OFFSET + Res3, OFFSET + Res4])
232 else:
233 Ret.append([OFFSET + Res4, OFFSET + Res3, OFFSET + Res2, OFFSET + Res1])
234 RowStart += COLUMN + 1
235 return Ret
238 # Returns a list of faces that makes up a fill pattern for a
239 # circle
240 def Fill_Ring_Face(OFFSET, NUM, FACE_DOWN=0):
241 Ret = []
242 Face = [1, 2, 0]
243 TempFace = [0, 0, 0]
244 # A = 0 # UNUSED
245 B = 1
246 C = 2
247 if NUM < 3:
248 return None
249 for i in range(NUM - 2):
250 if (i % 2):
251 TempFace[0] = Face[C]
252 TempFace[1] = Face[C] + 1
253 TempFace[2] = Face[B]
254 if FACE_DOWN:
255 Ret.append([OFFSET + Face[2], OFFSET + Face[1], OFFSET + Face[0]])
256 else:
257 Ret.append([OFFSET + Face[0], OFFSET + Face[1], OFFSET + Face[2]])
258 else:
259 TempFace[0] = Face[C]
260 if Face[C] == 0:
261 TempFace[1] = NUM - 1
262 else:
263 TempFace[1] = Face[C] - 1
264 TempFace[2] = Face[B]
265 if FACE_DOWN:
266 Ret.append([OFFSET + Face[0], OFFSET + Face[1], OFFSET + Face[2]])
267 else:
268 Ret.append([OFFSET + Face[2], OFFSET + Face[1], OFFSET + Face[0]])
270 Face[0] = TempFace[0]
271 Face[1] = TempFace[1]
272 Face[2] = TempFace[2]
273 return Ret
275 # Returns a list of faces that makes up a fill pattern around the last vert
276 def Fill_Fan_Face(OFFSET, NUM, FACE_DOWN=0):
277 Ret = []
278 Face = [NUM-1,0,1]
279 TempFace = [0, 0, 0]
280 A = 0
281 #B = 1 unused
282 C = 2
283 if NUM < 3:
284 return None
285 for _i in range(NUM - 2):
286 TempFace[0] = Face[A]
287 TempFace[1] = Face[C]
288 TempFace[2] = Face[C]+1
289 if FACE_DOWN:
290 Ret.append([OFFSET + Face[2], OFFSET + Face[1], OFFSET + Face[0]])
291 else:
292 Ret.append([OFFSET + Face[2], OFFSET + Face[1], OFFSET + Face[0]])
294 Face[0] = TempFace[0]
295 Face[1] = TempFace[1]
296 Face[2] = TempFace[2]
297 return Ret
299 # ####################################################################
300 # Create Allen Bit
301 # ####################################################################
303 def Allen_Fill(OFFSET, FLIP=0):
304 faces = []
305 Lookup = [[19, 1, 0],
306 [19, 2, 1],
307 [19, 3, 2],
308 [19, 20, 3],
309 [20, 4, 3],
310 [20, 5, 4],
311 [20, 6, 5],
312 [20, 7, 6],
313 [20, 8, 7],
314 [20, 9, 8],
316 [20, 21, 9],
318 [21, 10, 9],
319 [21, 11, 10],
320 [21, 12, 11],
321 [21, 13, 12],
322 [21, 14, 13],
323 [21, 15, 14],
325 [21, 22, 15],
326 [22, 16, 15],
327 [22, 17, 16],
328 [22, 18, 17]
330 for i in Lookup:
331 if FLIP:
332 faces.append([OFFSET + i[2], OFFSET + i[1], OFFSET + i[0]])
333 else:
334 faces.append([OFFSET + i[0], OFFSET + i[1], OFFSET + i[2]])
336 return faces
339 def Allen_Bit_Dia(FLAT_DISTANCE):
340 Flat_Radius = (float(FLAT_DISTANCE) / 2.0) / cos(radians(30))
341 return (Flat_Radius * 1.05) * 2.0
344 def Allen_Bit_Dia_To_Flat(DIA):
345 Flat_Radius = (DIA / 2.0) / 1.05
346 return (Flat_Radius * cos(radians(30))) * 2.0
349 def Create_Allen_Bit(FLAT_DISTANCE, HEIGHT):
350 verts = []
351 faces = []
352 DIV_COUNT = 36
354 Flat_Radius = (float(FLAT_DISTANCE) / 2.0) / cos(radians(30))
355 OUTTER_RADIUS = Flat_Radius * 1.05
356 Outter_Radius_Height = Flat_Radius * (0.1 / 5.77)
357 FaceStart_Outside = len(verts)
358 Deg_Step = 360.0 / float(DIV_COUNT)
360 for i in range(int(DIV_COUNT / 2) + 1): # only do half and mirror later
361 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
362 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
363 verts.append([x, y, 0])
365 FaceStart_Inside = len(verts)
367 Deg_Step = 360.0 / float(6)
368 for i in range(int(6 / 2) + 1):
369 x = sin(radians(i * Deg_Step)) * Flat_Radius
370 y = cos(radians(i * Deg_Step)) * Flat_Radius
371 verts.append([x, y, 0 - Outter_Radius_Height])
373 faces.extend(Allen_Fill(FaceStart_Outside, 0))
375 FaceStart_Bottom = len(verts)
377 Deg_Step = 360.0 / float(6)
378 for i in range(int(6 / 2) + 1):
379 x = sin(radians(i * Deg_Step)) * Flat_Radius
380 y = cos(radians(i * Deg_Step)) * Flat_Radius
381 verts.append([x, y, 0 - HEIGHT])
383 faces.extend(Build_Face_List_Quads(FaceStart_Inside, 3, 1, True))
384 faces.extend(Fill_Ring_Face(FaceStart_Bottom, 4))
386 M_Verts, M_Faces = Mirror_Verts_Faces(verts, faces, 'y')
387 verts.extend(M_Verts)
388 faces.extend(M_Faces)
390 return verts, faces, OUTTER_RADIUS * 2.0
391 # ####################################################################
392 # Create Torx Bit
393 # ####################################################################
395 def Torx_Bit_Size_To_Point_Distance(Bit_Size):
396 if Bit_Size == 'bf_Torx_T10':
397 return 2.83
398 elif Bit_Size == 'bf_Torx_T20':
399 return 3.94
400 elif Bit_Size == 'bf_Torx_T25':
401 return 4.52
402 elif Bit_Size == 'bf_Torx_T30':
403 return 5.61
404 elif Bit_Size == 'bf_Torx_T40':
405 return 6.75
406 elif Bit_Size == 'bf_Torx_T50':
407 return 8.94
408 elif Bit_Size == 'bf_Torx_T55':
409 return 8.94
410 else:
411 return 2.83 #default to M3
413 def Torx_Fill(OFFSET, FLIP=0):
414 faces = []
415 Lookup = [[0,10,11],
416 [0,11, 12],
417 [0,12,1],
419 [1, 12, 13],
420 [1, 13, 14],
421 [1, 14, 15],
422 [1, 15, 2],
424 [2, 15, 16],
425 [2, 16, 17],
426 [2, 17, 18],
427 [2, 18, 19],
428 [2, 19, 3],
430 [3, 19, 20],
431 [3, 20, 21],
432 [3, 21, 22],
433 [3, 22, 23],
434 [3, 23, 24],
435 [3, 24, 25],
436 [3, 25, 4],
439 [4, 25, 26],
440 [4, 26, 27],
441 [4, 27, 28],
442 [4, 28, 29],
443 [4, 29, 30],
444 [4, 30, 31],
445 [4, 31, 5],
447 [5, 31, 32],
448 [5, 32, 33],
449 [5, 33, 34],
450 [5, 34, 35],
451 [5, 35, 36],
452 [5, 36, 6],
454 [6, 36, 37],
455 [6, 37, 38],
456 [6, 38, 39],
457 [6, 39, 7],
459 [7, 39, 40],
460 [7, 40, 41],
461 [7, 41, 42],
462 [7, 42, 43],
463 [7, 43, 8],
465 [8, 43, 44],
466 [8, 44, 45],
467 [8, 45, 46],
468 [8, 46, 47],
469 [8, 47, 48],
470 [8, 48, 49],
471 [8, 49, 50],
472 [8, 50, 51],
473 [8, 51, 52],
474 [8, 52, 9],
476 for i in Lookup:
477 if FLIP:
478 faces.append([OFFSET + i[2], OFFSET + i[1], OFFSET + i[0]])
479 else:
480 faces.append([OFFSET + i[0], OFFSET + i[1], OFFSET + i[2]])
482 return faces
486 def Create_Torx_Bit(Point_Distance, HEIGHT):
487 verts = []
488 faces = []
490 POINT_RADIUS = Point_Distance * 0.5
491 OUTTER_RADIUS = POINT_RADIUS * 1.05
493 POINT_1_Y = POINT_RADIUS * 0.816592592592593
494 POINT_2_X = POINT_RADIUS * 0.511111111111111
495 POINT_2_Y = POINT_RADIUS * 0.885274074074074
496 POINT_3_X = POINT_RADIUS * 0.7072
497 POINT_3_Y = POINT_RADIUS * 0.408296296296296
498 POINT_4_X = POINT_RADIUS * 1.02222222222222
499 SMALL_RADIUS = POINT_RADIUS * 0.183407407407407
500 BIG_RADIUS = POINT_RADIUS * 0.333333333333333
501 # Values for T40 # POINT_1_Y = 2.756
502 # POINT_2_X = 1.725
503 # POINT_2_Y = 2.9878
504 # POINT_3_X = 2.3868
505 # POINT_3_Y = 1.378
506 # POINT_4_X = 3.45
508 # SMALL_RADIUS = 0.619
509 # BIG_RADIUS = 1.125
511 def Do_Curve(Curve_Height):
512 for i in range(0, 90, 10):
513 x = sin(radians(i)) * SMALL_RADIUS
514 y = cos(radians(i)) * SMALL_RADIUS
515 verts.append([x, POINT_1_Y + y, Curve_Height])
517 for i in range(260, 150, -10):
518 x = sin(radians(i)) * BIG_RADIUS
519 y = cos(radians(i)) * BIG_RADIUS
520 verts.append([POINT_2_X + x, POINT_2_Y + y, Curve_Height])
522 for i in range(340, 150 + 360, 10):
523 x = sin(radians(i%360)) * SMALL_RADIUS
524 y = cos(radians(i%360)) * SMALL_RADIUS
525 verts.append([POINT_3_X + x, POINT_3_Y + y, Curve_Height])
527 for i in range(320, 260, -10):
528 x = sin(radians(i)) * BIG_RADIUS
529 y = cos(radians(i)) * BIG_RADIUS
530 verts.append([POINT_4_X + x, y, Curve_Height])
532 FaceStart_Outside = len(verts)
534 for i in range(0, 100, 10):
535 x = sin(radians(i)) * OUTTER_RADIUS
536 y = cos(radians(i)) * OUTTER_RADIUS
537 verts.append([x, y, 0])
539 FaceStart_Top_Curve= len(verts)
540 Do_Curve(0)
541 faces.extend(Torx_Fill(FaceStart_Outside, 0))
543 FaceStart_Bottom_Curve= len(verts)
544 Do_Curve(0 - HEIGHT)
546 faces.extend(Build_Face_List_Quads(FaceStart_Top_Curve,42 ,1 , True))
548 verts.append([0,0,0 - HEIGHT]) # add center point for fill Fan
549 faces.extend(Fill_Fan_Face(FaceStart_Bottom_Curve, 44))
551 M_Verts, M_Faces = Mirror_Verts_Faces(verts, faces, 'x')
552 verts.extend(M_Verts)
553 faces.extend(M_Faces)
555 M_Verts, M_Faces = Mirror_Verts_Faces(verts, faces, 'y')
556 verts.extend(M_Verts)
557 faces.extend(M_Faces)
559 return verts, faces, OUTTER_RADIUS * 2.0
561 # ####################################################################
562 # Create Phillips Bit
563 # ####################################################################
565 def Phillips_Fill(OFFSET, FLIP=0):
566 faces = []
567 Lookup = [[0, 1, 10],
568 [1, 11, 10],
569 [1, 2, 11],
570 [2, 12, 11],
572 [2, 3, 12],
573 [3, 4, 12],
574 [4, 5, 12],
575 [5, 6, 12],
576 [6, 7, 12],
578 [7, 13, 12],
579 [7, 8, 13],
580 [8, 14, 13],
581 [8, 9, 14],
583 [10, 11, 16, 15],
584 [11, 12, 16],
585 [12, 13, 16],
586 [13, 14, 17, 16],
587 [15, 16, 17, 18]
589 for i in Lookup:
590 if FLIP:
591 if len(i) == 3:
592 faces.append([OFFSET + i[2], OFFSET + i[1], OFFSET + i[0]])
593 else:
594 faces.append([OFFSET + i[3], OFFSET + i[2], OFFSET + i[1], OFFSET + i[0]])
595 else:
596 if len(i) == 3:
597 faces.append([OFFSET + i[0], OFFSET + i[1], OFFSET + i[2]])
598 else:
599 faces.append([OFFSET + i[0], OFFSET + i[1], OFFSET + i[2], OFFSET + i[3]])
600 return faces
603 def Create_Phillips_Bit(FLAT_DIA, FLAT_WIDTH, HEIGHT):
604 verts = []
605 faces = []
607 DIV_COUNT = 36
608 FLAT_RADIUS = FLAT_DIA * 0.5
609 OUTTER_RADIUS = FLAT_RADIUS * 1.05
611 Flat_Half = float(FLAT_WIDTH) / 2.0
613 FaceStart_Outside = len(verts)
614 Deg_Step = 360.0 / float(DIV_COUNT)
615 for i in range(int(DIV_COUNT / 4) + 1): # only do half and mirror later
616 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
617 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
618 verts.append([x, y, 0])
620 # FaceStart_Inside = len(verts) # UNUSED
621 verts.append([0, FLAT_RADIUS, 0]) # 10
622 verts.append([Flat_Half, FLAT_RADIUS, 0]) # 11
623 verts.append([Flat_Half, Flat_Half, 0]) # 12
624 verts.append([FLAT_RADIUS, Flat_Half, 0]) # 13
625 verts.append([FLAT_RADIUS, 0, 0]) # 14
627 verts.append([0, Flat_Half, 0 - HEIGHT]) # 15
628 verts.append([Flat_Half, Flat_Half, 0 - HEIGHT]) # 16
629 verts.append([Flat_Half, 0, 0 - HEIGHT]) # 17
631 verts.append([0, 0, 0 - HEIGHT]) # 18
633 faces.extend(Phillips_Fill(FaceStart_Outside, True))
635 Spin_Verts, Spin_Face = SpinDup(verts, faces, 360, 4, 'z')
637 return Spin_Verts, Spin_Face, OUTTER_RADIUS * 2
640 # ####################################################################
641 # Create Head Types
642 # ####################################################################
644 def Max_Pan_Bit_Dia(HEAD_DIA):
645 HEAD_RADIUS = HEAD_DIA * 0.5
646 XRad = HEAD_RADIUS * 1.976
647 return (sin(radians(10)) * XRad) * 2.0
650 def Create_Pan_Head(HOLE_DIA, HEAD_DIA, SHANK_DIA, HEIGHT, RAD1, RAD2, FACE_OFFSET, DIV_COUNT):
652 HOLE_RADIUS = HOLE_DIA * 0.5
653 HEAD_RADIUS = HEAD_DIA * 0.5
654 SHANK_RADIUS = SHANK_DIA * 0.5
656 verts = []
657 faces = []
658 Row = 0
660 XRad = HEAD_RADIUS * 1.976
661 ZRad = HEAD_RADIUS * 1.768
662 EndRad = HEAD_RADIUS * 0.284
663 EndZOffset = HEAD_RADIUS * 0.432
664 HEIGHT = HEAD_RADIUS * 0.59
667 Dome_Rad = 5.6
668 RAD_Offset = 4.9
669 OtherRad = 0.8
670 OtherRad_X_Offset = 4.2
671 OtherRad_Z_Offset = 2.52
672 XRad = 9.88
673 ZRad = 8.84
674 EndRad = 1.42
675 EndZOffset = 2.16
676 HEIGHT = 2.95
678 FaceStart = FACE_OFFSET
680 z = cos(radians(10)) * ZRad
681 verts.append([HOLE_RADIUS, 0.0, (0.0 - ZRad) + z])
682 Start_Height = 0 - ((0.0 - ZRad) + z)
683 Row += 1
685 # for i in range(0,30,10): was 0 to 30 more work needed to make this look good.
686 for i in range(10, 30, 10):
687 x = sin(radians(i)) * XRad
688 z = cos(radians(i)) * ZRad
689 verts.append([x, 0.0, (0.0 - ZRad) + z])
690 Row += 1
692 for i in range(20, 140, 10):
693 x = sin(radians(i)) * EndRad
694 z = cos(radians(i)) * EndRad
695 if ((0.0 - EndZOffset) + z) < (0.0 - HEIGHT):
696 verts.append([(HEAD_RADIUS - EndRad) + x, 0.0, 0.0 - HEIGHT])
697 else:
698 verts.append([(HEAD_RADIUS - EndRad) + x, 0.0, (0.0 - EndZOffset) + z])
699 Row += 1
701 verts.append([SHANK_RADIUS, 0.0, (0.0 - HEIGHT)])
702 Row += 1
704 verts.append([SHANK_RADIUS, 0.0, (0.0 - HEIGHT) - Start_Height])
705 Row += 1
707 sVerts, sFaces = SpinDup(verts, faces, 360, DIV_COUNT, 'z')
708 sVerts.extend(verts) # add the start verts to the Spin verts to complete the loop
710 faces.extend(Build_Face_List_Quads(FaceStart, Row - 1, DIV_COUNT))
712 # Global_Head_Height = HEIGHT # UNUSED
714 return Move_Verts_Up_Z(sVerts, Start_Height), faces, HEIGHT
717 def Create_Dome_Head(HOLE_DIA, HEAD_DIA, SHANK_DIA, HEIGHT, RAD1, RAD2, FACE_OFFSET, DIV_COUNT):
718 HOLE_RADIUS = HOLE_DIA * 0.5
719 HEAD_RADIUS = HEAD_DIA * 0.5
720 SHANK_RADIUS = SHANK_DIA * 0.5
722 verts = []
723 faces = []
724 Row = 0
725 # Dome_Rad = HEAD_RADIUS * (1.0/1.75)
727 Dome_Rad = HEAD_RADIUS * 1.12
728 # Head_Height = HEAD_RADIUS * 0.78
729 RAD_Offset = HEAD_RADIUS * 0.98
730 Dome_Height = HEAD_RADIUS * 0.64
731 OtherRad = HEAD_RADIUS * 0.16
732 OtherRad_X_Offset = HEAD_RADIUS * 0.84
733 OtherRad_Z_Offset = HEAD_RADIUS * 0.504
736 Dome_Rad = 5.6
737 RAD_Offset = 4.9
738 Dome_Height = 3.2
739 OtherRad = 0.8
740 OtherRad_X_Offset = 4.2
741 OtherRad_Z_Offset = 2.52
744 FaceStart = FACE_OFFSET
746 verts.append([HOLE_RADIUS, 0.0, 0.0])
747 Row += 1
749 for i in range(0, 60, 10):
750 x = sin(radians(i)) * Dome_Rad
751 z = cos(radians(i)) * Dome_Rad
752 if ((0.0 - RAD_Offset) + z) <= 0:
753 verts.append([x, 0.0, (0.0 - RAD_Offset) + z])
754 Row += 1
756 for i in range(60, 160, 10):
757 x = sin(radians(i)) * OtherRad
758 z = cos(radians(i)) * OtherRad
759 z = (0.0 - OtherRad_Z_Offset) + z
760 if z < (0.0 - Dome_Height):
761 z = (0.0 - Dome_Height)
762 verts.append([OtherRad_X_Offset + x, 0.0, z])
763 Row += 1
765 verts.append([SHANK_RADIUS, 0.0, (0.0 - Dome_Height)])
766 Row += 1
768 sVerts, sFaces = SpinDup(verts, faces, 360, DIV_COUNT, 'z')
769 sVerts.extend(verts) # add the start verts to the Spin verts to complete the loop
771 faces.extend(Build_Face_List_Quads(FaceStart, Row - 1, DIV_COUNT))
773 return sVerts, faces, Dome_Height
776 def Create_CounterSink_Head(HOLE_DIA, HEAD_DIA, SHANK_DIA, HEIGHT, RAD1, DIV_COUNT):
778 HOLE_RADIUS = HOLE_DIA * 0.5
779 HEAD_RADIUS = HEAD_DIA * 0.5
780 SHANK_RADIUS = SHANK_DIA * 0.5
782 verts = []
783 faces = []
784 Row = 0
786 # HEAD_RADIUS = (HEIGHT/tan(radians(60))) + SHANK_RADIUS
787 HEIGHT = tan(radians(60)) * (HEAD_RADIUS - SHANK_RADIUS)
789 FaceStart = len(verts)
791 verts.append([HOLE_RADIUS, 0.0, 0.0])
792 Row += 1
794 # rad
795 for i in range(0, 100, 10):
796 x = sin(radians(i)) * RAD1
797 z = cos(radians(i)) * RAD1
798 verts.append([(HEAD_RADIUS - RAD1) + x, 0.0, (0.0 - RAD1) + z])
799 Row += 1
801 verts.append([SHANK_RADIUS, 0.0, 0.0 - HEIGHT])
802 Row += 1
804 sVerts, sFaces = SpinDup(verts, faces, 360, DIV_COUNT, 'z')
805 sVerts.extend(verts) # add the start verts to the Spin verts to complete the loop
807 faces.extend(Build_Face_List_Quads(FaceStart, Row - 1, DIV_COUNT))
809 return sVerts, faces, HEIGHT
812 def Create_Cap_Head(HOLE_DIA, HEAD_DIA, SHANK_DIA, HEIGHT, RAD1, RAD2, DIV_COUNT):
814 HOLE_RADIUS = HOLE_DIA * 0.5
815 HEAD_RADIUS = HEAD_DIA * 0.5
816 SHANK_RADIUS = SHANK_DIA * 0.5
818 verts = []
819 faces = []
820 Row = 0
821 BEVEL = HEIGHT * 0.01
823 FaceStart = len(verts)
825 verts.append([HOLE_RADIUS, 0.0, 0.0])
826 Row += 1
828 # rad
829 for i in range(0, 100, 10):
830 x = sin(radians(i)) * RAD1
831 z = cos(radians(i)) * RAD1
832 verts.append([(HEAD_RADIUS - RAD1) + x, 0.0, (0.0 - RAD1) + z])
833 Row += 1
835 verts.append([HEAD_RADIUS, 0.0, 0.0 - HEIGHT + BEVEL])
836 Row += 1
838 verts.append([HEAD_RADIUS - BEVEL, 0.0, 0.0 - HEIGHT])
839 Row += 1
841 # rad2
842 for i in range(0, 100, 10):
843 x = sin(radians(i)) * RAD2
844 z = cos(radians(i)) * RAD2
845 verts.append([(SHANK_RADIUS + RAD2) - x, 0.0, (0.0 - HEIGHT - RAD2) + z])
846 Row += 1
848 sVerts, sFaces = SpinDup(verts, faces, 360, DIV_COUNT, 'z')
849 sVerts.extend(verts) # add the start verts to the Spin verts to complete the loop
851 faces.extend(Build_Face_List_Quads(FaceStart, Row - 1, DIV_COUNT))
853 return sVerts, faces, HEIGHT + RAD2
856 def Create_Hex_Head(FLAT, HOLE_DIA, SHANK_DIA, HEIGHT):
858 verts = []
859 faces = []
860 HOLE_RADIUS = HOLE_DIA * 0.5
861 Half_Flat = FLAT / 2
862 TopBevelRadius = Half_Flat - (Half_Flat * (0.05 / 8))
863 Undercut_Height = (Half_Flat * (0.05 / 8))
864 Shank_Bevel = (Half_Flat * (0.05 / 8))
865 Flat_Height = HEIGHT - Undercut_Height - Shank_Bevel
866 # Undercut_Height = 5
867 SHANK_RADIUS = SHANK_DIA / 2
868 Row = 0
870 verts.append([0.0, 0.0, 0.0])
872 FaceStart = len(verts)
874 # inner hole
875 x = sin(radians(0)) * HOLE_RADIUS
876 y = cos(radians(0)) * HOLE_RADIUS
877 verts.append([x, y, 0.0])
879 x = sin(radians(60 / 6)) * HOLE_RADIUS
880 y = cos(radians(60 / 6)) * HOLE_RADIUS
881 verts.append([x, y, 0.0])
883 x = sin(radians(60 / 3)) * HOLE_RADIUS
884 y = cos(radians(60 / 3)) * HOLE_RADIUS
885 verts.append([x, y, 0.0])
887 x = sin(radians(60 / 2)) * HOLE_RADIUS
888 y = cos(radians(60 / 2)) * HOLE_RADIUS
889 verts.append([x, y, 0.0])
890 Row += 1
892 # bevel
893 x = sin(radians(0)) * TopBevelRadius
894 y = cos(radians(0)) * TopBevelRadius
895 vec1 = Vector([x, y, 0.0])
896 verts.append([x, y, 0.0])
898 x = sin(radians(60 / 6)) * TopBevelRadius
899 y = cos(radians(60 / 6)) * TopBevelRadius
900 vec2 = Vector([x, y, 0.0])
901 verts.append([x, y, 0.0])
903 x = sin(radians(60 / 3)) * TopBevelRadius
904 y = cos(radians(60 / 3)) * TopBevelRadius
905 vec3 = Vector([x, y, 0.0])
906 verts.append([x, y, 0.0])
908 x = sin(radians(60 / 2)) * TopBevelRadius
909 y = cos(radians(60 / 2)) * TopBevelRadius
910 vec4 = Vector([x, y, 0.0])
911 verts.append([x, y, 0.0])
912 Row += 1
914 # Flats
915 x = tan(radians(0)) * Half_Flat
916 dvec = vec1 - Vector([x, Half_Flat, 0.0])
917 verts.append([x, Half_Flat, -dvec.length])
919 x = tan(radians(60 / 6)) * Half_Flat
920 dvec = vec2 - Vector([x, Half_Flat, 0.0])
921 verts.append([x, Half_Flat, -dvec.length])
923 x = tan(radians(60 / 3)) * Half_Flat
924 dvec = vec3 - Vector([x, Half_Flat, 0.0])
925 Lowest_Point = -dvec.length
926 verts.append([x, Half_Flat, -dvec.length])
928 x = tan(radians(60 / 2)) * Half_Flat
929 dvec = vec4 - Vector([x, Half_Flat, 0.0])
930 Lowest_Point = -dvec.length
931 verts.append([x, Half_Flat, -dvec.length])
932 Row += 1
934 # down Bits Tri
935 x = tan(radians(0)) * Half_Flat
936 verts.append([x, Half_Flat, Lowest_Point])
938 x = tan(radians(60 / 6)) * Half_Flat
939 verts.append([x, Half_Flat, Lowest_Point])
941 x = tan(radians(60 / 3)) * Half_Flat
942 verts.append([x, Half_Flat, Lowest_Point])
944 x = tan(radians(60 / 2)) * Half_Flat
945 verts.append([x, Half_Flat, Lowest_Point])
946 Row += 1
948 # down Bits
950 x = tan(radians(0)) * Half_Flat
951 verts.append([x, Half_Flat, -Flat_Height])
953 x = tan(radians(60 / 6)) * Half_Flat
954 verts.append([x, Half_Flat, -Flat_Height])
956 x = tan(radians(60 / 3)) * Half_Flat
957 verts.append([x, Half_Flat, -Flat_Height])
959 x = tan(radians(60 / 2)) * Half_Flat
960 verts.append([x, Half_Flat, -Flat_Height])
961 Row += 1
963 # Under cut
964 x = sin(radians(0)) * Half_Flat
965 y = cos(radians(0)) * Half_Flat
966 vec1 = Vector([x, y, 0.0])
967 verts.append([x, y, -Flat_Height])
969 x = sin(radians(60 / 6)) * Half_Flat
970 y = cos(radians(60 / 6)) * Half_Flat
971 vec2 = Vector([x, y, 0.0])
972 verts.append([x, y, -Flat_Height])
974 x = sin(radians(60 / 3)) * Half_Flat
975 y = cos(radians(60 / 3)) * Half_Flat
976 vec3 = Vector([x, y, 0.0])
977 verts.append([x, y, -Flat_Height])
979 x = sin(radians(60 / 2)) * Half_Flat
980 y = cos(radians(60 / 2)) * Half_Flat
981 vec3 = Vector([x, y, 0.0])
982 verts.append([x, y, -Flat_Height])
983 Row += 1
985 # Under cut down bit
986 x = sin(radians(0)) * Half_Flat
987 y = cos(radians(0)) * Half_Flat
988 vec1 = Vector([x, y, 0.0])
989 verts.append([x, y, -Flat_Height - Undercut_Height])
991 x = sin(radians(60 / 6)) * Half_Flat
992 y = cos(radians(60 / 6)) * Half_Flat
993 vec2 = Vector([x, y, 0.0])
994 verts.append([x, y, -Flat_Height - Undercut_Height])
996 x = sin(radians(60 / 3)) * Half_Flat
997 y = cos(radians(60 / 3)) * Half_Flat
998 vec3 = Vector([x, y, 0.0])
999 verts.append([x, y, -Flat_Height - Undercut_Height])
1001 x = sin(radians(60 / 2)) * Half_Flat
1002 y = cos(radians(60 / 2)) * Half_Flat
1003 vec3 = Vector([x, y, 0.0])
1004 verts.append([x, y, -Flat_Height - Undercut_Height])
1005 Row += 1
1007 # Under cut to Shank BEVEL
1008 x = sin(radians(0)) * (SHANK_RADIUS + Shank_Bevel)
1009 y = cos(radians(0)) * (SHANK_RADIUS + Shank_Bevel)
1010 vec1 = Vector([x, y, 0.0])
1011 verts.append([x, y, -Flat_Height - Undercut_Height])
1013 x = sin(radians(60 / 6)) * (SHANK_RADIUS + Shank_Bevel)
1014 y = cos(radians(60 / 6)) * (SHANK_RADIUS + Shank_Bevel)
1015 vec2 = Vector([x, y, 0.0])
1016 verts.append([x, y, -Flat_Height - Undercut_Height])
1018 x = sin(radians(60 / 3)) * (SHANK_RADIUS + Shank_Bevel)
1019 y = cos(radians(60 / 3)) * (SHANK_RADIUS + Shank_Bevel)
1020 vec3 = Vector([x, y, 0.0])
1021 verts.append([x, y, -Flat_Height - Undercut_Height])
1023 x = sin(radians(60 / 2)) * (SHANK_RADIUS + Shank_Bevel)
1024 y = cos(radians(60 / 2)) * (SHANK_RADIUS + Shank_Bevel)
1025 vec3 = Vector([x, y, 0.0])
1026 verts.append([x, y, -Flat_Height - Undercut_Height])
1027 Row += 1
1029 # Under cut to Shank BEVEL
1030 x = sin(radians(0)) * SHANK_RADIUS
1031 y = cos(radians(0)) * SHANK_RADIUS
1032 vec1 = Vector([x, y, 0.0])
1033 verts.append([x, y, -Flat_Height - Undercut_Height - Shank_Bevel])
1035 x = sin(radians(60 / 6)) * SHANK_RADIUS
1036 y = cos(radians(60 / 6)) * SHANK_RADIUS
1037 vec2 = Vector([x, y, 0.0])
1038 verts.append([x, y, -Flat_Height - Undercut_Height - Shank_Bevel])
1040 x = sin(radians(60 / 3)) * SHANK_RADIUS
1041 y = cos(radians(60 / 3)) * SHANK_RADIUS
1042 vec3 = Vector([x, y, 0.0])
1043 verts.append([x, y, -Flat_Height - Undercut_Height - Shank_Bevel])
1045 x = sin(radians(60 / 2)) * SHANK_RADIUS
1046 y = cos(radians(60 / 2)) * SHANK_RADIUS
1047 vec3 = Vector([x, y, 0.0])
1048 verts.append([x, y, -Flat_Height - Undercut_Height - Shank_Bevel])
1049 Row += 1
1051 faces.extend(Build_Face_List_Quads(FaceStart, 3, Row - 1))
1053 Mirror_Verts, Mirror_Faces = Mirror_Verts_Faces(verts, faces, 'y')
1054 verts.extend(Mirror_Verts)
1055 faces.extend(Mirror_Faces)
1057 Spin_Verts, Spin_Faces = SpinDup(verts, faces, 360, 6, 'z')
1059 return Spin_Verts, Spin_Faces, 0 - (-HEIGHT)
1063 def Create_12_Point(FLAT, HOLE_DIA, SHANK_DIA, HEIGHT,FLANGE_DIA):
1064 FLANGE_HEIGHT = (1.89/8.0)*HEIGHT
1065 FLAT_HEIGHT = (4.18/8.0)*HEIGHT
1066 # FLANGE_DIA = (13.27/8.0)*FLAT
1068 FLANGE_RADIUS = FLANGE_DIA * 0.5
1069 FLANGE_TAPPER_HEIGHT = HEIGHT - FLANGE_HEIGHT - FLAT_HEIGHT
1071 # HOLE_DIA = 0.0
1073 verts = []
1074 faces = []
1075 HOLE_RADIUS = HOLE_DIA / 2
1076 Half_Flat = FLAT / 2
1077 TopBevelRadius = Half_Flat - (Half_Flat * (0.05 / 8))
1078 # Undercut_Height = (Half_Flat * (0.05 / 8))
1079 # Shank_Bevel = (Half_Flat * (0.05 / 8))
1080 # Flat_Height = HEIGHT - Undercut_Height - Shank_Bevel
1081 # Undercut_Height = 5
1082 SHANK_RADIUS = SHANK_DIA / 2
1083 Row = 0
1085 verts.append([0.0, 0.0, 0.0])
1087 # print("HOLE_RADIUS" + str(HOLE_RADIUS))
1088 # print("TopBevelRadius" + str(TopBevelRadius))
1090 FaceStart = len(verts)
1092 # inner hole
1093 x = sin(radians(0)) * HOLE_RADIUS
1094 y = cos(radians(0)) * HOLE_RADIUS
1095 verts.append([x, y, 0.0])
1097 x = sin(radians(5)) * HOLE_RADIUS
1098 y = cos(radians(5)) * HOLE_RADIUS
1099 verts.append([x, y, 0.0])
1101 x = sin(radians(10)) * HOLE_RADIUS
1102 y = cos(radians(10)) * HOLE_RADIUS
1103 verts.append([x, y, 0.0])
1105 x = sin(radians(15)) * HOLE_RADIUS
1106 y = cos(radians(15)) * HOLE_RADIUS
1107 verts.append([x, y, 0.0])
1109 x = sin(radians(20)) * HOLE_RADIUS
1110 y = cos(radians(20)) * HOLE_RADIUS
1111 verts.append([x, y, 0.0])
1113 x = sin(radians(25)) * HOLE_RADIUS
1114 y = cos(radians(25)) * HOLE_RADIUS
1115 verts.append([x, y, 0.0])
1117 x = sin(radians(30)) * HOLE_RADIUS
1118 y = cos(radians(30)) * HOLE_RADIUS
1119 verts.append([x, y, 0.0])
1121 Row += 1
1125 # bevel
1126 x = sin(radians(0)) * TopBevelRadius
1127 y = cos(radians(0)) * TopBevelRadius
1128 vec1 = Vector([x, y, 0.0])
1129 verts.append([x, y, 0.0])
1131 x = sin(radians(5)) * TopBevelRadius
1132 y = cos(radians(5)) * TopBevelRadius
1133 vec2 = Vector([x, y, 0.0])
1134 verts.append([x, y, 0.0])
1136 x = sin(radians(10)) * TopBevelRadius
1137 y = cos(radians(10)) * TopBevelRadius
1138 vec3 = Vector([x, y, 0.0])
1139 verts.append([x, y, 0.0])
1141 x = sin(radians(15)) * TopBevelRadius
1142 y = cos(radians(15)) * TopBevelRadius
1143 vec4 = Vector([x, y, 0.0])
1144 verts.append([x, y, 0.0])
1146 x = sin(radians(20)) * TopBevelRadius
1147 y = cos(radians(20)) * TopBevelRadius
1148 vec5 = Vector([x, y, 0.0])
1149 verts.append([x, y, 0.0])
1151 x = sin(radians(25)) * TopBevelRadius
1152 y = cos(radians(25)) * TopBevelRadius
1153 vec6 = Vector([x, y, 0.0])
1154 verts.append([x, y, 0.0])
1156 x = sin(radians(30)) * TopBevelRadius
1157 y = cos(radians(30)) * TopBevelRadius
1158 vec7 = Vector([x, y, 0.0])
1159 verts.append([x, y, 0.0])
1161 Row += 1
1164 #45Deg bevel on the top
1166 #First we work out how far up the Y axis the vert is
1167 v_origin = Vector([0.0,0.0,0.0]) # center of the model
1168 v_15Deg_Point = Vector([tan(radians(15)) * Half_Flat,Half_Flat,0.0]) #Is a know point to work back from
1170 x = tan(radians(0)) * Half_Flat
1171 Point_Distance =(tan(radians(30)) * v_15Deg_Point.x)+Half_Flat
1172 dvec = vec1 - Vector([x, Point_Distance, 0.0])
1173 verts.append([x, Point_Distance, -dvec.length])
1174 v_0_Deg_Top_Point = Vector([x, Point_Distance, -dvec.length])
1176 v_0_Deg_Point = Vector([x, Point_Distance,0.0])
1178 v_5Deg_Line = Vector([tan(radians(5)) * Half_Flat, Half_Flat, 0.0])
1179 v_5Deg_Line.length *= 2 # extende out the line on a 5 deg angle
1181 #We cross 2 lines. One from the origin to the 0 Deg point
1182 #and the second is from the origin extended out past the first line
1183 # This gives the cross point of the
1184 v_Cross = geometry.intersect_line_line_2d(v_0_Deg_Point,v_15Deg_Point,v_origin,v_5Deg_Line)
1185 dvec = vec2 - Vector([v_Cross.x,v_Cross.y,0.0])
1186 verts.append([v_Cross.x,v_Cross.y,-dvec.length])
1187 v_5_Deg_Top_Point = Vector([v_Cross.x,v_Cross.y,-dvec.length])
1189 v_10Deg_Line = Vector([tan(radians(10)) * Half_Flat, Half_Flat, 0.0])
1190 v_10Deg_Line.length *= 2 # extende out the line
1192 v_Cross = geometry.intersect_line_line_2d(v_0_Deg_Point,v_15Deg_Point,v_origin,v_10Deg_Line)
1193 dvec = vec3 - Vector([v_Cross.x,v_Cross.y,0.0])
1194 verts.append([v_Cross.x,v_Cross.y,-dvec.length])
1195 v_10_Deg_Top_Point = Vector([v_Cross.x,v_Cross.y,-dvec.length])
1197 #The remain points are stright forward because y is all the same y height (Half_Flat)
1198 x = tan(radians(15)) * Half_Flat
1199 dvec = vec4 - Vector([x, Half_Flat, 0.0])
1200 Lowest_Point = -dvec.length
1201 verts.append([x, Half_Flat, -dvec.length])
1202 v_15_Deg_Top_Point = Vector([x, Half_Flat, -dvec.length])
1204 x = tan(radians(20)) * Half_Flat
1205 dvec = vec5 - Vector([x, Half_Flat, 0.0])
1206 Lowest_Point = -dvec.length
1207 verts.append([x, Half_Flat, -dvec.length])
1208 v_20_Deg_Top_Point = Vector([x, Half_Flat, -dvec.length])
1210 x = tan(radians(25)) * Half_Flat
1211 dvec = vec6 - Vector([x, Half_Flat, 0.0])
1212 Lowest_Point = -dvec.length
1213 verts.append([x, Half_Flat, -dvec.length])
1214 v_25_Deg_Top_Point = Vector([x, Half_Flat, -dvec.length])
1216 x = tan(radians(30)) * Half_Flat
1217 dvec = vec7 - Vector([x, Half_Flat, 0.0])
1218 Lowest_Point = -dvec.length
1219 verts.append([x, Half_Flat, -dvec.length])
1220 v_30_Deg_Top_Point = Vector([x, Half_Flat, -dvec.length])
1221 Row += 1
1224 #Down Bits
1225 # print ("Point_Distance")
1226 # print (Point_Distance)
1230 Flange_Adjacent = FLANGE_RADIUS - Point_Distance
1231 if (Flange_Adjacent == 0.0):
1232 Flange_Adjacent = 0.000001
1233 Flange_Opposite = FLANGE_TAPPER_HEIGHT
1235 # print ("Flange_Opposite")
1236 # print (Flange_Opposite)
1237 # print ("Flange_Adjacent")
1238 # print (Flange_Adjacent)
1240 FLANGE_ANGLE_RAD = atan(Flange_Opposite/Flange_Adjacent )
1241 # FLANGE_ANGLE_RAD = radians(45)
1242 # print("FLANGE_ANGLE_RAD")
1243 # print (degrees (FLANGE_ANGLE_RAD))
1246 v_Extended_Flange_Edge = Vector([0.0,0.0,-HEIGHT + FLANGE_HEIGHT + (tan(FLANGE_ANGLE_RAD)* FLANGE_RADIUS) ])
1247 # print("v_Extended_Flange_Edge")
1248 # print (v_Extended_Flange_Edge)
1250 #0deg
1251 v_Flange_Edge = Vector([sin(radians(0)) * FLANGE_RADIUS,cos(radians(0)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT ])
1252 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)
1253 verts.append(v_Cross[0])
1255 #5deg
1256 v_Flange_Edge = Vector([sin(radians(5)) * FLANGE_RADIUS,cos(radians(5)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT ])
1257 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)
1258 verts.append(v_Cross[0])
1260 #10deg
1261 v_Flange_Edge = Vector([sin(radians(10)) * FLANGE_RADIUS,cos(radians(10)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT ])
1262 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)
1263 verts.append(v_Cross[0])
1265 #15deg
1266 v_Flange_Edge = Vector([sin(radians(15)) * FLANGE_RADIUS,cos(radians(15)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT ])
1267 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)
1268 verts.append(v_Cross[0])
1271 #20deg
1272 v_Flange_Edge = Vector([sin(radians(20)) * FLANGE_RADIUS,cos(radians(20)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT ])
1273 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)
1274 verts.append(v_Cross[0])
1276 #25deg
1277 v_Flange_Edge = Vector([sin(radians(25)) * FLANGE_RADIUS,cos(radians(25)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT ])
1278 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)
1279 verts.append(v_Cross[0])
1282 #30deg
1283 v_Flange_Edge = Vector([sin(radians(30)) * FLANGE_RADIUS,cos(radians(30)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT ])
1284 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)
1285 verts.append(v_Cross[0])
1287 Row += 1
1291 verts.append([sin(radians(0)) * FLANGE_RADIUS,cos(radians(0)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT ])
1292 verts.append([sin(radians(5)) * FLANGE_RADIUS,cos(radians(5)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT])
1293 verts.append([sin(radians(10)) * FLANGE_RADIUS,cos(radians(10)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT])
1294 verts.append([sin(radians(15)) * FLANGE_RADIUS,cos(radians(15)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT])
1295 verts.append([sin(radians(20)) * FLANGE_RADIUS,cos(radians(20)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT])
1296 verts.append([sin(radians(25)) * FLANGE_RADIUS,cos(radians(25)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT])
1297 verts.append([sin(radians(30)) * FLANGE_RADIUS,cos(radians(30)) * FLANGE_RADIUS,-HEIGHT + FLANGE_HEIGHT])
1299 Row += 1
1301 verts.append([sin(radians(0)) * FLANGE_RADIUS,cos(radians(0)) * FLANGE_RADIUS,-HEIGHT])
1302 verts.append([sin(radians(5)) * FLANGE_RADIUS,cos(radians(5)) * FLANGE_RADIUS,-HEIGHT])
1303 verts.append([sin(radians(10)) * FLANGE_RADIUS,cos(radians(10)) * FLANGE_RADIUS,-HEIGHT])
1304 verts.append([sin(radians(15)) * FLANGE_RADIUS,cos(radians(15)) * FLANGE_RADIUS,-HEIGHT])
1305 verts.append([sin(radians(20)) * FLANGE_RADIUS,cos(radians(20)) * FLANGE_RADIUS,-HEIGHT])
1306 verts.append([sin(radians(25)) * FLANGE_RADIUS,cos(radians(25)) * FLANGE_RADIUS,-HEIGHT])
1307 verts.append([sin(radians(30)) * FLANGE_RADIUS,cos(radians(30)) * FLANGE_RADIUS,-HEIGHT])
1309 Row += 1
1312 verts.append([sin(radians(0)) * SHANK_RADIUS,cos(radians(0)) * SHANK_RADIUS,-HEIGHT])
1313 verts.append([sin(radians(0)) * SHANK_RADIUS,cos(radians(0)) * SHANK_RADIUS,-HEIGHT])
1314 verts.append([sin(radians(10)) * SHANK_RADIUS,cos(radians(10)) * SHANK_RADIUS,-HEIGHT])
1315 verts.append([sin(radians(10)) * SHANK_RADIUS,cos(radians(10)) * SHANK_RADIUS,-HEIGHT])
1316 verts.append([sin(radians(20)) * SHANK_RADIUS,cos(radians(20)) * SHANK_RADIUS,-HEIGHT])
1317 verts.append([sin(radians(20)) * SHANK_RADIUS,cos(radians(20)) * SHANK_RADIUS,-HEIGHT])
1318 verts.append([sin(radians(30)) * SHANK_RADIUS,cos(radians(30)) * SHANK_RADIUS,-HEIGHT])
1320 Row += 1
1323 faces.extend(Build_Face_List_Quads(FaceStart, 6, Row - 1))
1325 Spin_Verts, Spin_Faces = SpinDup(verts, faces, 360,12, 'z')
1327 return Spin_Verts, Spin_Faces, 0 - (-HEIGHT)
1330 def Create_12_Point_Head(FLAT, HOLE_DIA, SHANK_DIA, HEIGHT,FLANGE_DIA):
1331 #TODO add under head radius
1332 return Create_12_Point(FLAT, HOLE_DIA, SHANK_DIA, HEIGHT,FLANGE_DIA)
1336 # ####################################################################
1337 # Create External Thread
1338 # ####################################################################
1341 def Thread_Start3(verts, INNER_RADIUS, OUTTER_RADIUS, PITCH, DIV_COUNT,
1342 CREST_PERCENT, ROOT_PERCENT, Height_Offset):
1344 Ret_Row = 0
1346 Height_Start = Height_Offset - PITCH
1347 Height_Step = float(PITCH) / float(DIV_COUNT)
1348 Deg_Step = 360.0 / float(DIV_COUNT)
1350 Crest_Height = float(PITCH) * float(CREST_PERCENT) / float(100)
1351 Root_Height = float(PITCH) * float(ROOT_PERCENT) / float(100)
1352 Root_to_Crest_Height = Crest_to_Root_Height = \
1353 (float(PITCH) - (Crest_Height + Root_Height)) / 2.0
1355 # thread start
1356 Rank = float(OUTTER_RADIUS - INNER_RADIUS) / float(DIV_COUNT)
1357 for j in range(4):
1359 for i in range(DIV_COUNT + 1):
1360 z = Height_Offset - (Height_Step * i)
1361 if z > Height_Start:
1362 z = Height_Start
1363 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
1364 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
1365 verts.append([x, y, z])
1366 Height_Offset -= Crest_Height
1367 Ret_Row += 1
1369 for i in range(DIV_COUNT + 1):
1370 z = Height_Offset - (Height_Step * i)
1371 if z > Height_Start:
1372 z = Height_Start
1374 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
1375 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
1376 verts.append([x, y, z])
1377 Height_Offset -= Crest_to_Root_Height
1378 Ret_Row += 1
1380 for i in range(DIV_COUNT + 1):
1381 z = Height_Offset - (Height_Step * i)
1382 if z > Height_Start:
1383 z = Height_Start
1385 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
1386 y = cos(radians(i * Deg_Step)) * INNER_RADIUS
1387 if j == 0:
1388 x = sin(radians(i * Deg_Step)) * (OUTTER_RADIUS - (i * Rank))
1389 y = cos(radians(i * Deg_Step)) * (OUTTER_RADIUS - (i * Rank))
1390 verts.append([x, y, z])
1391 Height_Offset -= 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
1402 if j == 0:
1403 x = sin(radians(i * Deg_Step)) * (OUTTER_RADIUS - (i * Rank))
1404 y = cos(radians(i * Deg_Step)) * (OUTTER_RADIUS - (i * Rank))
1405 verts.append([x, y, z])
1406 Height_Offset -= Root_to_Crest_Height
1407 Ret_Row += 1
1409 return Ret_Row, Height_Offset
1412 def Create_Shank_Verts(START_DIA, OUTTER_DIA, LENGTH, Z_LOCATION, DIV_COUNT):
1414 verts = []
1416 START_RADIUS = START_DIA / 2
1417 OUTTER_RADIUS = OUTTER_DIA / 2
1419 Opp = abs(START_RADIUS - OUTTER_RADIUS)
1420 Taper_Lentgh = Opp / tan(radians(31))
1422 if Taper_Lentgh > LENGTH:
1423 Taper_Lentgh = 0
1425 Stright_Length = LENGTH - Taper_Lentgh
1427 Deg_Step = 360.0 / float(DIV_COUNT)
1429 Row = 0
1431 Lowest_Z_Vert = 0
1433 Height_Offset = Z_LOCATION
1435 # Ring
1436 for i in range(DIV_COUNT + 1):
1437 x = sin(radians(i * Deg_Step)) * START_RADIUS
1438 y = cos(radians(i * Deg_Step)) * START_RADIUS
1439 z = Height_Offset - 0
1440 verts.append([x, y, z])
1441 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1442 Height_Offset -= Stright_Length
1443 Row += 1
1445 for i in range(DIV_COUNT + 1):
1446 x = sin(radians(i * Deg_Step)) * START_RADIUS
1447 y = cos(radians(i * Deg_Step)) * START_RADIUS
1448 z = Height_Offset - 0
1449 verts.append([x, y, z])
1450 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1451 Height_Offset -= Taper_Lentgh
1452 Row += 1
1454 return verts, Row, Height_Offset
1457 def Create_Thread_Start_Verts(INNER_DIA, OUTTER_DIA, PITCH, CREST_PERCENT,
1458 ROOT_PERCENT, Z_LOCATION, DIV_COUNT):
1460 verts = []
1462 INNER_RADIUS = INNER_DIA / 2
1463 OUTTER_RADIUS = OUTTER_DIA / 2
1465 Deg_Step = 360.0 / float(DIV_COUNT)
1466 Height_Step = float(PITCH) / float(DIV_COUNT)
1468 Row = 0
1470 Lowest_Z_Vert = 0
1472 Height_Offset = Z_LOCATION
1474 Height_Start = Height_Offset
1476 Crest_Height = float(PITCH) * float(CREST_PERCENT) / float(100)
1477 Root_Height = float(PITCH) * float(ROOT_PERCENT) / float(100)
1478 Root_to_Crest_Height = Crest_to_Root_Height = \
1479 (float(PITCH) - (Crest_Height + Root_Height)) / 2.0
1481 Rank = float(OUTTER_RADIUS - INNER_RADIUS) / float(DIV_COUNT)
1483 Height_Offset = Z_LOCATION + PITCH
1484 Cut_off = Z_LOCATION
1486 for j in range(1):
1488 for i in range(DIV_COUNT + 1):
1489 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
1490 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
1491 z = Height_Offset - (Height_Step * i)
1492 if z > Cut_off:
1493 z = Cut_off
1494 verts.append([x, y, z])
1495 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1496 Height_Offset -= Crest_Height
1497 Row += 1
1499 for i in range(DIV_COUNT + 1):
1500 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
1501 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
1502 z = Height_Offset - (Height_Step * i)
1503 if z > Cut_off:
1504 z = Cut_off
1505 verts.append([x, y, z])
1506 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1507 Height_Offset -= Crest_to_Root_Height
1508 Row += 1
1510 for i in range(DIV_COUNT + 1):
1511 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
1512 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
1513 z = Height_Offset - (Height_Step * i)
1514 if z > Cut_off:
1515 z = Cut_off
1516 verts.append([x, y, z])
1517 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1518 Height_Offset -= Root_Height
1519 Row += 1
1521 for i in range(DIV_COUNT + 1):
1522 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
1523 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
1524 z = Height_Offset - (Height_Step * i)
1525 if z > Cut_off:
1526 z = Cut_off
1527 verts.append([x, y, z])
1528 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1529 Height_Offset -= Root_to_Crest_Height
1530 Row += 1
1532 for j in range(2):
1533 for i in range(DIV_COUNT + 1):
1534 z = Height_Offset - (Height_Step * i)
1535 if z > Height_Start:
1536 z = Height_Start
1537 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
1538 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
1539 verts.append([x, y, z])
1540 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1541 Height_Offset -= Crest_Height
1542 Row += 1
1544 for i in range(DIV_COUNT + 1):
1545 z = Height_Offset - (Height_Step * i)
1546 if z > Height_Start:
1547 z = Height_Start
1549 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
1550 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
1551 verts.append([x, y, z])
1552 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1553 Height_Offset -= Crest_to_Root_Height
1554 Row += 1
1556 for i in range(DIV_COUNT + 1):
1557 z = Height_Offset - (Height_Step * i)
1558 if z > Height_Start:
1559 z = Height_Start
1561 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
1562 y = cos(radians(i * Deg_Step)) * INNER_RADIUS
1563 if j == 0:
1564 x = sin(radians(i * Deg_Step)) * (OUTTER_RADIUS - (i * Rank))
1565 y = cos(radians(i * Deg_Step)) * (OUTTER_RADIUS - (i * Rank))
1566 verts.append([x, y, z])
1567 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1568 Height_Offset -= Root_Height
1569 Row += 1
1571 for i in range(DIV_COUNT + 1):
1572 z = Height_Offset - (Height_Step * i)
1573 if z > Height_Start:
1574 z = Height_Start
1576 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
1577 y = cos(radians(i * Deg_Step)) * INNER_RADIUS
1579 if j == 0:
1580 x = sin(radians(i * Deg_Step)) * (OUTTER_RADIUS - (i * Rank))
1581 y = cos(radians(i * Deg_Step)) * (OUTTER_RADIUS - (i * Rank))
1582 verts.append([x, y, z])
1583 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1584 Height_Offset -= Root_to_Crest_Height
1585 Row += 1
1587 return verts, Row, Height_Offset
1590 def Create_Thread_Verts(INNER_DIA, OUTTER_DIA, PITCH, HEIGHT,
1591 CREST_PERCENT, ROOT_PERCENT, Z_LOCATION, DIV_COUNT):
1593 verts = []
1595 INNER_RADIUS = INNER_DIA / 2
1596 OUTTER_RADIUS = OUTTER_DIA / 2
1598 Deg_Step = 360.0 / float(DIV_COUNT)
1599 Height_Step = float(PITCH) / float(DIV_COUNT)
1601 NUM_OF_START_THREADS = 4.0
1602 NUM_OF_END_THREADS = 3.0
1603 Num = int((HEIGHT - ((NUM_OF_START_THREADS * PITCH) + (NUM_OF_END_THREADS * PITCH))) / PITCH)
1604 Row = 0
1606 Crest_Height = float(PITCH) * float(CREST_PERCENT) / float(100)
1607 Root_Height = float(PITCH) * float(ROOT_PERCENT) / float(100)
1608 Root_to_Crest_Height = Crest_to_Root_Height = \
1609 (float(PITCH) - (Crest_Height + Root_Height)) / 2.0
1611 Height_Offset = Z_LOCATION
1613 Lowest_Z_Vert = 0
1615 for j in range(Num):
1617 for i in range(DIV_COUNT + 1):
1618 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
1619 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
1620 z = Height_Offset - (Height_Step * i)
1621 verts.append([x, y, z])
1622 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1623 Height_Offset -= Crest_Height
1624 Row += 1
1626 for i in range(DIV_COUNT + 1):
1627 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
1628 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
1629 z = Height_Offset - (Height_Step * i)
1630 verts.append([x, y, z])
1631 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1632 Height_Offset -= Crest_to_Root_Height
1633 Row += 1
1635 for i in range(DIV_COUNT + 1):
1636 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
1637 y = cos(radians(i * Deg_Step)) * INNER_RADIUS
1638 z = Height_Offset - (Height_Step * i)
1639 verts.append([x, y, z])
1640 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1641 Height_Offset -= Root_Height
1642 Row += 1
1644 for i in range(DIV_COUNT + 1):
1645 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
1646 y = cos(radians(i * Deg_Step)) * INNER_RADIUS
1647 z = Height_Offset - (Height_Step * i)
1648 verts.append([x, y, z])
1649 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1650 Height_Offset -= Root_to_Crest_Height
1651 Row += 1
1653 return verts, Row, Height_Offset
1656 def Create_Thread_End_Verts(INNER_DIA, OUTTER_DIA, PITCH, CREST_PERCENT,
1657 ROOT_PERCENT, Z_LOCATION, DIV_COUNT):
1658 verts = []
1660 INNER_RADIUS = INNER_DIA / 2
1661 OUTTER_RADIUS = OUTTER_DIA / 2
1663 Deg_Step = 360.0 / float(DIV_COUNT)
1664 Height_Step = float(PITCH) / float(DIV_COUNT)
1666 Crest_Height = float(PITCH) * float(CREST_PERCENT) / float(100)
1667 Root_Height = float(PITCH) * float(ROOT_PERCENT) / float(100)
1668 Root_to_Crest_Height = Crest_to_Root_Height = \
1669 (float(PITCH) - (Crest_Height + Root_Height)) / 2.0
1671 Row = 0
1673 Height_Offset = Z_LOCATION
1674 Tapper_Height_Start = Height_Offset - PITCH - PITCH
1675 Max_Height = Tapper_Height_Start - PITCH
1676 Lowest_Z_Vert = 0
1678 for j in range(4):
1680 for i in range(DIV_COUNT + 1):
1681 z = Height_Offset - (Height_Step * i)
1682 z = max(z, Max_Height)
1683 Tapper_Radius = OUTTER_RADIUS
1684 if z < Tapper_Height_Start:
1685 Tapper_Radius = OUTTER_RADIUS - (Tapper_Height_Start - z)
1687 x = sin(radians(i * Deg_Step)) * (Tapper_Radius)
1688 y = cos(radians(i * Deg_Step)) * (Tapper_Radius)
1689 verts.append([x, y, z])
1690 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1691 Height_Offset -= Crest_Height
1692 Row += 1
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_to_Root_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 - (Tapper_Height_Start - z)
1712 if Tapper_Radius > INNER_RADIUS:
1713 Tapper_Radius = INNER_RADIUS
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 -= 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_to_Crest_Height
1734 Row += 1
1736 return verts, Row, Height_Offset, Lowest_Z_Vert
1739 def Create_External_Thread(SHANK_DIA, SHANK_LENGTH, INNER_DIA, OUTTER_DIA,
1740 PITCH, LENGTH, CREST_PERCENT, ROOT_PERCENT, DIV_COUNT):
1742 verts = []
1743 faces = []
1745 Total_Row = 0
1746 # Thread_Len = 0 # UNUSED
1748 Face_Start = len(verts)
1749 Offset = 0.0
1751 Shank_Verts, Shank_Row, Offset = Create_Shank_Verts(
1752 SHANK_DIA, OUTTER_DIA, SHANK_LENGTH,
1753 Offset, DIV_COUNT
1755 Total_Row += Shank_Row
1757 Thread_Start_Verts, Thread_Start_Row, Offset = Create_Thread_Start_Verts(
1758 INNER_DIA, OUTTER_DIA, PITCH, CREST_PERCENT,
1759 ROOT_PERCENT, Offset, DIV_COUNT
1761 Total_Row += Thread_Start_Row
1763 Thread_Verts, Thread_Row, Offset = Create_Thread_Verts(
1764 INNER_DIA, OUTTER_DIA, PITCH, LENGTH,
1765 CREST_PERCENT, ROOT_PERCENT, Offset, DIV_COUNT
1767 Total_Row += Thread_Row
1769 Thread_End_Verts, Thread_End_Row, Offset, Lowest_Z_Vert = Create_Thread_End_Verts(
1770 INNER_DIA, OUTTER_DIA, PITCH, CREST_PERCENT,
1771 ROOT_PERCENT, Offset, DIV_COUNT
1773 Total_Row += Thread_End_Row
1775 verts.extend(Shank_Verts)
1776 verts.extend(Thread_Start_Verts)
1777 verts.extend(Thread_Verts)
1778 verts.extend(Thread_End_Verts)
1780 faces.extend(Build_Face_List_Quads(Face_Start, DIV_COUNT, Total_Row - 1, 0))
1781 faces.extend(Fill_Ring_Face(len(verts) - DIV_COUNT, DIV_COUNT, 1))
1783 return verts, faces, 0.0 - Lowest_Z_Vert
1786 # ####################################################################
1787 # Create Nut
1788 # ####################################################################
1790 def add_Hex_Nut(FLAT, HOLE_DIA, HEIGHT):
1791 global Global_Head_Height
1792 global Global_NutRad
1794 verts = []
1795 faces = []
1796 HOLE_RADIUS = HOLE_DIA * 0.5
1797 Half_Flat = FLAT / 2
1798 Half_Height = HEIGHT / 2
1799 TopBevelRadius = Half_Flat - 0.05
1801 Global_NutRad = TopBevelRadius
1803 Row = 0
1804 Lowest_Z_Vert = 0.0
1806 verts.append([0.0, 0.0, 0.0])
1808 FaceStart = len(verts)
1809 # inner hole
1811 x = sin(radians(0)) * HOLE_RADIUS
1812 y = cos(radians(0)) * HOLE_RADIUS
1813 # print ("rad 0 x;", x, "y:" ,y )
1814 verts.append([x, y, 0.0])
1816 x = sin(radians(60 / 6)) * HOLE_RADIUS
1817 y = cos(radians(60 / 6)) * HOLE_RADIUS
1818 # print ("rad 60/6x;", x, "y:" ,y )
1819 verts.append([x, y, 0.0])
1821 x = sin(radians(60 / 3)) * HOLE_RADIUS
1822 y = cos(radians(60 / 3)) * HOLE_RADIUS
1823 # print ("rad 60/3x;", x, "y:" ,y )
1824 verts.append([x, y, 0.0])
1826 x = sin(radians(60 / 2)) * HOLE_RADIUS
1827 y = cos(radians(60 / 2)) * HOLE_RADIUS
1828 # print ("rad 60/2x;", x, "y:" ,y )
1829 verts.append([x, y, 0.0])
1830 Row += 1
1832 # Bevel
1834 x = sin(radians(0)) * TopBevelRadius
1835 y = cos(radians(0)) * TopBevelRadius
1836 vec1 = Vector([x, y, 0.0])
1837 verts.append([x, y, 0.0])
1839 x = sin(radians(60 / 6)) * TopBevelRadius
1840 y = cos(radians(60 / 6)) * TopBevelRadius
1841 vec2 = Vector([x, y, 0.0])
1842 verts.append([x, y, 0.0])
1844 x = sin(radians(60 / 3)) * TopBevelRadius
1845 y = cos(radians(60 / 3)) * TopBevelRadius
1846 vec3 = Vector([x, y, 0.0])
1847 verts.append([x, y, 0.0])
1849 x = sin(radians(60 / 2)) * TopBevelRadius
1850 y = cos(radians(60 / 2)) * TopBevelRadius
1851 vec4 = Vector([x, y, 0.0])
1852 verts.append([x, y, 0.0])
1853 Row += 1
1855 # Flats
1856 x = tan(radians(0)) * Half_Flat
1857 dvec = vec1 - Vector([x, Half_Flat, 0.0])
1858 verts.append([x, Half_Flat, -dvec.length])
1859 Lowest_Z_Vert = min(Lowest_Z_Vert, -dvec.length)
1861 x = tan(radians(60 / 6)) * Half_Flat
1862 dvec = vec2 - Vector([x, Half_Flat, 0.0])
1863 verts.append([x, Half_Flat, -dvec.length])
1864 Lowest_Z_Vert = min(Lowest_Z_Vert, -dvec.length)
1866 x = tan(radians(60 / 3)) * Half_Flat
1867 dvec = vec3 - Vector([x, Half_Flat, 0.0])
1868 Lowest_Point = -dvec.length
1869 verts.append([x, Half_Flat, -dvec.length])
1870 Lowest_Z_Vert = min(Lowest_Z_Vert, -dvec.length)
1872 x = tan(radians(60 / 2)) * Half_Flat
1873 dvec = vec4 - Vector([x, Half_Flat, 0.0])
1874 Lowest_Point = -dvec.length
1875 verts.append([x, Half_Flat, -dvec.length])
1876 Lowest_Z_Vert = min(Lowest_Z_Vert, -dvec.length)
1877 Row += 1
1879 # down Bits Tri
1880 x = tan(radians(0)) * Half_Flat
1881 verts.append([x, Half_Flat, Lowest_Point])
1883 x = tan(radians(60 / 6)) * Half_Flat
1884 verts.append([x, Half_Flat, Lowest_Point])
1885 x = tan(radians(60 / 3)) * Half_Flat
1886 verts.append([x, Half_Flat, Lowest_Point])
1888 x = tan(radians(60 / 2)) * Half_Flat
1889 verts.append([x, Half_Flat, Lowest_Point])
1890 Lowest_Z_Vert = min(Lowest_Z_Vert, Lowest_Point)
1891 Row += 1
1893 # down Bits
1895 x = tan(radians(0)) * Half_Flat
1896 verts.append([x, Half_Flat, -Half_Height])
1898 x = tan(radians(60 / 6)) * Half_Flat
1899 verts.append([x, Half_Flat, -Half_Height])
1901 x = tan(radians(60 / 3)) * Half_Flat
1902 verts.append([x, Half_Flat, -Half_Height])
1904 x = tan(radians(60 / 2)) * Half_Flat
1905 verts.append([x, Half_Flat, -Half_Height])
1906 Lowest_Z_Vert = min(Lowest_Z_Vert, -Half_Height)
1907 Row += 1
1909 faces.extend(Build_Face_List_Quads(FaceStart, 3, Row - 1))
1911 Global_Head_Height = HEIGHT
1913 Tvert, tface = Mirror_Verts_Faces(verts, faces, 'z', Lowest_Z_Vert)
1914 verts.extend(Tvert)
1915 faces.extend(tface)
1917 Tvert, tface = Mirror_Verts_Faces(verts, faces, 'y')
1918 verts.extend(Tvert)
1919 faces.extend(tface)
1921 S_verts, S_faces = SpinDup(verts, faces, 360, 6, 'z')
1923 # return verts, faces, TopBevelRadius
1924 return S_verts, S_faces, TopBevelRadius
1927 def add_Nylon_Head(OUTSIDE_RADIUS, Z_LOCATION, DIV_COUNT):
1928 verts = []
1929 faces = []
1930 Row = 0
1932 INNER_HOLE = OUTSIDE_RADIUS - (OUTSIDE_RADIUS * (1.25 / 4.75))
1933 EDGE_THICKNESS = (OUTSIDE_RADIUS * (0.4 / 4.75))
1934 RAD1 = (OUTSIDE_RADIUS * (0.5 / 4.75))
1935 OVER_ALL_HEIGHT = (OUTSIDE_RADIUS * (2.0 / 4.75))
1937 FaceStart = len(verts)
1939 # Start_Height = 0 - 3 # UNUSED
1940 Height_Offset = Z_LOCATION
1941 Lowest_Z_Vert = 0
1943 x = INNER_HOLE
1944 z = (Height_Offset - OVER_ALL_HEIGHT) + EDGE_THICKNESS
1945 verts.append([x, 0.0, z])
1946 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1947 Row += 1
1949 x = INNER_HOLE
1950 z = (Height_Offset - OVER_ALL_HEIGHT)
1951 verts.append([x, 0.0, z])
1952 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1953 Row += 1
1955 for i in range(180, 80, -10):
1956 x = sin(radians(i)) * RAD1
1957 z = cos(radians(i)) * RAD1
1958 verts.append([(OUTSIDE_RADIUS - RAD1) + x, 0.0, ((Height_Offset - OVER_ALL_HEIGHT) + RAD1) + z])
1959 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1960 Row += 1
1962 x = OUTSIDE_RADIUS - 0
1963 z = Height_Offset
1964 verts.append([x, 0.0, z])
1965 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1966 Row += 1
1968 sVerts, sFaces = SpinDup(verts, faces, 360, DIV_COUNT, 'z')
1969 sVerts.extend(verts) # add the start verts to the Spin verts to complete the loop
1971 faces.extend(Build_Face_List_Quads(FaceStart, Row - 1, DIV_COUNT,1))
1973 return Move_Verts_Up_Z(sVerts, 0), faces, Lowest_Z_Vert
1976 def add_Nylon_Part(OUTSIDE_RADIUS, Z_LOCATION, DIV_COUNT):
1977 verts = []
1978 faces = []
1979 Row = 0
1981 INNER_HOLE = OUTSIDE_RADIUS - (OUTSIDE_RADIUS * (1.5 / 4.75))
1982 EDGE_THICKNESS = (OUTSIDE_RADIUS * (0.4 / 4.75))
1983 OVER_ALL_HEIGHT = (OUTSIDE_RADIUS * (2.0 / 4.75))
1984 PART_THICKNESS = OVER_ALL_HEIGHT - EDGE_THICKNESS
1985 PART_INNER_HOLE = (OUTSIDE_RADIUS * (2.5 / 4.75))
1987 FaceStart = len(verts)
1989 Height_Offset = Z_LOCATION
1990 Lowest_Z_Vert = 0
1992 x = INNER_HOLE + EDGE_THICKNESS
1993 z = Height_Offset
1994 verts.append([x, 0.0, z])
1995 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
1996 Row += 1
1998 x = PART_INNER_HOLE
1999 z = Height_Offset
2000 verts.append([x, 0.0, z])
2001 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
2002 Row += 1
2004 x = PART_INNER_HOLE
2005 z = Height_Offset - PART_THICKNESS
2006 verts.append([x, 0.0, z])
2007 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
2008 Row += 1
2010 x = INNER_HOLE + EDGE_THICKNESS
2011 z = Height_Offset - PART_THICKNESS
2012 verts.append([x, 0.0, z])
2013 Lowest_Z_Vert = min(Lowest_Z_Vert, z)
2014 Row += 1
2016 sVerts, sFaces = SpinDup(verts, faces, 360, DIV_COUNT, 'z')
2017 sVerts.extend(verts) # add the start verts to the Spin verts to complete the loop
2019 faces.extend(Build_Face_List_Quads(FaceStart, Row - 1, DIV_COUNT, 1))
2021 return sVerts, faces, 0 - Lowest_Z_Vert
2024 def add_12_Point_Nut(FLAT, HOLE_DIA, HEIGHT,FLANGE_DIA):
2025 return Create_12_Point(FLAT, HOLE_DIA,HOLE_DIA, HEIGHT,FLANGE_DIA)
2029 # ####################################################################
2030 # Create Internal Thread
2031 # ####################################################################
2033 def Create_Internal_Thread_Start_Verts(verts, INNER_RADIUS, OUTTER_RADIUS, PITCH, DIV,
2034 CREST_PERCENT, ROOT_PERCENT, Height_Offset):
2036 Ret_Row = 0
2037 # Move the offset up so that the verts start at
2038 # at the correct place (Height_Start)
2039 Height_Offset = Height_Offset + PITCH
2041 Height_Start = Height_Offset - PITCH
2042 Height_Step = float(PITCH) / float(DIV)
2043 Deg_Step = 360.0 / float(DIV)
2045 Crest_Height = float(PITCH) * float(CREST_PERCENT) / float(100)
2046 Root_Height = float(PITCH) * float(ROOT_PERCENT) / float(100)
2047 Root_to_Crest_Height = Crest_to_Root_Height = \
2048 (float(PITCH) - (Crest_Height + Root_Height)) / 2.0
2050 Rank = float(OUTTER_RADIUS - INNER_RADIUS) / float(DIV)
2052 for i in range(DIV + 1):
2053 z = Height_Offset - (Height_Step * i)
2054 if z > Height_Start:
2055 z = Height_Start
2056 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
2057 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
2059 verts.append([x, y, z])
2060 Height_Offset -= Crest_Height
2061 Ret_Row += 1
2063 for i in range(DIV + 1):
2064 z = Height_Offset - (Height_Step * i)
2065 if z > Height_Start:
2066 z = Height_Start
2068 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
2069 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
2071 verts.append([x, y, z])
2072 Height_Offset -= Crest_to_Root_Height
2073 Ret_Row += 1
2075 for i in range(DIV + 1):
2076 z = Height_Offset - (Height_Step * i)
2077 if z > Height_Start:
2078 z = Height_Start
2080 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
2081 y = cos(radians(i * Deg_Step)) * INNER_RADIUS
2083 x = sin(radians(i * Deg_Step)) * (OUTTER_RADIUS - (i * Rank))
2084 y = cos(radians(i * Deg_Step)) * (OUTTER_RADIUS - (i * Rank))
2086 verts.append([x, y, z])
2087 Height_Offset -= Root_Height
2088 Ret_Row += 1
2090 for i in range(DIV + 1):
2091 z = Height_Offset - (Height_Step * i)
2092 if z > Height_Start:
2093 z = Height_Start
2095 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
2096 y = cos(radians(i * Deg_Step)) * INNER_RADIUS
2098 x = sin(radians(i * Deg_Step)) * (OUTTER_RADIUS - (i * Rank))
2099 y = cos(radians(i * Deg_Step)) * (OUTTER_RADIUS - (i * Rank))
2101 verts.append([x, y, z])
2102 Height_Offset -= Root_to_Crest_Height
2103 Ret_Row += 1
2105 return Ret_Row, Height_Offset
2108 def Create_Internal_Thread_End_Verts(verts, INNER_RADIUS, OUTTER_RADIUS, PITCH,
2109 CREST_PERCENT, ROOT_PERCENT, Height_Offset,
2110 DIV_COUNT):
2111 Ret_Row = 0
2112 Height_End = Height_Offset - PITCH
2113 Height_Step = float(PITCH) / float(DIV_COUNT)
2114 Deg_Step = 360.0 / float(DIV_COUNT)
2116 Crest_Height = float(PITCH) * float(CREST_PERCENT) / float(100)
2117 Root_Height = float(PITCH) * float(ROOT_PERCENT) / float(100)
2118 Root_to_Crest_Height = Crest_to_Root_Height = \
2119 (float(PITCH) - (Crest_Height + Root_Height)) / 2.0
2121 Rank = float(OUTTER_RADIUS - INNER_RADIUS) / float(DIV_COUNT)
2123 Num = 0
2125 for j in range(2):
2126 for i in range(DIV_COUNT + 1):
2127 z = Height_Offset - (Height_Step * i)
2128 if z < Height_End:
2129 z = Height_End
2130 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
2131 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
2132 verts.append([x, y, z])
2134 Height_Offset -= Crest_Height
2135 Ret_Row += 1
2137 for i in range(DIV_COUNT + 1):
2138 z = Height_Offset - (Height_Step * i)
2139 if z < Height_End:
2140 z = Height_End
2142 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
2143 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
2144 verts.append([x, y, z])
2146 Height_Offset -= Crest_to_Root_Height
2147 Ret_Row += 1
2149 for i in range(DIV_COUNT + 1):
2150 z = Height_Offset - (Height_Step * i)
2151 if z < Height_End:
2152 z = Height_End
2154 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
2155 y = cos(radians(i * Deg_Step)) * INNER_RADIUS
2157 if j == Num:
2158 # Fix T51338 - seems that the placing a small random offset makes the mesh valid
2159 rand_offset = triangular(0.0001, 0.009)
2160 x = sin(radians(i * Deg_Step)) * (INNER_RADIUS + (i * Rank + rand_offset))
2161 y = cos(radians(i * Deg_Step)) * (INNER_RADIUS + (i * Rank + rand_offset))
2163 if j > Num:
2164 x = sin(radians(i * Deg_Step)) * (OUTTER_RADIUS)
2165 y = cos(radians(i * Deg_Step)) * (OUTTER_RADIUS)
2167 verts.append([x, y, z])
2169 Height_Offset -= Root_Height
2170 Ret_Row += 1
2172 for i in range(DIV_COUNT + 1):
2173 z = Height_Offset - (Height_Step * i)
2174 if z < Height_End:
2175 z = Height_End
2177 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
2178 y = cos(radians(i * Deg_Step)) * INNER_RADIUS
2180 if j == Num:
2181 x = sin(radians(i * Deg_Step)) * (INNER_RADIUS + (i * Rank))
2182 y = cos(radians(i * Deg_Step)) * (INNER_RADIUS + (i * Rank))
2183 if j > Num:
2184 x = sin(radians(i * Deg_Step)) * (OUTTER_RADIUS)
2185 y = cos(radians(i * Deg_Step)) * (OUTTER_RADIUS)
2187 verts.append([x, y, z])
2189 Height_Offset -= Root_to_Crest_Height
2190 Ret_Row += 1
2192 return Ret_Row, Height_End # send back Height End as this is the lowest point
2195 def Create_Internal_Thread(INNER_DIA, OUTTER_DIA, PITCH, HEIGHT,
2196 CREST_PERCENT, ROOT_PERCENT, INTERNAL, DIV_COUNT):
2197 verts = []
2198 faces = []
2200 INNER_RADIUS = INNER_DIA / 2
2201 OUTTER_RADIUS = OUTTER_DIA / 2
2203 Deg_Step = 360.0 / float(DIV_COUNT)
2204 Height_Step = float(PITCH) / float(DIV_COUNT)
2206 # less one pitch for the start and end that is 1/2 pitch high
2207 Num = int(round((HEIGHT - PITCH) / PITCH))
2209 Row = 0
2211 Crest_Height = float(PITCH) * float(CREST_PERCENT) / float(100)
2212 Root_Height = float(PITCH) * float(ROOT_PERCENT) / float(100)
2213 Root_to_Crest_Height = Crest_to_Root_Height = \
2214 (float(PITCH) - (Crest_Height + Root_Height)) / 2.0
2216 Height_Offset = 0
2217 FaceStart = len(verts)
2219 Row_Inc, Height_Offset = Create_Internal_Thread_Start_Verts(
2220 verts, INNER_RADIUS, OUTTER_RADIUS, PITCH,
2221 DIV_COUNT, CREST_PERCENT, ROOT_PERCENT,
2222 Height_Offset
2224 Row += Row_Inc
2226 for j in range(Num):
2228 for i in range(DIV_COUNT + 1):
2229 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
2230 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
2231 verts.append([x, y, Height_Offset - (Height_Step * i)])
2232 Height_Offset -= Crest_Height
2233 Row += 1
2235 for i in range(DIV_COUNT + 1):
2236 x = sin(radians(i * Deg_Step)) * OUTTER_RADIUS
2237 y = cos(radians(i * Deg_Step)) * OUTTER_RADIUS
2238 verts.append([x, y, Height_Offset - (Height_Step * i)])
2239 Height_Offset -= Crest_to_Root_Height
2240 Row += 1
2242 for i in range(DIV_COUNT + 1):
2243 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
2244 y = cos(radians(i * Deg_Step)) * INNER_RADIUS
2245 verts.append([x, y, Height_Offset - (Height_Step * i)])
2246 Height_Offset -= Root_Height
2247 Row += 1
2249 for i in range(DIV_COUNT + 1):
2250 x = sin(radians(i * Deg_Step)) * INNER_RADIUS
2251 y = cos(radians(i * Deg_Step)) * INNER_RADIUS
2252 verts.append([x, y, Height_Offset - (Height_Step * i)])
2253 Height_Offset -= Root_to_Crest_Height
2254 Row += 1
2256 Row_Inc, Height_Offset = Create_Internal_Thread_End_Verts(
2257 verts, INNER_RADIUS, OUTTER_RADIUS,
2258 PITCH, CREST_PERCENT,
2259 ROOT_PERCENT, Height_Offset, DIV_COUNT
2262 Row += Row_Inc
2263 faces.extend(Build_Face_List_Quads(FaceStart, DIV_COUNT, Row - 1, FLIP=1))
2265 return verts, faces, 0 - Height_Offset
2268 def Nut_Mesh(props, context):
2270 verts = []
2271 faces = []
2272 Head_Verts = []
2273 Head_Faces = []
2276 Face_Start = len(verts)
2279 if props.bf_Nut_Type == 'bf_Nut_12Pnt':
2280 Nut_Height = props.bf_12_Point_Nut_Height
2281 else:
2282 Nut_Height = props.bf_Hex_Nut_Height
2284 Thread_Verts, Thread_Faces, New_Nut_Height = Create_Internal_Thread(
2285 props.bf_Minor_Dia, props.bf_Major_Dia,
2286 props.bf_Pitch, Nut_Height,
2287 props.bf_Crest_Percent, props.bf_Root_Percent,
2288 1, props.bf_Div_Count
2290 verts.extend(Thread_Verts)
2291 faces.extend(Copy_Faces(Thread_Faces, Face_Start))
2293 Face_Start = len(verts)
2295 if props.bf_Nut_Type == 'bf_Nut_12Pnt':
2296 Head_Verts, Head_Faces, Lock_Nut_Rad = add_12_Point_Nut(
2297 props.bf_12_Point_Nut_Flat_Distance,
2298 props.bf_Major_Dia, New_Nut_Height,
2299 #Limit the size of the Flange to avoid calculation error
2300 max(props.bf_12_Point_Nut_Flange_Dia,props.bf_12_Point_Nut_Flat_Distance)
2302 else:
2303 Head_Verts, Head_Faces, Lock_Nut_Rad = add_Hex_Nut(
2304 props.bf_Hex_Nut_Flat_Distance,
2305 props.bf_Major_Dia, New_Nut_Height
2307 verts.extend((Head_Verts))
2308 faces.extend(Copy_Faces(Head_Faces, Face_Start))
2310 LowZ = 0 - New_Nut_Height
2312 if props.bf_Nut_Type == 'bf_Nut_Lock':
2313 Face_Start = len(verts)
2314 Nylon_Head_Verts, Nylon_Head_faces, LowZ = add_Nylon_Head(
2315 Lock_Nut_Rad, 0 - New_Nut_Height,
2316 props.bf_Div_Count
2318 verts.extend((Nylon_Head_Verts))
2319 faces.extend(Copy_Faces(Nylon_Head_faces, Face_Start))
2321 Face_Start = len(verts)
2322 Nylon_Verts, Nylon_faces, Temp_LowZ = add_Nylon_Part(
2323 Lock_Nut_Rad, 0 - New_Nut_Height,
2324 props.bf_Div_Count
2326 verts.extend((Nylon_Verts))
2327 faces.extend(Copy_Faces(Nylon_faces, Face_Start))
2329 return Move_Verts_Up_Z(verts, 0 - LowZ), faces
2332 # ####################################################################
2333 # Create Bolt
2334 # ####################################################################
2336 def Bolt_Mesh(props, context):
2338 verts = []
2339 faces = []
2340 Bit_Verts = []
2341 Bit_Faces = []
2342 Bit_Dia = 0.001
2343 Head_Verts = []
2344 Head_Faces = []
2345 Head_Height = 0.0
2347 ReSized_Allen_Bit_Flat_Distance = props.bf_Allen_Bit_Flat_Distance # set default
2349 Head_Height = props.bf_Hex_Head_Height # will be changed by the Head Functions
2351 if props.bf_Bit_Type == 'bf_Bit_Allen' and props.bf_Head_Type == 'bf_Head_Pan':
2352 # need to size Allen bit if it is too big.
2353 if Allen_Bit_Dia(props.bf_Allen_Bit_Flat_Distance) > Max_Pan_Bit_Dia(props.bf_Pan_Head_Dia):
2354 ReSized_Allen_Bit_Flat_Distance = Allen_Bit_Dia_To_Flat(
2355 Max_Pan_Bit_Dia(props.bf_Pan_Head_Dia)
2357 ReSized_Allen_Bit_Flat_Distance -= ReSized_Allen_Bit_Flat_Distance * 0.05 # It looks better if it is just a bit smaller
2358 # print ("Resized Allen Bit Flat Distance to ",ReSized_Allen_Bit_Flat_Distance)
2360 # Bit Mesh
2361 if props.bf_Bit_Type == 'bf_Bit_Allen':
2362 Bit_Verts, Bit_Faces, Bit_Dia = Create_Allen_Bit(
2363 ReSized_Allen_Bit_Flat_Distance,
2364 props.bf_Allen_Bit_Depth
2367 if props.bf_Bit_Type == 'bf_Bit_Torx':
2368 Bit_Verts, Bit_Faces, Bit_Dia = Create_Torx_Bit(
2369 Torx_Bit_Size_To_Point_Distance(props.bf_Torx_Size_Type),
2370 props.bf_Torx_Bit_Depth
2374 if props.bf_Bit_Type == 'bf_Bit_Philips':
2375 Bit_Verts, Bit_Faces, Bit_Dia = Create_Phillips_Bit(
2376 props.bf_Philips_Bit_Dia,
2377 props.bf_Philips_Bit_Dia * (0.5 / 1.82),
2378 props.bf_Phillips_Bit_Depth
2380 # Head Mesh
2381 if props.bf_Head_Type == 'bf_Head_Hex':
2382 Head_Verts, Head_Faces, Head_Height = Create_Hex_Head(
2383 props.bf_Hex_Head_Flat_Distance, Bit_Dia,
2384 props.bf_Shank_Dia, props.bf_Hex_Head_Height
2387 elif props.bf_Head_Type == 'bf_Head_12Pnt':
2388 Head_Verts, Head_Faces, Head_Height = Create_12_Point_Head(
2389 props.bf_12_Point_Head_Flat_Distance, Bit_Dia,
2390 props.bf_Shank_Dia, props.bf_12_Point_Head_Height,
2391 #Limit the size of the Flange to avoid calculation error
2392 max(props.bf_12_Point_Head_Flange_Dia,props.bf_12_Point_Head_Flat_Distance)
2394 elif props.bf_Head_Type == 'bf_Head_Cap':
2395 Head_Verts, Head_Faces, Head_Height = Create_Cap_Head(
2396 Bit_Dia, props.bf_Cap_Head_Dia,
2397 props.bf_Shank_Dia, props.bf_Cap_Head_Height,
2398 props.bf_Cap_Head_Dia * (1.0 / 19.0),
2399 props.bf_Cap_Head_Dia * (1.0 / 19.0),
2400 props.bf_Div_Count
2402 elif props.bf_Head_Type == 'bf_Head_Dome':
2403 Head_Verts, Head_Faces, Head_Height = Create_Dome_Head(
2404 Bit_Dia, props.bf_Dome_Head_Dia,
2405 props.bf_Shank_Dia, props.bf_Hex_Head_Height,
2406 1, 1, 0, props.bf_Div_Count
2409 elif props.bf_Head_Type == 'bf_Head_Pan':
2410 Head_Verts, Head_Faces, Head_Height = Create_Pan_Head(
2411 Bit_Dia, props.bf_Pan_Head_Dia,
2412 props.bf_Shank_Dia,
2413 props.bf_Hex_Head_Height, 1, 1, 0,
2414 props.bf_Div_Count
2416 elif props.bf_Head_Type == 'bf_Head_CounterSink':
2417 Head_Verts, Head_Faces, Head_Height = Create_CounterSink_Head(
2418 Bit_Dia, props.bf_CounterSink_Head_Dia,
2419 props.bf_Shank_Dia, props.bf_CounterSink_Head_Dia,
2420 props.bf_CounterSink_Head_Dia * (0.09 / 6.31),
2421 props.bf_Div_Count
2424 Face_Start = len(verts)
2425 verts.extend(Move_Verts_Up_Z(Bit_Verts, Head_Height))
2426 faces.extend(Copy_Faces(Bit_Faces, Face_Start))
2428 Face_Start = len(verts)
2429 verts.extend(Move_Verts_Up_Z(Head_Verts, Head_Height))
2430 faces.extend(Copy_Faces(Head_Faces, Face_Start))
2432 Face_Start = len(verts)
2433 Thread_Verts, Thread_Faces, Thread_Height = Create_External_Thread(
2434 props.bf_Shank_Dia, props.bf_Shank_Length,
2435 props.bf_Minor_Dia, props.bf_Major_Dia,
2436 props.bf_Pitch, props.bf_Thread_Length,
2437 props.bf_Crest_Percent,
2438 props.bf_Root_Percent, props.bf_Div_Count
2441 verts.extend(Move_Verts_Up_Z(Thread_Verts, 0))
2442 faces.extend(Copy_Faces(Thread_Faces, Face_Start))
2444 return Move_Verts_Up_Z(verts, Thread_Height), faces
2453 def Create_New_Mesh(props, context):
2455 verts = []
2456 faces = []
2457 edges = []
2458 sObjName = ''
2460 if props.bf_Model_Type == 'bf_Model_Bolt':
2461 # print('Create Bolt')
2462 verts, faces = Bolt_Mesh(props, context)
2463 sObjName = 'Bolt'
2465 if props.bf_Model_Type == 'bf_Model_Nut':
2466 # print('Create Nut')
2467 verts, faces = Nut_Mesh(props, context)
2468 sObjName = 'Nut'
2470 verts, faces = RemoveDoubles(verts, faces)
2472 verts = Scale_Mesh_Verts(verts, GLOBAL_SCALE)
2474 mesh = bpy.data.meshes.new(name=sObjName)
2475 mesh.from_pydata(verts, edges, faces)
2477 # useful for development when the mesh may be invalid.
2478 # Fix T51338 : Validate the mesh (the internal thread generator for the Nut
2479 # should be more reliable now, however there could be other possible errors)
2480 is_not_mesh_valid = mesh.validate()
2482 if is_not_mesh_valid:
2483 props.report({'INFO'}, "Mesh is not Valid, correcting")
2485 return mesh