diff --git a/CHANGELOG.md b/CHANGELOG.md index f57f916c..3bbbc409 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ CHANGELOG for FlatCAM beta - minor changes - fixed the Follow plugin not marking correctly the resulting Geometry objet as a `multigeo` - fixed the Cutout plugin not working with Geometry objects that are made out of a MultiLineString +- fixed the Milling Plugin who changed the tools information "tools_mill_multidepth" when changing from Basic to Advanced mode to the application default value but that defeated the change made by the Cutout plugin +- fixed a Shapely 2.0 deprecation warning in the Report plugin 24.01.2022 diff --git a/appPlugins/ToolCutOut.py b/appPlugins/ToolCutOut.py index bfa3be7c..8c896ba7 100644 --- a/appPlugins/ToolCutOut.py +++ b/appPlugins/ToolCutOut.py @@ -944,17 +944,6 @@ class CutOut(AppTool): geo_obj.multigeo = True geo_obj.solid_geometry = deepcopy(solid_geo) - xmin, ymin, xmax, ymax = CutOut.recursive_bounds(geo_obj.solid_geometry) - geo_obj.options['xmin'] = xmin - geo_obj.options['ymin'] = ymin - geo_obj.options['xmax'] = xmax - geo_obj.options['ymax'] = ymax - - geo_obj.options['tools_mill_tooldia'] = str(cut_dia) - geo_obj.options['tools_mill_cutz'] = self.ui.cutz_entry.get_value() - geo_obj.options['tools_mill_multidepth'] = self.ui.mpass_cb.get_value() - geo_obj.options['tools_mill_depthperpass'] = self.ui.maxdepth_entry.get_value() - geo_obj.tools[1] = deepcopy(self.cut_tool_dict) geo_obj.tools[1]['tooldia'] = str(cut_dia) geo_obj.tools[1]['solid_geometry'] = geo_obj.solid_geometry @@ -962,9 +951,11 @@ class CutOut(AppTool): geo_obj.tools[1]['data']['name'] = outname geo_obj.tools[1]['data']['tools_mill_tooldia'] = str(cut_dia) geo_obj.tools[1]['data']['tools_mill_cutz'] = self.ui.cutz_entry.get_value() + geo_obj.tools[1]['data']['tools_mill_multidepth'] = self.ui.mpass_cb.get_value() geo_obj.tools[1]['data']['tools_mill_depthperpass'] = self.ui.maxdepth_entry.get_value() + # if there are "thin gaps" if gaps_solid_geo: geo_obj.tools[99] = deepcopy(self.cut_tool_dict) geo_obj.tools[99]['tooldia'] = str(cut_dia) @@ -978,6 +969,17 @@ class CutOut(AppTool): # plot this tool in a different color geo_obj.tools[99]['data']['override_color'] = "#29a3a3fa" + xmin, ymin, xmax, ymax = CutOut.recursive_bounds(geo_obj.solid_geometry) + geo_obj.options['xmin'] = xmin + geo_obj.options['ymin'] = ymin + geo_obj.options['xmax'] = xmax + geo_obj.options['ymax'] = ymax + + geo_obj.options['tools_mill_tooldia'] = str(cut_dia) + geo_obj.options['tools_mill_cutz'] = self.ui.cutz_entry.get_value() + geo_obj.options['tools_mill_multidepth'] = self.ui.mpass_cb.get_value() + geo_obj.options['tools_mill_depthperpass'] = self.ui.maxdepth_entry.get_value() + def excellon_init(exc_obj, app_o): if not holes: return 'fail' @@ -1008,6 +1010,7 @@ class CutOut(AppTool): ret = app_obj.app_obj.new_object('excellon', outname_exc, excellon_init, autoselected=False) if ret == 'fail': app_obj.inform.emit('[ERROR_NOTCL] %s' % _("Mouse bites failed.")) + app_obj.should_we_save = True ret = app_obj.app_obj.new_object('geometry', outname, geo_init, autoselected=False) if ret == 'fail': @@ -1247,11 +1250,6 @@ class CutOut(AppTool): geo_obj.multigeo = True geo_obj.solid_geometry = deepcopy(solid_geo) - geo_obj.options['xmin'] = xmin - geo_obj.options['ymin'] = ymin - geo_obj.options['xmax'] = xmax - geo_obj.options['ymax'] = ymax - geo_obj.tools[1] = deepcopy(self_c.cut_tool_dict) geo_obj.tools[1]['tooldia'] = str(cut_dia) geo_obj.tools[1]['solid_geometry'] = geo_obj.solid_geometry @@ -1274,6 +1272,17 @@ class CutOut(AppTool): geo_obj.tools[99]['data']['tools_mill_depthperpass'] = self_c.ui.maxdepth_entry.get_value() geo_obj.tools[99]['data']['override_color'] = "#29a3a3fa" + xmin, ymin, xmax, ymax = CutOut.recursive_bounds(geo_obj.solid_geometry) + geo_obj.options['xmin'] = xmin + geo_obj.options['ymin'] = ymin + geo_obj.options['xmax'] = xmax + geo_obj.options['ymax'] = ymax + + geo_obj.options['tools_mill_tooldia'] = str(cut_dia) + geo_obj.options['tools_mill_cutz'] = self_c.ui.cutz_entry.get_value() + geo_obj.options['tools_mill_multidepth'] = self_c.ui.mpass_cb.get_value() + geo_obj.options['tools_mill_depthperpass'] = self_c.ui.maxdepth_entry.get_value() + def excellon_init(exc_obj, app_o): if not holes: return 'fail' diff --git a/appPlugins/ToolMilling.py b/appPlugins/ToolMilling.py index ec3b2ae5..7670d9cb 100644 --- a/appPlugins/ToolMilling.py +++ b/appPlugins/ToolMilling.py @@ -728,9 +728,12 @@ class ToolMilling(AppTool, Excellon): tool_data['tools_mill_offset_value'] = 0.0 tool_data['tools_mill_job_type'] = 0 # _('Roughing') - tool_data['tools_mill_multidepth'] = False - tool_data['tools_mill_extracut'] = False - tool_data['tools_mill_dwell'] = False + # we made the decision here what to do with the hidden parameters + # some will disable some of the hidden features but other are set by + # other plugins so we hide them but we do not disable (like the `multidepth`) + # tool_data['tools_mill_multidepth'] = False + tool_data['tools_mill_extracut'] = self.app.defaults["tools_mill_extracut"] + tool_data['tools_mill_dwell'] = self.app.defaults["tools_mill_dwell"] tool_data['tools_mill_area_exclusion'] = False self.ui.offset_type_lbl.hide() @@ -787,7 +790,10 @@ class ToolMilling(AppTool, Excellon): tool_data['tools_mill_offset_value'] = app_defaults['tools_mill_offset_value'] tool_data['tools_mill_job_type'] = app_defaults['tools_mill_job_type'] - tool_data['tools_mill_multidepth'] = app_defaults['tools_mill_multidepth'] + # we made the decision here what to do with the hidden parameters + # some will disable some of the hidden features but other are set by + # other plugins so we hide them but we do not disable (like the `multidepth`) + # tool_data['tools_mill_multidepth'] = app_defaults['tools_mill_multidepth'] tool_data['tools_mill_extracut'] = app_defaults['tools_mill_extracut'] tool_data['tools_mill_dwell'] = app_defaults['tools_mill_dwell'] tool_data['tools_mill_area_exclusion'] = app_defaults['tools_mill_area_exclusion'] @@ -1706,6 +1712,15 @@ class ToolMilling(AppTool, Excellon): def update_ui(self): self.ui_disconnect() + # load the Milling object + self.obj_name = self.ui.object_combo.currentText() + # Get source object. + try: + self.target_obj = self.app.collection.get_by_name(self.obj_name) + except Exception: + self.app.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Could not retrieve object"), str(self.obj_name))) + return + if self.ui.target_radio.get_value() == 'exc': plugin_table = self.ui.tools_table else: @@ -1781,7 +1796,15 @@ class ToolMilling(AppTool, Excellon): def to_form(self, storage=None): if storage is None: - storage = self.app.options + # load the Milling object + self.obj_name = self.ui.object_combo.currentText() + # Get source object. + try: + self.target_obj = self.app.collection.get_by_name(self.obj_name) + except Exception: + self.app.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Could not retrieve object"), str(self.obj_name))) + return + storage = self.app.options if self.target_obj is None else self.target_obj.options # calculate self.currnet_row for the cellWidgets in the Tools Table if self.ui.target_radio.get_value() == 'geo': @@ -3211,10 +3234,12 @@ class ToolMilling(AppTool, Excellon): float(tools_dict[tooluid_key]['data']['tools_mill_tooldia']), self.decimals) dia_cnc_dict['data']['tools_mill_tooldia'] = deepcopy(tooldia_val) + # Path optimizations if "optimization_type" not in tools_dict[tooluid_key]['data']: def_optimization_type = geo_obj.options["tools_mill_optimization_type"] tools_dict[tooluid_key]['data']["tools_mill_optimization_type"] = def_optimization_type + # Polishing job_type = tools_dict[tooluid_key]['data']['tools_mill_job_type'] if job_type == 3: # Polishing self.app.log.debug("Painting the polished area ...") diff --git a/appPlugins/ToolReport.py b/appPlugins/ToolReport.py index 9ff4d176..1afddc5c 100644 --- a/appPlugins/ToolReport.py +++ b/appPlugins/ToolReport.py @@ -7,9 +7,9 @@ from PyQt6 import QtGui, QtCore, QtWidgets from appTool import AppTool -from appGUI.GUIElements import FCTree, VerticalScrollArea, FCLabel +from appGUI.GUIElements import FCTree, VerticalScrollArea -from shapely.geometry import MultiPolygon, Polygon +from shapely.geometry import MultiPolygon, Polygon, MultiLineString from shapely.ops import unary_union from copy import deepcopy @@ -458,7 +458,10 @@ class ObjectReport(AppTool): if k == 'solid_geometry': # printed_value = _('Present') if v else _('None') try: - printed_value = str(len(v)) + if isinstance(k, (MultiPolygon, MultiLineString)): + printed_value = str(len(v.geoms)) + else: + printed_value = str(len(v)) except (TypeError, AttributeError): printed_value = '1' self.treeWidget.addChild(geo_tool, [str(k), printed_value], True) diff --git a/camlib.py b/camlib.py index eafbc1c9..33890223 100644 --- a/camlib.py +++ b/camlib.py @@ -3597,7 +3597,7 @@ class CNCjob(Geometry): :rtype: str """ - log.debug("geometry_tool_gcode_gen()") + log.debug("camlib.CNCJob.geometry_tool_gcode_gen()") t_gcode = '' temp_solid_geometry = [] @@ -3868,9 +3868,13 @@ class CNCjob(Geometry): log.debug("Starting G-Code...") current_tooldia = float('%.*f' % (self.decimals, float(self.tooldia))) - self.app.inform.emit('%s: %s%s.' % (_("Starting G-Code for tool with diameter"), - str(current_tooldia), - str(self.units))) + msg = '%s: %s%s.' % (_("Starting G-Code for tool with diameter"), str(current_tooldia), str(self.units)) + self.app.log.debug(msg) + self.app.inform.emit(msg) + if not self.multidepth: + self.app.log.debug("camlib.CNCJob.geometry_tool_gcode_gen() -> Multidepth OFF -> Single Pass") + else: + self.app.log.debug("camlib.CNCJob.geometry_tool_gcode_gen() -> Multidepth ON -> Multiple Pass") # Measurements total_travel = 0.0