Sun Position: Fix crash when Blender was started in background
[blender-addons.git] / add_mesh_BoltFactory / Boltfactory.py
blob0c56e9b7870624611f7a8490cbf7046511f99f36
1 # SPDX-License-Identifier: GPL-2.0-or-later
4 import bpy
5 import bmesh
6 from mathutils import Matrix
7 from bpy.types import Operator
8 from bpy_extras.object_utils import AddObjectHelper
9 from bpy.props import (
10 BoolProperty,
11 EnumProperty,
12 FloatProperty,
13 IntProperty,
14 FloatVectorProperty,
15 StringProperty,
17 from . import createMesh
18 from bpy_extras import object_utils
21 class add_mesh_bolt(Operator, AddObjectHelper):
22 bl_idname = "mesh.bolt_add"
23 bl_label = "Add Bolt"
24 bl_options = {'REGISTER', 'UNDO', 'PRESET'}
25 bl_description = "Construct many types of Bolts"
28 MAX_INPUT_NUMBER = 50
30 Bolt : BoolProperty(name = "Bolt",
31 default = True,
32 description = "Bolt")
33 change : BoolProperty(name = "Change",
34 default = False,
35 description = "change Bolt")
37 # Model Types
38 Model_Type_List = [('bf_Model_Bolt', 'BOLT', 'Bolt Model'),
39 ('bf_Model_Nut', 'NUT', 'Nut Model')]
40 bf_Model_Type: EnumProperty(
41 attr='bf_Model_Type',
42 name='Model',
43 description='Choose the type off model you would like',
44 items=Model_Type_List, default='bf_Model_Bolt'
46 # Head Types
47 Model_Type_List = [('bf_Head_Hex', 'HEX', 'Hex Head'),
48 ('bf_Head_12Pnt', '12 POINT', '12 Point Head'),
49 ('bf_Head_Cap', 'CAP', 'Cap Head'),
50 ('bf_Head_Dome', 'DOME', 'Dome Head'),
51 ('bf_Head_Pan', 'PAN', 'Pan Head'),
52 ('bf_Head_CounterSink', 'COUNTER SINK', 'Counter Sink Head')]
53 bf_Head_Type: EnumProperty(
54 attr='bf_Head_Type',
55 name='Head',
56 description='Choose the type off Head you would like',
57 items=Model_Type_List, default='bf_Head_Hex'
59 # Bit Types
60 Bit_Type_List = [('bf_Bit_None', 'NONE', 'No Bit Type'),
61 ('bf_Bit_Allen', 'ALLEN', 'Allen Bit Type'),
62 ('bf_Bit_Torx', 'TORX', 'Torx Bit Type'),
63 ('bf_Bit_Philips', 'PHILLIPS', 'Phillips Bit Type')]
64 bf_Bit_Type: EnumProperty(
65 attr='bf_Bit_Type',
66 name='Bit Type',
67 description='Choose the type of bit to you would like',
68 items=Bit_Type_List, default='bf_Bit_None'
70 # Nut Types
71 Nut_Type_List = [('bf_Nut_Hex', 'HEX', 'Hex Nut'),
72 ('bf_Nut_Lock', 'LOCK', 'Lock Nut'),
73 ('bf_Nut_12Pnt', '12 POINT', '12 Point Nut')]
74 bf_Nut_Type: EnumProperty(
75 attr='bf_Nut_Type',
76 name='Nut Type',
77 description='Choose the type of nut you would like',
78 items=Nut_Type_List, default='bf_Nut_Hex'
80 # Shank Types
81 bf_Shank_Length: FloatProperty(
82 attr='bf_Shank_Length',
83 name='Shank Length', default=0,
84 min=0, soft_min=0, max=MAX_INPUT_NUMBER,
85 description='Length of the unthreaded shank',
86 unit='LENGTH',
88 bf_Shank_Dia: FloatProperty(
89 attr='bf_Shank_Dia',
90 name='Shank Dia', default=3,
91 min=0, soft_min=0,
92 max=MAX_INPUT_NUMBER,
93 description='Diameter of the shank',
94 unit='LENGTH',
96 bf_Phillips_Bit_Depth: FloatProperty(
97 attr='bf_Phillips_Bit_Depth',
98 name='Bit Depth', default=1.1431535482406616,
99 min=0, soft_min=0,
100 max=MAX_INPUT_NUMBER,
101 description='Depth of the Phillips Bit',
102 unit='LENGTH',
104 bf_Allen_Bit_Depth: FloatProperty(
105 attr='bf_Allen_Bit_Depth',
106 name='Bit Depth', default=1.5,
107 min=0, soft_min=0,
108 max=MAX_INPUT_NUMBER,
109 description='Depth of the Allen Bit',
110 unit='LENGTH',
112 bf_Allen_Bit_Flat_Distance: FloatProperty(
113 attr='bf_Allen_Bit_Flat_Distance',
114 name='Flat Dist', default=2.5,
115 min=0, soft_min=0,
116 max=MAX_INPUT_NUMBER,
117 description='Flat Distance of the Allen Bit',
118 unit='LENGTH',
120 # Torx Size Types
121 Torx_Size_Type_List = [('bf_Torx_T10', 'T10', 'T10'),
122 ('bf_Torx_T20', 'T20', 'T20'),
123 ('bf_Torx_T25', 'T25', 'T25'),
124 ('bf_Torx_T30', 'T30', 'T30'),
125 ('bf_Torx_T40', 'T40', 'T40'),
126 ('bf_Torx_T50', 'T50', 'T50'),
127 ('bf_Torx_T55', 'T55', 'T55'),
130 bf_Torx_Size_Type: EnumProperty(
131 attr='bf_Torx_Size_Type',
132 name='Torx Size',
133 description='Size of the Torx Bit',
134 items=Torx_Size_Type_List, default='bf_Torx_T20'
136 bf_Torx_Bit_Depth: FloatProperty(
137 attr='bf_Torx_Bit_Depth',
138 name='Bit Depth', default=1.5,
139 min=0, soft_min=0,
140 max=MAX_INPUT_NUMBER,
141 description='Depth of the Torx Bit',
142 unit='LENGTH',
144 bf_Hex_Head_Height: FloatProperty(
145 attr='bf_Hex_Head_Height',
146 name='Head Height', default=2,
147 min=0, soft_min=0, max=MAX_INPUT_NUMBER,
148 description='Height of the Hex Head',
149 unit='LENGTH',
151 bf_Hex_Head_Flat_Distance: FloatProperty(
152 attr='bf_Hex_Head_Flat_Distance',
153 name='Flat Dist', default=5.5,
154 min=0, soft_min=0,
155 max=MAX_INPUT_NUMBER,
156 description='Flat Distance of the Hex Head',
157 unit='LENGTH',
159 bf_12_Point_Head_Height: FloatProperty(
160 attr='bf_12_Point_Head_Height',
161 name='Head Height', default=3.0,
162 min=0, soft_min=0, max=MAX_INPUT_NUMBER,
163 description='Height of the 12 Point Head',
164 unit='LENGTH',
166 bf_12_Point_Head_Flat_Distance: FloatProperty(
167 attr='bf_12_Point_Head_Flat_Distance',
168 name='Flat Dist', default=3.0,
169 min=0.001, soft_min=0, #limit to 0.001 to avoid calculation error
170 max=MAX_INPUT_NUMBER,
171 description='Flat Distance of the 12 Point Head',
172 unit='LENGTH',
174 bf_12_Point_Head_Flange_Dia: FloatProperty(
175 attr='bf_12_Point_Head_Flange_Dia',
176 name='12 Point Head Flange Dia', default=5.5,
177 min=0, soft_min=0,
178 max=MAX_INPUT_NUMBER,
179 description='Flange diameter of the 12 point Head',
180 unit='LENGTH',
182 bf_CounterSink_Head_Dia: FloatProperty(
183 attr='bf_CounterSink_Head_Dia',
184 name='Head Dia', default=6.300000190734863,
185 min=0, soft_min=0,
186 max=MAX_INPUT_NUMBER,
187 description='Diameter of the Counter Sink Head',
188 unit='LENGTH',
190 bf_Cap_Head_Height: FloatProperty(
191 attr='bf_Cap_Head_Height',
192 name='Head Height', default=3,
193 min=0, soft_min=0,
194 max=MAX_INPUT_NUMBER,
195 description='Height of the Cap Head',
196 unit='LENGTH',
198 bf_Cap_Head_Dia: FloatProperty(
199 attr='bf_Cap_Head_Dia',
200 name='Head Dia', default=5.5,
201 min=0, soft_min=0,
202 max=MAX_INPUT_NUMBER,
203 description='Diameter of the Cap Head',
204 unit='LENGTH',
206 bf_Dome_Head_Dia: FloatProperty(
207 attr='bf_Dome_Head_Dia',
208 name='Dome Head Dia', default=5.599999904632568,
209 min=0, soft_min=0,
210 max=MAX_INPUT_NUMBER,
211 description='Length of the unthreaded shank',
212 unit='LENGTH',
214 bf_Pan_Head_Dia: FloatProperty(
215 attr='bf_Pan_Head_Dia',
216 name='Pan Head Dia', default=5.599999904632568,
217 min=0, soft_min=0,
218 max=MAX_INPUT_NUMBER,
219 description='Diameter of the Pan Head',
220 unit='LENGTH',
223 bf_Philips_Bit_Dia: FloatProperty(
224 attr='bf_Philips_Bit_Dia',
225 name='Bit Dia', default=1.8199999332427979,
226 min=0, soft_min=0,
227 max=MAX_INPUT_NUMBER,
228 description='Diameter of the Philips Bit',
229 unit='LENGTH',
232 bf_Thread_Length: FloatProperty(
233 attr='bf_Thread_Length',
234 name='Thread Length', default=6,
235 min=0, soft_min=0,
236 max=MAX_INPUT_NUMBER,
237 description='Length of the Thread',
238 unit='LENGTH',
241 bf_Major_Dia: FloatProperty(
242 attr='bf_Major_Dia',
243 name='Major Dia', default=3,
244 min=0, soft_min=0,
245 max=MAX_INPUT_NUMBER,
246 description='Outside diameter of the Thread',
247 unit='LENGTH',
250 bf_Pitch: FloatProperty(
251 attr='bf_Pitch',
252 name='Pitch', default=0.3499999940395355,
253 min=0.1, soft_min=0.1,
254 max=7.0,
255 description='Pitch if the thread',
256 unit='LENGTH',
258 bf_Minor_Dia: FloatProperty(
259 attr='bf_Minor_Dia',
260 name='Minor Dia', default=2.6211137771606445,
261 min=0, soft_min=0,
262 max=MAX_INPUT_NUMBER,
263 description='Inside diameter of the Thread',
264 unit='LENGTH',
266 bf_Crest_Percent: IntProperty(
267 attr='bf_Crest_Percent',
268 name='Crest Percent', default=10,
269 min=1, soft_min=1,
270 max=90,
271 description='Percent of the pitch that makes up the Crest',
273 bf_Root_Percent: IntProperty(
274 attr='bf_Root_Percent',
275 name='Root Percent', default=10,
276 min=1, soft_min=1,
277 max=90,
278 description='Percent of the pitch that makes up the Root',
280 bf_Div_Count: IntProperty(
281 attr='bf_Div_Count',
282 name='Div count', default=36,
283 min=4, soft_min=4,
284 max=4096,
285 description='Div count determine circle resolution',
287 bf_Hex_Nut_Height: FloatProperty(
288 attr='bf_Hex_Nut_Height',
289 name='Hex Nut Height', default=2.4000000953674316,
290 min=0, soft_min=0,
291 max=MAX_INPUT_NUMBER,
292 description='Height of the Hex Nut',
293 unit='LENGTH',
295 bf_Hex_Nut_Flat_Distance: FloatProperty(
296 attr='bf_Hex_Nut_Flat_Distance',
297 name='Hex Nut Flat Dist', default=5.5,
298 min=0, soft_min=0,
299 max=MAX_INPUT_NUMBER,
300 description='Flat distance of the Hex Nut',
301 unit='LENGTH',
303 bf_12_Point_Nut_Height: FloatProperty(
304 attr='bf_12_Point_Nut_Height',
305 name='12 Point Nut Height', default=2.4000000953674316,
306 min=0, soft_min=0,
307 max=MAX_INPUT_NUMBER,
308 description='Height of the 12 Point Nut',
309 unit='LENGTH',
312 bf_12_Point_Nut_Flat_Distance: FloatProperty(
313 attr='bf_12_Point_Nut_Flat_Distance',
314 name='12 Point Nut Flat Dist', default=3.0,
315 min=0.001, soft_min=0, #limit to 0.001 to avoid calculation error
316 max=MAX_INPUT_NUMBER,
317 description='Flat distance of the 12 point Nut',
318 unit='LENGTH',
320 bf_12_Point_Nut_Flange_Dia: FloatProperty(
321 attr='bf_12_Point_Nut_Flange_Dia',
322 name='12 Point Nut Flange Dia', default=5.5,
323 min=0, soft_min=0,
324 max=MAX_INPUT_NUMBER,
325 description='Flange diameter of the 12 point Nut',
326 unit='LENGTH',
328 def draw(self, context):
329 layout = self.layout
330 col = layout.column()
332 # ENUMS
333 col.prop(self, 'bf_Model_Type')
334 col.separator()
336 # Bit
337 if self.bf_Model_Type == 'bf_Model_Bolt':
338 col.prop(self, 'bf_Bit_Type')
339 if self.bf_Bit_Type == 'bf_Bit_None':
340 pass
341 elif self.bf_Bit_Type == 'bf_Bit_Allen':
342 col.prop(self, 'bf_Allen_Bit_Depth')
343 col.prop(self, 'bf_Allen_Bit_Flat_Distance')
344 elif self.bf_Bit_Type == 'bf_Bit_Torx':
345 col.prop(self, 'bf_Torx_Bit_Depth')
346 col.prop(self, 'bf_Torx_Size_Type')
347 elif self.bf_Bit_Type == 'bf_Bit_Philips':
348 col.prop(self, 'bf_Phillips_Bit_Depth')
349 col.prop(self, 'bf_Philips_Bit_Dia')
350 col.separator()
351 # Head
352 if self.bf_Model_Type == 'bf_Model_Bolt':
353 col.prop(self, 'bf_Head_Type')
354 if self.bf_Head_Type == 'bf_Head_Hex':
355 col.prop(self, 'bf_Hex_Head_Height')
356 col.prop(self, 'bf_Hex_Head_Flat_Distance')
357 elif self.bf_Head_Type == 'bf_Head_12Pnt':
358 col.prop(self, 'bf_12_Point_Head_Height')
359 col.prop(self, 'bf_12_Point_Head_Flat_Distance')
360 col.prop(self, 'bf_12_Point_Head_Flange_Dia')
361 elif self.bf_Head_Type == 'bf_Head_Cap':
362 col.prop(self, 'bf_Cap_Head_Height')
363 col.prop(self, 'bf_Cap_Head_Dia')
364 elif self.bf_Head_Type == 'bf_Head_Dome':
365 col.prop(self, 'bf_Dome_Head_Dia')
366 elif self.bf_Head_Type == 'bf_Head_Pan':
367 col.prop(self, 'bf_Pan_Head_Dia')
368 elif self.bf_Head_Type == 'bf_Head_CounterSink':
369 col.prop(self, 'bf_CounterSink_Head_Dia')
370 col.separator()
371 # Shank
372 if self.bf_Model_Type == 'bf_Model_Bolt':
373 col.label(text='Shank')
374 col.prop(self, 'bf_Shank_Length')
375 col.prop(self, 'bf_Shank_Dia')
376 col.separator()
377 # Nut
378 if self.bf_Model_Type == 'bf_Model_Nut':
379 col.prop(self, 'bf_Nut_Type')
380 if self.bf_Nut_Type == "bf_Nut_12Pnt":
381 col.prop(self, 'bf_12_Point_Nut_Height')
382 col.prop(self, 'bf_12_Point_Nut_Flat_Distance')
383 col.prop(self, 'bf_12_Point_Nut_Flange_Dia')
384 else:
385 col.prop(self, 'bf_Hex_Nut_Height')
386 col.prop(self, 'bf_Hex_Nut_Flat_Distance')
390 # Thread
391 col.label(text='Thread')
392 if self.bf_Model_Type == 'bf_Model_Bolt':
393 col.prop(self, 'bf_Thread_Length')
394 col.prop(self, 'bf_Major_Dia')
395 col.prop(self, 'bf_Minor_Dia')
396 col.prop(self, 'bf_Pitch')
397 col.prop(self, 'bf_Crest_Percent')
398 col.prop(self, 'bf_Root_Percent')
399 col.prop(self, 'bf_Div_Count')
401 if self.change == False:
402 # generic transform props
403 col.separator()
404 col.prop(self, 'align')
405 col.prop(self, 'location')
406 col.prop(self, 'rotation')
408 @classmethod
409 def poll(cls, context):
410 return context.scene is not None
412 def execute(self, context):
414 if bpy.context.mode == "OBJECT":
415 if context.selected_objects != [] and context.active_object and \
416 (context.active_object.data is not None) and ('Bolt' in context.active_object.data.keys()) and \
417 (self.change == True):
418 obj = context.active_object
419 use_auto_smooth = bool(obj.data.use_auto_smooth) # Copy value, do not take a reference
420 use_smooth = bool(obj.data.polygons[0].use_smooth) # Copy value, do not take a reference
422 mesh = createMesh.Create_New_Mesh(self, context)
424 # Modify existing mesh data object by replacing geometry (but leaving materials etc)
425 bm = bmesh.new()
426 bm.from_mesh(mesh)
427 bm.to_mesh(obj.data)
428 bm.free()
430 # Preserve flat/smooth choice. New mesh is flat by default
431 obj.data.use_auto_smooth = use_auto_smooth
432 if use_smooth:
433 bpy.ops.object.shade_smooth()
435 bpy.data.meshes.remove(mesh)
437 try:
438 bpy.ops.object.vertex_group_remove(all=True)
439 except:
440 pass
442 else:
443 mesh = createMesh.Create_New_Mesh(self, context)
444 obj = object_utils.object_data_add(context, mesh, operator=self)
446 obj.data["Bolt"] = True
447 obj.data["change"] = False
448 for prm in BoltParameters():
449 obj.data[prm] = getattr(self, prm)
451 if bpy.context.mode == "EDIT_MESH":
452 obj = context.edit_object
453 mesh = createMesh.Create_New_Mesh(self, context)
455 bm = bmesh.from_edit_mesh(obj.data) # Access edit mode's mesh data
456 bm.from_mesh(mesh) # Append new mesh data
457 bmesh.update_edit_mesh(obj.data) # Flush changes (update edit mode's view)
459 bpy.data.meshes.remove(mesh) # Remove temporary mesh
461 return {'FINISHED'}
463 def invoke(self, context, event):
464 self.execute(context)
466 return {'FINISHED'}
468 # Register:
469 def Bolt_contex_menu(self, context):
470 bl_label = 'Change'
472 obj = context.object
473 layout = self.layout
475 if obj.data is not None and 'Bolt' in obj.data.keys():
476 props = layout.operator("mesh.bolt_add", text="Change Bolt")
477 props.change = True
478 for prm in BoltParameters():
479 setattr(props, prm, obj.data[prm])
480 layout.separator()
482 def menu_func_bolt(self, context):
483 layout = self.layout
484 layout.separator()
485 oper = self.layout.operator(add_mesh_bolt.bl_idname, text="Bolt", icon="MOD_SCREW")
486 oper.change = False
488 classes = (
489 add_mesh_bolt,
494 def register():
495 for cls in classes:
496 bpy.utils.register_class(cls)
497 bpy.types.VIEW3D_MT_mesh_add.append(menu_func_bolt)
498 bpy.types.VIEW3D_MT_object_context_menu.prepend(Bolt_contex_menu)
501 def unregister():
502 bpy.types.VIEW3D_MT_object_context_menu.remove(Bolt_contex_menu)
503 bpy.types.VIEW3D_MT_mesh_add.remove(menu_func_bolt)
504 for cls in reversed(classes):
505 bpy.utils.unregister_class(cls)
507 def BoltParameters():
508 BoltParameters = [
509 "bf_Model_Type",
510 "bf_Head_Type",
511 "bf_Bit_Type",
512 "bf_Nut_Type",
513 "bf_Shank_Length",
514 "bf_Shank_Dia",
515 "bf_Phillips_Bit_Depth",
516 "bf_Allen_Bit_Depth",
517 "bf_Allen_Bit_Flat_Distance",
518 "bf_Torx_Bit_Depth",
519 "bf_Torx_Size_Type",
520 "bf_Hex_Head_Height",
521 "bf_Hex_Head_Flat_Distance",
522 "bf_CounterSink_Head_Dia",
523 "bf_Cap_Head_Height",
524 "bf_Cap_Head_Dia",
525 "bf_Dome_Head_Dia",
526 "bf_Pan_Head_Dia",
527 "bf_Philips_Bit_Dia",
528 "bf_Thread_Length",
529 "bf_Major_Dia",
530 "bf_Pitch",
531 "bf_Minor_Dia",
532 "bf_Crest_Percent",
533 "bf_Root_Percent",
534 "bf_Div_Count",
535 "bf_Hex_Nut_Height",
536 "bf_Hex_Nut_Flat_Distance",
538 return BoltParameters