- fixed a double application of milling offset when having geometries with multiple tools

- finished the mill-excellon feature in the Milling Tool; milling will be done progressively from the hole center toward the edge
This commit is contained in:
Marius Stanciu
2021-12-23 22:04:41 +02:00
committed by Marius
parent da154a865c
commit 03f096a1cd
6 changed files with 217 additions and 65 deletions

View File

@@ -491,6 +491,8 @@ class ToolMilling(AppTool, Excellon):
# Excellon properties
"tools_mill_milling_type": self.ui.milling_type_radio,
"tools_mill_milling_dia": self.ui.mill_dia_entry,
"tools_mill_milling_overlap": self.ui.overlap_entry,
"tools_mill_milling_connect": self.ui.connect_cb,
# Geometry properties
# "tools_mill_tooldia": self.ui.addtool_entry,
@@ -547,6 +549,8 @@ class ToolMilling(AppTool, Excellon):
self.name2option = {
"milling_type": "tools_mill_milling_type",
"milling_dia": "tools_mill_milling_dia",
"milling_overlap": "tools_mill_milling_overlap",
"milling_connect": "tools_mill_milling_connect",
"mill_offset_type": "tools_mill_offset_type",
"mill_offset": "tools_mill_offset_value",
@@ -1285,6 +1289,10 @@ class ToolMilling(AppTool, Excellon):
self.ui.mill_dia_label.show()
self.ui.mill_dia_entry.show()
self.ui.ovlabel.show()
self.ui.overlap_entry.show()
self.ui.connect_cb.show()
self.ui.frxylabel.hide()
self.ui.xyfeedrate_entry.hide()
self.ui.extracut_cb.hide()
@@ -1311,6 +1319,10 @@ class ToolMilling(AppTool, Excellon):
self.ui.mill_dia_label.hide()
self.ui.mill_dia_entry.hide()
self.ui.ovlabel.hide()
self.ui.overlap_entry.hide()
self.ui.connect_cb.hide()
self.ui.frxylabel.show()
self.ui.xyfeedrate_entry.show()
self.ui.extracut_cb.show()
@@ -2768,14 +2780,6 @@ class ToolMilling(AppTool, Excellon):
outname = "%s_%s" % (self.target_obj.options["name"], 'exc_cnc')
tools_dict = self.sel_tools
old_disp_number = 0
# create a unified geometry for the selected tools
drills_tool_geo = []
slots_tool_geo = []
total_paint_geo = []
final_solid_geometry = []
new_obj = HybridGeoExc(app=self.app)
new_obj.options = dict()
for opt, val in self.target_obj.options.items():
@@ -2789,22 +2793,36 @@ class ToolMilling(AppTool, Excellon):
new_obj.options[oname] = self.app.options[option]
for tool in tools_dict:
old_disp_number = 0
drills_tool_geo = []
slots_tool_geo = []
total_paint_geo = []
mill_type = tools_dict[tool]['data']['tools_mill_milling_type']
mill_dia = tools_dict[tool]['data']['tools_mill_milling_dia']
buff_dia = float(tools_dict[tool]['tooldia'])
over = 0.05
conn = True
cont = True
over = tools_dict[tool]['data']['tools_mill_milling_overlap'] / 100
conn = tools_dict[tool]['data']['tools_mill_milling_connect']
cont = True # in this case we need the contour always on
if tools_dict[tool]['data']['tools_mill_offset_type'] == 0: # Path
offset = 0.0
elif tools_dict[tool]['data']['tools_mill_offset_type'] == 1: # In
offset = -mill_dia / 2.0
elif tools_dict[tool]['data']['tools_mill_offset_type'] == 2: # Out
offset = mill_dia / 2.0
else: # Custom
offset = tools_dict[tool]['data']['tools_mill_offset_value']
buff_dia = float(tools_dict[tool]['tooldia']) / 2.0 + offset
if mill_type in ['drills', 'both']:
drills_tool_geo = [
d_p.buffer(buff_dia / 2.0) for d_p in tools_dict[tool]['drills']
d_p.buffer(buff_dia) for d_p in tools_dict[tool]['drills']
]
total_paint_geo = drills_tool_geo
elif mill_type in ['slots', 'both']:
slots_tool_geo = [
LineString(s_l).buffer(buff_dia / 2.0) for s_l in tools_dict[tool]['slots']
LineString(s_l).buffer(buff_dia) for s_l in tools_dict[tool]['slots']
]
total_paint_geo = slots_tool_geo
elif mill_type == 'both':
@@ -2839,10 +2857,9 @@ class ToolMilling(AppTool, Excellon):
total_geometry += list(x.get_objects())
# clean the geometry
new_geo = [g for g in total_geometry if g and not g.is_empty]
total_geometry = new_geo
final_solid_geometry += total_geometry
total_geometry = [g for g in total_geometry if g and not g.is_empty]
else:
self.app.log.debug("The tools does not have a suitable geometry for milling.")
continue
tools_dict[tool]['data']['tools_mill_tooldia'] = mill_dia
@@ -2851,7 +2868,7 @@ class ToolMilling(AppTool, Excellon):
new_obj.tools[tool] = {
'tooldia': mill_dia,
'data': deepcopy(self.target_obj.tools[tool]['data']),
'solid_geometry': final_solid_geometry
'solid_geometry': deepcopy(total_geometry)
}
new_obj.tools[tool]['data']['tools_mill_tooldia'] = mill_dia
new_obj.tools[tool]['data']['segx'] = self.app.options['geometry_segx']
@@ -2865,7 +2882,7 @@ class ToolMilling(AppTool, Excellon):
# a milled geometry (either drills or slots or both) not a total sum.
# painting the polygons
self.mtool_gen_cncjob(geo_obj=new_obj, tools_dict=new_obj.tools)
self.mtool_gen_cncjob(geo_obj=new_obj, tools_dict=new_obj.tools, disable_offset=True)
def on_generatecnc_from_geo(self):
self.app.log.debug("Generating CNCJob from Geometry ...")
@@ -2932,7 +2949,7 @@ class ToolMilling(AppTool, Excellon):
# print(tooldia_val)
def mtool_gen_cncjob(self, geo_obj=None, outname=None, tools_dict=None, tools_in_use=None, segx=None, segy=None,
toolchange=None, plot=True, use_thread=True):
toolchange=None, plot=True, use_thread=True, disable_offset=False):
"""
Creates a multi-tool CNCJob out of this Geometry object.
The actual work is done by the target CNCJobObject object's
@@ -2949,6 +2966,7 @@ class ToolMilling(AppTool, Excellon):
:param segy: number of segments on the Y axis, for auto-levelling
:param plot: if True the generated object will be plotted; if False will not be plotted
:param use_thread: if True use threading
:param disable_offset: If True then the set offset for each tool will not be used
:return: None
"""
@@ -2958,7 +2976,7 @@ class ToolMilling(AppTool, Excellon):
outname = "%s_%s" % (geo_obj.options["name"], 'cnc') if outname is None else outname
tools_dict = self.sel_tools if tools_dict is None else tools_dict
print(tools_dict)
if not geo_obj.tools:
segx = segx if segx is not None else float(geo_obj.options['segx'])
segy = segy if segy is not None else float(geo_obj.options['segy'])
@@ -3054,6 +3072,9 @@ class ToolMilling(AppTool, Excellon):
else:
tool_offset = 0.0
if disable_offset is True:
tool_offset = 0.0
dia_cnc_dict['data']['tools_mill_offset_value'] = tool_offset
z_cut = tools_dict[tooluid_key]['data']["tools_mill_cutz"]
@@ -3298,7 +3319,11 @@ class ToolMilling(AppTool, Excellon):
else:
tool_offset = 0.0
if disable_offset is True:
tool_offset = 0.0
dia_cnc_dict['data']['tools_mill_offset_value'] = tool_offset
tools_dict[tooluid_key]['data']['tools_mill_offset_value'] = tool_offset
# Solid Geometry
tool_solid_geometry = geo_obj.tools[tooluid_key]['solid_geometry']
@@ -4199,10 +4224,45 @@ class MillingUI:
param_grid.addWidget(self.offset_label, 6, 0)
param_grid.addWidget(self.offset_entry, 6, 1)
# Overlap
self.ovlabel = FCLabel('%s:' % _('Overlap'))
self.ovlabel.setToolTip(
_("How much (percentage) of the tool width to overlap each tool pass.\n"
"Adjust the value starting with lower values\n"
"and increasing it if areas that should be processed are still \n"
"not processed.\n"
"Lower values = faster processing, faster execution on CNC.\n"
"Higher values = slow processing and slow execution on CNC\n"
"due of too many paths.")
)
self.overlap_entry = FCDoubleSpinner(callback=self.confirmation_message, suffix='%')
self.overlap_entry.set_precision(3)
self.overlap_entry.setWrapping(True)
self.overlap_entry.setRange(0.0000, 99.9999)
self.overlap_entry.setSingleStep(0.1)
self.overlap_entry.setObjectName('milling_overlap')
param_grid.addWidget(self.ovlabel, 8, 0)
param_grid.addWidget(self.overlap_entry, 8, 1)
# Connect lines
self.connect_cb = FCCheckBox('%s' % _("Connect"))
self.connect_cb.setObjectName('milling_connect')
self.connect_cb.setToolTip(
_("Draw lines between resulting\n"
"segments to minimize tool lifts.")
)
param_grid.addWidget(self.connect_cb, 10, 0, 1, 2)
self.ovlabel.hide()
self.overlap_entry.hide()
self.connect_cb.hide()
self.offset_separator_line = QtWidgets.QFrame()
self.offset_separator_line.setFrameShape(QtWidgets.QFrame.Shape.HLine)
self.offset_separator_line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken)
param_grid.addWidget(self.offset_separator_line, 8, 0, 1, 2)
param_grid.addWidget(self.offset_separator_line, 12, 0, 1, 2)
# Tool Type
self.tool_shape_label = FCLabel('%s:' % _('Shape'))
@@ -4225,8 +4285,8 @@ class MillingUI:
else:
self.tool_shape_combo.setCurrentIndex(idx)
param_grid.addWidget(self.tool_shape_label, 10, 0)
param_grid.addWidget(self.tool_shape_combo, 10, 1)
param_grid.addWidget(self.tool_shape_label, 14, 0)
param_grid.addWidget(self.tool_shape_combo, 14, 1)
# separator_line = QtWidgets.QFrame()
# separator_line.setFrameShape(QtWidgets.QFrame.Shape.HLine)
@@ -4250,8 +4310,8 @@ class MillingUI:
)
self.job_type_combo.setObjectName('mill_job_type')
param_grid.addWidget(self.job_type_lbl, 14, 0)
param_grid.addWidget(self.job_type_combo, 14, 1)
param_grid.addWidget(self.job_type_lbl, 16, 0)
param_grid.addWidget(self.job_type_combo, 16, 1)
# Polish Margin
self.polish_margin_lbl = FCLabel('%s:' % _('Margin'))
@@ -4263,8 +4323,8 @@ class MillingUI:
self.polish_margin_entry.set_range(-10000.0000, 10000.0000)
self.polish_margin_entry.setObjectName("mill_polish_margin")
param_grid.addWidget(self.polish_margin_lbl, 16, 0)
param_grid.addWidget(self.polish_margin_entry, 16, 1)
param_grid.addWidget(self.polish_margin_lbl, 18, 0)
param_grid.addWidget(self.polish_margin_entry, 18, 1)
# Polish Overlap
self.polish_over_lbl = FCLabel('%s:' % _('Overlap'))
@@ -4278,8 +4338,8 @@ class MillingUI:
self.polish_over_entry.setSingleStep(0.1)
self.polish_over_entry.setObjectName("mill_polish_overlap")
param_grid.addWidget(self.polish_over_lbl, 18, 0)
param_grid.addWidget(self.polish_over_entry, 18, 1)
param_grid.addWidget(self.polish_over_lbl, 20, 0)
param_grid.addWidget(self.polish_over_entry, 20, 1)
# Polish Method
self.polish_method_lbl = FCLabel('%s:' % _('Method'))
@@ -4296,8 +4356,8 @@ class MillingUI:
)
self.polish_method_combo.setObjectName('mill_polish_method')
param_grid.addWidget(self.polish_method_lbl, 20, 0)
param_grid.addWidget(self.polish_method_combo, 20, 1)
param_grid.addWidget(self.polish_method_lbl, 22, 0)
param_grid.addWidget(self.polish_method_combo, 22, 1)
self.polish_margin_lbl.hide()
self.polish_margin_entry.hide()
@@ -4309,7 +4369,7 @@ class MillingUI:
self.job_separator_line = QtWidgets.QFrame()
self.job_separator_line.setFrameShape(QtWidgets.QFrame.Shape.HLine)
self.job_separator_line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken)
param_grid.addWidget(self.job_separator_line, 22, 0, 1, 2)
param_grid.addWidget(self.job_separator_line, 24, 0, 1, 2)
# Tip Dia
self.tipdialabel = FCLabel('%s:' % _('V-Tip Dia'))
@@ -4324,8 +4384,8 @@ class MillingUI:
self.tipdia_entry.setSingleStep(0.1)
self.tipdia_entry.setObjectName("mill_tipdia")
param_grid.addWidget(self.tipdialabel, 24, 0)
param_grid.addWidget(self.tipdia_entry, 24, 1)
param_grid.addWidget(self.tipdialabel, 26, 0)
param_grid.addWidget(self.tipdia_entry, 26, 1)
# Tip Angle
self.tipanglelabel = FCLabel('%s:' % _('V-Tip Angle'))
@@ -4341,8 +4401,8 @@ class MillingUI:
self.tipangle_entry.setSingleStep(1)
self.tipangle_entry.setObjectName("mill_tipangle")
param_grid.addWidget(self.tipanglelabel, 26, 0)
param_grid.addWidget(self.tipangle_entry, 26, 1)
param_grid.addWidget(self.tipanglelabel, 28, 0)
param_grid.addWidget(self.tipangle_entry, 28, 1)
self.tipdialabel.hide()
self.tipdia_entry.hide()
@@ -4363,8 +4423,8 @@ class MillingUI:
self.cutz_entry.setSingleStep(0.1)
self.cutz_entry.setObjectName("mill_cutz")
param_grid.addWidget(self.cutzlabel, 28, 0)
param_grid.addWidget(self.cutz_entry, 28, 1)
param_grid.addWidget(self.cutzlabel, 30, 0)
param_grid.addWidget(self.cutz_entry, 30, 1)
# Multi-Depth
self.mpass_cb = FCCheckBox('%s:' % _("Multi-Depth"))
@@ -4388,8 +4448,8 @@ class MillingUI:
self.mis_mpass_geo = OptionalInputSection(self.mpass_cb, [self.maxdepth_entry])
param_grid.addWidget(self.mpass_cb, 30, 0)
param_grid.addWidget(self.maxdepth_entry, 30, 1)
param_grid.addWidget(self.mpass_cb, 32, 0)
param_grid.addWidget(self.maxdepth_entry, 32, 1)
# Travel Z (z_move)
self.travelzlabel = FCLabel('%s:' % _('Travel Z'))
@@ -4406,8 +4466,8 @@ class MillingUI:
self.travelz_entry.setSingleStep(0.1)
self.travelz_entry.setObjectName("mill_travelz")
param_grid.addWidget(self.travelzlabel, 32, 0)
param_grid.addWidget(self.travelz_entry, 32, 1)
param_grid.addWidget(self.travelzlabel, 34, 0)
param_grid.addWidget(self.travelz_entry, 34, 1)
# Feedrate X-Y
self.frxylabel = FCLabel('%s:' % _('Feedrate X-Y'))
@@ -4421,8 +4481,8 @@ class MillingUI:
self.xyfeedrate_entry.setSingleStep(0.1)
self.xyfeedrate_entry.setObjectName("mill_feedratexy")
param_grid.addWidget(self.frxylabel, 34, 0)
param_grid.addWidget(self.xyfeedrate_entry, 34, 1)
param_grid.addWidget(self.frxylabel, 36, 0)
param_grid.addWidget(self.xyfeedrate_entry, 36, 1)
self.frxylabel.hide()
self.xyfeedrate_entry.hide()
@@ -4441,8 +4501,8 @@ class MillingUI:
self.feedrate_z_entry.setSingleStep(0.1)
self.feedrate_z_entry.setObjectName("mill_feedratez")
param_grid.addWidget(self.frzlabel, 36, 0)
param_grid.addWidget(self.feedrate_z_entry, 36, 1)
param_grid.addWidget(self.frzlabel, 38, 0)
param_grid.addWidget(self.feedrate_z_entry, 38, 1)
# Rapid Feedrate
self.feedrate_rapid_label = FCLabel('%s:' % _('Feedrate Rapids'))
@@ -4459,8 +4519,8 @@ class MillingUI:
self.feedrate_rapid_entry.setSingleStep(0.1)
self.feedrate_rapid_entry.setObjectName("mill_fr_rapid")
param_grid.addWidget(self.feedrate_rapid_label, 38, 0)
param_grid.addWidget(self.feedrate_rapid_entry, 38, 1)
param_grid.addWidget(self.feedrate_rapid_label, 40, 0)
param_grid.addWidget(self.feedrate_rapid_entry, 40, 1)
# default values is to hide
self.feedrate_rapid_label.hide()
@@ -4494,8 +4554,8 @@ class MillingUI:
self.extracut_cb.hide()
self.e_cut_entry.hide()
param_grid.addWidget(self.extracut_cb, 40, 0)
param_grid.addWidget(self.e_cut_entry, 40, 1)
param_grid.addWidget(self.extracut_cb, 42, 0)
param_grid.addWidget(self.e_cut_entry, 42, 1)
# Spindlespeed
self.spindle_label = FCLabel('%s:' % _('Spindle speed'))
@@ -4509,8 +4569,8 @@ class MillingUI:
self.spindlespeed_entry.set_step(100)
self.spindlespeed_entry.setObjectName("mill_spindlespeed")
param_grid.addWidget(self.spindle_label, 42, 0)
param_grid.addWidget(self.spindlespeed_entry, 42, 1)
param_grid.addWidget(self.spindle_label, 44, 0)
param_grid.addWidget(self.spindlespeed_entry, 44, 1)
# Dwell
self.dwell_cb = FCCheckBox('%s:' % _('Dwell'))
@@ -4530,8 +4590,8 @@ class MillingUI:
)
self.dwelltime_entry.setObjectName("mill_dwelltime")
param_grid.addWidget(self.dwell_cb, 44, 0)
param_grid.addWidget(self.dwelltime_entry, 44, 1)
param_grid.addWidget(self.dwell_cb, 46, 0)
param_grid.addWidget(self.dwelltime_entry, 46, 1)
self.ois_dwell = OptionalInputSection(self.dwell_cb, [self.dwelltime_entry])