-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy paththreading_tool.py
More file actions
146 lines (121 loc) · 8.03 KB
/
threading_tool.py
File metadata and controls
146 lines (121 loc) · 8.03 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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
from guifw.abstractparameters import *
from gcode import *
from collections import OrderedDict
class ThreadingTool(ItemWithParameters):
def __init__(self, path=[], model=None, viewUpdater=None, tool=None, **kwargs):
ItemWithParameters.__init__(self, **kwargs)
self.viewUpdater = viewUpdater
self.path = GCode()
self.tool = tool[0]
self.millingDirection = ChoiceParameter(parent=self, name="Milling direction", choices=["CW top-down (RH)", "CCW bottom-up (RH)", "CCW top-down (LH)", "CW bottom-up (LH)"], value="CW top-down (RH)", callback = self.generatePath)
self.presets = OrderedDict([("M3",[3, 0.5, 0, 2.0]),
("M4",[4, 0.7, 0, 2.0]),
("M5",[5, 0.8, 0, 4.0]),
("M6",[6, 1, 0, 4.0]),
("M8",[8, 1.25, 0, 4.0]),
("M10",[10, 1.5, 0, 4.0]),
("NPT 1/8",[0.38*25.4, 1.0/27.0*25.4, 1.7899, 4.0]),
("NPT 1/4", [0.50250 * 25.4, 1.0 / 18.0 * 25.4, 1.7899, 4.0])])
self.presetParameter = ChoiceParameter(parent=self, name="Presets", choices=self.presets.keys(), value = "M6", callback = self.loadPreset)
self.startDepth=NumericalParameter(parent=self, name='start depth', value=0, enforceRange=False, step=0.1, callback = self.generatePath)
self.stopDepth=NumericalParameter(parent=self, name='end depth ', value=-10, enforceRange=False, step=0.1, callback = self.generatePath)
self.xpos = NumericalParameter(parent=self, name='x ', value=0, min=-2000, max=2000, enforceRange=False, step=0.1, callback = self.generatePath)
self.ypos = NumericalParameter(parent=self, name='y ', value=0, min=-2000, max=2000, enforceRange=False, step=0.1, callback = self.generatePath)
self.startDiameter = NumericalParameter(parent=self, name='start diameter ', value=8, min=0, max=1000, enforceRange=False, step=0.1, callback = self.generatePath)
self.diameter = NumericalParameter(parent=self, name='final diameter ', value=8, min=0, max=1000, enforceRange=False, step=0.1, callback = self.generatePath)
self.diameterSteps = NumericalParameter(parent=self, name='diameter steps ', value=0, min=0, max=10, step=1, callback = self.generatePath)
self.pitch=NumericalParameter(parent=self, name='thread pitch', value=1.0, min=0.01, max=5, step=0.01, callback = self.generatePath)
self.toolDiameter=NumericalParameter(parent=self, name='tool tip diameter', value=4.0, min=0, max=20, step=0.1, callback = self.generatePath)
self.coneAngle=NumericalParameter(parent=self, name='cone angle', value=0.0, min=-89.9, max=89.9, step=0.1, callback = self.generatePath)
self.backoffPercentage=NumericalParameter(parent=self, name='backoff percentage', value=100.0, min=-30, max=100, enforceRange=False, step=5, callback = self.generatePath)
self.traverseHeight=NumericalParameter(parent=self, name='traverse height', value=5.0, enforceRange=False, step=1.0, callback = self.generatePath)
self.filename=TextParameter(parent=self, name="output filename", value="thread.ngc")
self.saveButton=ActionParameter(parent=self, name='Save to file', callback=self.save)
self.feedrate=NumericalParameter(parent=self, name='default feedrate', value=400.0, min=1, max=5000, step=10)
self.parameters=[self.millingDirection, self.presetParameter, [ self.xpos, self.ypos], self.startDepth, self.stopDepth, self.startDiameter, self.diameter, self.diameterSteps, self.pitch, self.toolDiameter, self.coneAngle, self.backoffPercentage, self.traverseHeight, self.feedrate, [self.filename, self.saveButton] ]
self.generatePath(None)
def setThread(self, diameter, pitch, angle, tool):
self.diameter.updateValue(diameter)
#self.diameter.viewRefresh()
self.pitch.updateValue(pitch)
#self.pitch.viewRefresh()
self.coneAngle.updateValue(angle)
#self.coneAngle.viewRefresh()
self.toolDiameter.updateValue(tool)
#self.toolDiameter.viewRefresh()
self.generatePath(None)
def loadPreset(self, parameter):
params = self.presets[parameter.value]
self.setThread(*params)
def generatePath(self, parameter=None):
self.path.outpaths=[]
path = []
cx=self.xpos.getValue()
cy=self.ypos.getValue()
pos = [cx, cy, 0]
start_depth = self.startDepth.getValue()
final_depth = self.stopDepth.getValue()
stepdown = self.pitch.getValue()
tool_radius = self.toolDiameter.getValue()/2.0
traverse_height=self.traverseHeight.getValue()
backoff_percentage=self.backoffPercentage.getValue()/100.0
hole_diameter = self.diameter.getValue()
hole_radius=self.startDiameter.getValue()/2.0
if self.diameterSteps.getValue()==0:
hole_radius = hole_diameter/2.0
cone_angle = self.coneAngle.getValue()/180.0*PI
angle_steps=200
lefthand = self.millingDirection.getValue() in [ "CCW top-down (LH)", "CW bottom-up (LH)"]
bottomup = self.millingDirection.getValue() in ["CCW bottom-up (RH)", "CW bottom-up (LH)"]
for cycles in range(0, int(self.diameterSteps.getValue())+1):
d=start_depth
x=pos[0]; y=pos[1]+hole_radius-tool_radius; z=0.0;
x=(1.0-backoff_percentage)*x + backoff_percentage*pos[0]
y=(1.0-backoff_percentage)*y + backoff_percentage*pos[1]
path.append(GPoint(position=([x, y, traverse_height]), rapid=True))
z=start_depth
path.append(GPoint(position=([x,y,z])))
while d>final_depth:
for i in range(0,angle_steps+1):
if d>final_depth:
d-=stepdown/angle_steps
else:
d=final_depth
break
x=pos[0]+ (hole_radius-tool_radius+(d-start_depth)*sin(cone_angle)/cos(cone_angle)) *sin((float(i)/angle_steps)*2*PI)
y=pos[1]+ (hole_radius-tool_radius+(d-start_depth)*sin(cone_angle)/cos(cone_angle)) *cos((float(i)/angle_steps)*2*PI)
z=d
if lefthand:
x=-x
path.append(GPoint(position=([x,y,z])))
# for i in range(0,angle_steps+1):
# if d>final_depth:
# d-=stepdown/angle_steps
# else:
# d=final_depth
# x=pos[0]+ (hole_radius-tool_radius+(d-start_depth)*sin(cone_angle)) *sin((float(i)/angle_steps)*2*PI)
# y=pos[1]+ (hole_radius-tool_radius+(d-start_depth)*sin(cone_angle)) *cos((float(i)/angle_steps)*2*PI)
# z=d
# path.append([x,y,z])
x=(1.0-backoff_percentage)*x + backoff_percentage*pos[0]
y=(1.0-backoff_percentage)*y + backoff_percentage*pos[1]
#z=(1.0-backoff_percentage)*z + backoff_percentage*traverse_height
path.append(GPoint(position=([x,y,z])))
path.append(GPoint(position=([x,y,traverse_height]), rapid=True))
if bottomup:
path.reverse()
self.path.path = path
path=[]
if self.diameterSteps.getValue()>0:
hole_radius+=(hole_diameter-self.startDiameter.getValue())/self.diameterSteps.getValue() / 2.0
if cycles == int(self.diameterSteps.getValue()):
hole_radius = hole_diameter/2.0
if self.viewUpdater!=None:
print("updating view")
self.viewUpdater(self.path)
def getCompletePath(self):
self.generatePath()
return self.path
def save(self):
self.path.default_feedrate=self.feedrate.getValue()
self.path.write(self.filename.getValue())