-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathThreadMeister.py
More file actions
100 lines (81 loc) · 3.23 KB
/
ThreadMeister.py
File metadata and controls
100 lines (81 loc) · 3.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
"""
ThreadMeister – Heat-set Insert Creator for Fusion 360
Copyright (c) 2026 Andreas Kircher
SPDX-License-Identifier: MIT
This add-in automates the creation of heat-set insert holes for 3D printing,
using the dimensional specifications from CNC Kitchen.
Author: Andreas Kircher (Andreas.O.Kircher@gmail.com)
Created with assistance from: Claude (Anthropic) / Perplexity
Insert specifications from: CNC Kitchen (cnckitchen.com)
Version: 1.2.2
Features:
- Creates heat-set insert holes at sketch points
- Hole creation with CNC Kitchen specifications (M2-M10, 1/4"-20) – customizable via config.ini
- Blind holes and through holes
- Automatic chamfer for easier insert installation
- Automatic bottom radius for blind holes
- Timeline grouping for easy management
- Direct subtraction from target body
- Clean temp sketch approach for reliable profile selection
Usage:
1. Create a sketch with points where you want insert holes
2. Click "ThreadMeister" button in SOLID > MODIFY menu
3. Select target body and sketch points
4. Choose insert size and options
5. Done!
Known Issues:
- Not tested with Apple macOS
- Overlapping bores may cause incomplete extrusions (no chamfer/radius)
"""
import traceback
import os
import sys
# Add the add-in directory to sys.path so local modules are importable
_addin_path = os.path.dirname(os.path.realpath(__file__))
if _addin_path not in sys.path:
sys.path.insert(0, _addin_path)
# Add the core subdirectory to sys.path for module imports
_core_path = os.path.join(_addin_path, 'core')
if _core_path not in sys.path:
sys.path.insert(0, _core_path)
import tm_state
import tm_config
from tm_ui import CommandCreatedHandler
def run(context):
"""Called when the add-in is loaded."""
try:
tm_config.load_config()
cmdDefs = tm_state._ui.commandDefinitions
addon_path = os.path.dirname(os.path.realpath(__file__))
resources_path = os.path.join(addon_path, 'resources', 'icons')
buttonDef = cmdDefs.addButtonDefinition(
tm_state.CMD_ID,
tm_state.CMD_NAME,
tm_state.CMD_Description,
resources_path
)
onCommandCreated = CommandCreatedHandler()
buttonDef.commandCreated.add(onCommandCreated)
tm_state._handlers.append(onCommandCreated)
panel = tm_state._ui.allToolbarPanels.itemById(tm_state.PANEL_ID)
if panel:
buttonControl = panel.controls.addCommand(buttonDef)
buttonControl.isPromoted = True
buttonControl.isPromotedByDefault = True
else:
tm_state._ui.messageBox(f'Could not find panel: {tm_state.PANEL_ID}')
except Exception:
tm_state._ui.messageBox('Failed to load add-in:\n{}'.format(traceback.format_exc()))
def stop(context):
"""Called when the add-in is unloaded."""
try:
cmdDef = tm_state._ui.commandDefinitions.itemById(tm_state.CMD_ID)
if cmdDef:
cmdDef.deleteMe()
panel = tm_state._ui.allToolbarPanels.itemById(tm_state.PANEL_ID)
if panel:
control = panel.controls.itemById(tm_state.CMD_ID)
if control:
control.deleteMe()
except Exception:
tm_state._ui.messageBox('Failed to stop add-in:\n{}'.format(traceback.format_exc()))