-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathProfile.py
More file actions
459 lines (400 loc) · 20.9 KB
/
Profile.py
File metadata and controls
459 lines (400 loc) · 20.9 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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
from SketchOp import SketchOp
import geom
import cad
import Tool
from Object import PyChoiceProperty
from Object import PyProperty
from Object import PyPropertyLength
from SpeedOp import SpeedOp
import wx
from nc.nc import *
import kurve_funcs
from HeeksConfig import HeeksConfig
import Tags
import Tag
import math
from Drawing import Drawing
from consts import *
PROFILE_RIGHT_OR_INSIDE = -1
PROFILE_ON = 0
PROFILE_LEFT_OR_OUTSIDE = 1
PROFILE_CONVENTIONAL = 0
PROFILE_CLIMB = 1
type = 0
class Profile(SketchOp):
def __init__(self, sketch = 0):
SketchOp.__init__(self, sketch)
self.tool_on_side = PROFILE_LEFT_OR_OUTSIDE
self.cut_mode = PROFILE_CLIMB
self.auto_roll_radius = 2.0
self.auto_roll_on = True
self.auto_roll_off = True
self.roll_on_point = geom.Point3D(0,0,0)
self.roll_off_point = geom.Point3D(0,0,0)
self.start_given = False
self.end_given = False
self.start = geom.Point3D(0,0,0)
self.end = geom.Point3D(0,0,0)
self.sort_sketches = True
self.tags = None
self.offset_extra = 0.0
self.do_finishing_pass = False
self.only_finishing_pass = False
self.finishing_h_feed_rate = 100.0
self.finishing_cut_mode = PROFILE_CONVENTIONAL
self.finishing_step_down = 1.0
self.end_beyond_full_profile = False
self.extend_at_start = 0.0
self.extend_at_end = 0.0
self.lead_in_line_len = 0.0
self.lead_out_line_len = 0.0
def TypeName(self):
return "Profile"
def GetType(self):
return type
def op_icon(self):
# the name of the PNG file in the HeeksCNC icons folder
return "profile"
def HasEdit(self):
return True
def Edit(self):
import ProfileDlg
res = ProfileDlg.Do(self)
return res
def MakeACopy(self):
copy = Profile(self.sketch)
cad.PyIncref(copy)
copy.CopyFrom(self)
return copy
def CopyFrom(self, object):
SketchOp.CopyFrom(self, object)
self.tool_on_side = object.tool_on_side
self.cut_mode = object.cut_mode
self.auto_roll_radius = object.auto_roll_radius
self.auto_roll_on = object.auto_roll_on
self.auto_roll_off = object.auto_roll_off
self.roll_on_point = object.roll_on_point
self.roll_off_point = object.roll_off_point
self.start_given = object.start_given
self.end_given = object.end_given
self.start = object.start
self.end = object.end
self.extend_at_start = object.extend_at_start
self.extend_at_end = object.extend_at_end
self.lead_in_line_len = object.lead_in_line_len
self.lead_out_line_len = object.lead_out_line_len
self.end_beyond_full_profile = object.end_beyond_full_profile
self.sort_sketches = object.sort_sketches
self.offset_extra = object.offset_extra
self.do_finishing_pass = object.do_finishing_pass
self.only_finishing_pass = object.only_finishing_pass
self.finishing_h_feed_rate = object.finishing_h_feed_rate
self.finishing_cut_mode = object.finishing_cut_mode
self.finishing_step_down = object.finishing_step_down
def WriteXml(self):
cad.BeginXmlChild('params')
cad.SetXmlValue('side', self.tool_on_side)
cad.SetXmlValue('cut_mode', self.cut_mode)
cad.SetXmlValue('auto_roll_on', self.auto_roll_on)
if not self.auto_roll_on:
cad.SetXmlValue('roll_onx', self.roll_on_point.x)
cad.SetXmlValue('roll_ony', self.roll_on_point.y)
cad.SetXmlValue('roll_onz', self.roll_on_point.z)
cad.SetXmlValue('auto_roll_off', self.auto_roll_off)
if not self.auto_roll_off:
cad.SetXmlValue('roll_offx', self.roll_off_point.x)
cad.SetXmlValue('roll_offy', self.roll_off_point.y)
cad.SetXmlValue('roll_offz', self.roll_off_point.z)
if self.auto_roll_on or self.auto_roll_off:
cad.SetXmlValue('roll_radius', self.auto_roll_radius)
cad.SetXmlValue('start_given', self.start_given)
if self.start_given:
cad.SetXmlValue('startx', self.start.x)
cad.SetXmlValue('starty', self.start.y)
cad.SetXmlValue('startz', self.start.z)
cad.SetXmlValue('end_given', self.end_given)
if self.end_given:
cad.SetXmlValue('endx', self.end.x)
cad.SetXmlValue('endy', self.end.y)
cad.SetXmlValue('endz', self.end.z)
cad.SetXmlValue('end_beyond_full_profile', self.end_beyond_full_profile)
cad.SetXmlValue('sort_sketches', self.sort_sketches)
cad.SetXmlValue('extend_at_start', self.extend_at_start)
cad.SetXmlValue('extend_at_end', self.extend_at_end)
cad.SetXmlValue('lead_in_line_len', self.lead_in_line_len)
cad.SetXmlValue('lead_out_line_len', self.lead_out_line_len)
cad.SetXmlValue('offset_extra', self.offset_extra)
cad.SetXmlValue('do_finishing_pass', self.do_finishing_pass)
cad.SetXmlValue('only_finishing_pass', self.only_finishing_pass)
cad.SetXmlValue('finishing_feed_rate', self.finishing_h_feed_rate)
cad.SetXmlValue('finish_cut_mode', self.finishing_cut_mode)
cad.SetXmlValue('finishing_step_down', self.finishing_step_down)
cad.EndXmlChild()
SketchOp.WriteXml(self)
def ReadXml(self):
child_element = cad.GetFirstXmlChild()
while child_element != None:
if child_element == 'params':
self.tool_on_side = cad.GetXmlInt('side', self.tool_on_side)
self.cut_mode = cad.GetXmlInt('cut_mode', self.cut_mode)
self.auto_roll_on = cad.GetXmlBool('auto_roll_on', self.auto_roll_on)
self.roll_on_point.x = cad.GetXmlFloat('roll_onx', self.roll_on_point.x)
self.roll_on_point.y = cad.GetXmlFloat('roll_ony', self.roll_on_point.y)
self.roll_on_point.z = cad.GetXmlFloat('roll_onz', self.roll_on_point.z)
self.auto_roll_off = cad.GetXmlBool('auto_roll_off', self.auto_roll_off)
self.roll_off_point.x = cad.GetXmlFloat('roll_offx', self.roll_off_point.x)
self.roll_off_point.y = cad.GetXmlFloat('roll_offy', self.roll_off_point.y)
self.roll_off_point.z = cad.GetXmlFloat('roll_offz', self.roll_off_point.z)
self.auto_roll_radius = cad.GetXmlFloat('roll_radius', self.auto_roll_radius)
self.start_given = cad.GetXmlBool('start_given', self.start_given)
self.start.x = cad.GetXmlFloat('startx', self.start.x)
self.start.y = cad.GetXmlFloat('starty', self.start.y)
self.start.z = cad.GetXmlFloat('startz', self.start.z)
self.end_given = cad.GetXmlBool('end_given', self.end_given)
self.end.x = cad.GetXmlFloat('endx', self.end.x)
self.end.y = cad.GetXmlFloat('endy', self.end.y)
self.end.z = cad.GetXmlFloat('endz', self.end.z)
self.end_beyond_full_profile = cad.GetXmlBool('end_beyond_full_profile', self.end_beyond_full_profile)
self.sort_sketches = cad.GetXmlBool('sort_sketches', self.sort_sketches)
self.offset_extra = cad.GetXmlFloat('offset_extra', self.offset_extra)
self.do_finishing_pass = cad.GetXmlBool('do_finishing_pass', self.do_finishing_pass)
self.only_finishing_pass = cad.GetXmlBool('only_finishing_pass', self.only_finishing_pass)
self.finishing_h_feed_rate = cad.GetXmlFloat('finishing_feed_rate', self.finishing_h_feed_rate)
self.finishing_cut_mode = cad.GetXmlInt('finish_cut_mode', self.finishing_cut_mode)
self.finishing_step_down = cad.GetXmlFloat('finishing_step_down', self.finishing_step_down)
self.extend_at_start = cad.GetXmlFloat('extend_at_start', self.extend_at_start)
self.extend_at_end = cad.GetXmlFloat('extend_at_end', self.extend_at_end)
self.lead_in_line_len = cad.GetXmlFloat('lead_in_line_len', self.lead_in_line_len)
self.lead_out_line_len = cad.GetXmlFloat('lead_out_line_len', self.lead_out_line_len)
if child_element == 'Tags':
self.tags = cad.GetXmlObject()
self.Add(self.tags)
child_element = cad.GetNextXmlChild()
SketchOp.ReadXml(self)
def ReadDefaultValues(self):
SketchOp.ReadDefaultValues(self)
config = HeeksConfig()
self.tool_on_side = config.ReadInt("ToolOnSide", PROFILE_LEFT_OR_OUTSIDE)
self.cut_mode = config.ReadInt("CutMode", PROFILE_CLIMB)
self.auto_roll_radius = config.ReadFloat("RollRadius", 2.0)
self.offset_extra = config.ReadFloat("OffsetExtra", 0.0)
self.do_finishing_pass = config.ReadBool("DoFinishPass", False)
self.only_finishing_pass = config.ReadBool("OnlyFinishPass", False)
self.finishing_h_feed_rate = config.ReadFloat("FinishFeedRate", 100.0)
self.finishing_cut_mode = config.ReadInt("FinishCutMode", PROFILE_CONVENTIONAL)
self.finishing_step_down = config.ReadFloat("FinishStepDown", 1.0)
self.end_beyond_full_profile = config.ReadBool("EndBeyond", False)
self.extend_at_start = config.ReadFloat("ExtendAtStart", 0.0)
self.extend_at_end = config.ReadFloat("ExtendAtEnd", 0.0)
self.lead_in_line_len = config.ReadFloat("LeadInLineLen", 0.0)
self.lead_out_line_len = config.ReadFloat("LeadOutLineLen", 0.0)
self.SetDefaultTool(TOOL_TYPE_SLOTCUTTER)
def WriteDefaultValues(self):
SketchOp.WriteDefaultValues(self)
config = HeeksConfig()
config.WriteInt("ToolOnSide", self.tool_on_side)
config.WriteInt("CutMode", self.cut_mode)
config.WriteFloat("RollRadius", self.auto_roll_radius)
config.WriteFloat("OffsetExtra", self.offset_extra)
config.WriteBool("DoFinishPass", self.do_finishing_pass)
config.WriteBool("OnlyFinishPass", self.only_finishing_pass)
config.WriteFloat("FinishFeedRate", self.finishing_h_feed_rate)
config.WriteInt("FinishCutMode", self.finishing_cut_mode)
config.WriteFloat("FinishStepDown", self.finishing_step_down)
config.WriteBool("EndBeyond", self.end_beyond_full_profile)
config.WriteFloat("ExtendAtStart", self.extend_at_start)
config.WriteFloat("ExtendAtEnd", self.extend_at_end)
config.WriteFloat("LeadInLineLen", self.lead_in_line_len)
config.WriteFloat("LeadOutLineLen", self.lead_out_line_len)
def GetProperties(self):
properties = []
sketch_order = cad.SketchOrderType.SketchOrderTypeUnknown
sketch_object = cad.GetObjectFromId(cad.OBJECT_TYPE_SKETCH, self.sketch)
if sketch_object != None:
sketch_order = sketch_object.GetSketchOrder()
choices = []
if sketch_order == cad.SketchOrderType.SketchOrderTypeOpen:
choices.append('Left')
choices.append('Right')
elif sketch_order == cad.SketchOrderType.SketchOrderTypeCloseCW or sketch_order == cad.SketchOrderType.SketchOrderTypeCloseCCW:
choices.append('Outside')
choices.append('Inside')
else:
choices.append('Outside or Left')
choices.append('Inside or Right')
choices.append('On')
choice = 0
if self.tool_on_side == PROFILE_RIGHT_OR_INSIDE:
choice = 1
elif self.tool_on_side == PROFILE_LEFT_OR_OUTSIDE:
choice = 2
properties.append(PyChoiceProperty("Tool On Side", 'tool_on_side', choices, self, alternative_values = [PROFILE_LEFT_OR_OUTSIDE, PROFILE_RIGHT_OR_INSIDE, PROFILE_ON]))
properties.append(PyChoiceProperty("Cut Mode", 'cut_mode', ['Conventional', 'Climb'], self))
properties.append(PyProperty("Auto Roll On", 'auto_roll_on', self))
properties.append(PyProperty("Roll On Point", 'roll_on_point', self))
properties.append(PyProperty("Auto Roll Off", 'auto_roll_off', self))
properties.append(PyProperty("Roll Off Point", 'roll_off_point', self))
properties.append(PyPropertyLength("Roll Radius", 'auto_roll_radius', self))
properties.append(PyProperty("Use Start Point", 'start_given', self))
properties.append(PyProperty("Start Point", 'start', self))
properties.append(PyProperty("Use End Point", 'end_given', self))
properties.append(PyProperty("End Point", 'end', self))
properties.append(PyProperty("End Beyond Full Profile", 'end_beyond_full_profile', self))
properties.append(PyPropertyLength("Extend Before Start", 'extend_at_start', self))
properties.append(PyPropertyLength("Extend Past End", 'extend_at_end', self))
properties.append(PyPropertyLength("Lead In Line Length", 'lead_in_line_len', self))
properties.append(PyPropertyLength("Lead Out Line Length", 'lead_out_line_len', self))
properties.append(PyPropertyLength("Offset Extra", 'offset_extra', self))
properties.append(PyProperty("Do Finishing Pass", 'do_finishing_pass', self))
properties.append(PyProperty("Only Finishing Pass", 'only_finishing_pass', self))
properties.append(PyProperty("Finishing Feed Rate", 'finishing_h_feed_rate', self))
properties.append(PyChoiceProperty("Finish Cut Mode", 'finishing_cut_mode', ['Conventional', 'Climb'], self))
properties.append(PyPropertyLength("Finishing Step Down", 'finishing_step_down', self))
properties += SketchOp.GetProperties(self)
return properties
def DoGCodeCallsForSketch(self, object, data):
cut_mode, depth_params, tool_diameter, roll_radius, offset_extra, cutting_edge_angle = data
# decide if we need to reverse the kurve
direction_reversed = False
initially_ccw = False
if self.tool_on_side != PROFILE_ON:
if object.GetType() == cad.OBJECT_TYPE_CIRCLE:
initially_ccw = True
if object.GetType() == cad.OBJECT_TYPE_SKETCH:
order = object.GetSketchOrder()
if order == cad.SketchOrderType.SketchOrderTypeCloseCCW:
initially_ccw = True
if self.spindle_speed<0:direction_reversed = not direction_reversed
if cut_mode == PROFILE_CONVENTIONAL: direction_reversed = not direction_reversed
if self.tool_on_side == PROFILE_RIGHT_OR_INSIDE: direction_reversed = not direction_reversed
curve = object.GetCurve()
if self.start_given or self.end_given:
start = None
if self.start_given:
start = geom.Point(self.start.x, self.start.y)
end = None
end_beyond = False
if self.end_given:
end = geom.Point(self.end.x, self.end.y)
end_beyond = self.end_beyond_full_profile
kurve_funcs.make_smaller(curve, start, end, end_beyond)
if curve.NumVertices() <= 1:
raise NameError("sketch has no spans! object = " + object.GetTitle() + ' curve = ' + str(curve))
if initially_ccw != direction_reversed:
curve.Reverse()
if ( not self.start_given ) and ( not self.end_given ):
kurve_funcs.set_good_start_point(curve, direction_reversed)
# start - assume we are at a suitable clearance height
# get offset side string
side_string = 'on'
if self.tool_on_side == PROFILE_LEFT_OR_OUTSIDE:
side_string = 'right' if direction_reversed else 'left'
elif self.tool_on_side == PROFILE_RIGHT_OR_INSIDE:
side_string = 'left' if direction_reversed else 'right'
# roll on
if self.tool_on_side == PROFILE_LEFT_OR_OUTSIDE or self.tool_on_side == PROFILE_RIGHT_OR_INSIDE:
if self.auto_roll_on:
roll_on = 'auto'
else:
roll_on = geom.Point(self.roll_on_point.x/wx.GetApp().program.units, self.roll_on_point.ywx.GetApp().program.units)
else:
roll_on = None
# roll off
if self.tool_on_side == PROFILE_LEFT_OR_OUTSIDE or self.tool_on_side == PROFILE_RIGHT_OR_INSIDE:
if self.auto_roll_off:
roll_off = 'auto'
else:
roll_off = geom.Point(self.roll_off_point.x/wx.GetApp().program.units, self.roll_off_point.ywx.GetApp().program.units)
else:
roll_off = None
tags_cleared = False
for tag in self.GetTags():
if not tags_cleared:
kurve_funcs.clear_tags()
tags_cleared = True
kurve_funcs.add_tag(geom.Point(tag.pos.x / wx.GetApp().program.units, tag.pos.y / wx.GetApp().program.units), tag.width / wx.GetApp().program.units, tag.angle * math.pi / 180.0, tag.height / wx.GetApp().program.units)
# extend_at_start, extend_at_end
extend_at_start = self.extend_at_start / wx.GetApp().program.units
extend_at_end = self.extend_at_end / wx.GetApp().program.units
# lead in lead out line length
lead_in_line_len = self.lead_in_line_len / wx.GetApp().program.units
lead_out_line_len = self.lead_out_line_len / wx.GetApp().program.units
# profile the kurve
kurve_funcs.profile(curve, side_string, tool_diameter / 2, offset_extra, roll_radius, roll_on, roll_off, depth_params, extend_at_start,extend_at_end,lead_in_line_len,lead_out_line_len)
# do we need this here
absolute()
def DoGCodeCallsForPass(self, finishing_pass):
failure = self.CheckToolExists()
if failure: return failure
tool = Tool.FindTool(self.tool_number)
depthparams = self.GetDepthParams()
if not finishing_pass or self.only_finishing_pass:
SpeedOp.DoGCodeCalls(self)
if self.auto_roll_on or self.auto_roll_off:
roll_radius = self.auto_roll_radius / wx.GetApp().program.units
else:
roll_radius = None
depth_params = self.GetDepthParams()
tool_diameter = tool.CuttingRadius(True) * 2.0
cutting_edge_angle = tool.cutting_edge_angle
if finishing_pass:
feedrate_hv(self.finishing_h_feed_rate / wx.GetApp().program.units, self.vertical_feed_rate / wx.GetApp().program.units)
flush_nc()
offset_extra = 0.0
depth_params.step_down = self.finishing_step_down
depth_params.z_finish_depth = 0.0
else:
offset_extra = self.offset_extra / wx.GetApp().program.units
cut_mode = self.finishing_cut_mode if finishing_pass else self.cut_mode
self.DoEachSketch(self.DoGCodeCallsForSketch, (cut_mode, depth_params, tool_diameter, roll_radius, offset_extra, cutting_edge_angle))
def GetTags(self):
if self.tags == None:
return []
else:
return self.tags.GetChildren()
def DoGCodeCalls(self):
# roughing pass
if not self.do_finishing_pass or not self.only_finishing_pass:
self.DoGCodeCallsForPass(False)
# finishing pass
if self.do_finishing_pass:
self.DoGCodeCallsForPass(True)
def AddMissingChildren(self):
# add tags
self.tags = Tags.Tags()
self.Add(self.tags)
def OnGlCommands(self, select, marked, no_color):
if self.tags:
if cad.ObjectMarked(self.tags):
marked = True
object = self.tags.GetFirstChild()
while object:
object_marked = cad.ObjectMarked(object)
object.OnGlCommands(select, marked or object_marked, no_color)
object = self.tags.GetNextChild()
SketchOp.OnGlCommands(self, select, marked, no_color)
class TagDrawing(Drawing):
def __init__(self):
Drawing.__init__(self)
self.profile = None
def GetTitle(self):
return "Tag Drawing"
def is_an_add_level(self, level):
return True
def number_of_steps(self):
return 1
def calculate_item(self, end):
if end.type == cad.DigitizeType.DIGITIZE_NO_ITEM_TYPE:
return False
if (self.TempObject() != None) and (self.TempObject().GetType() != Tag.type):
self.ClearObjectsMade()
if self.TempObject() == None:
tag = Tag.Tag()
self.AddToTempObjects(tag)
else:
self.TempObject().pos.x = end.point.x
self.TempObject().pos.y = end.point.y
return True
def GetOwnerForDrawingObjects(self):
return self.profile.tags
tag_drawing = TagDrawing()