From 17533aebc3ca76a57e474db1844efa1f0ed79872 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 21 Jan 2022 22:15:33 +0200 Subject: [PATCH] - fixed more issues with the `cncjob` Tcl command - made sure that some autocomplete keywords are correctly processed by the application; needs the delete of the preferences files --- CHANGELOG.md | 2 + appPlugins/ToolMilling.py | 46 ++++++++++++++------ app_Main.py | 76 +++++++++++++++++---------------- defaults.py | 17 +++++--- tclCommands/TclCommandCncjob.py | 9 +++- 5 files changed, 91 insertions(+), 59 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 37acbedf..95777037 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ CHANGELOG for FlatCAM beta - added a new Tcl command: `buffer` which will buffer the geometry of an object or will scale individually each geometry sub element - fixed the buffer() method for the Excellon objects (the resulting tool diameters were calculated less than the what was expected) - fixed the description for the new Tcl command `buffer` +- fixed more issues with the `cncjob` Tcl command +- made sure that some autocomplete keywords are correctly processed by the application; needs the delete of the preferences files 19.01.2022 diff --git a/appPlugins/ToolMilling.py b/appPlugins/ToolMilling.py index 7cdbb74f..9f254be2 100644 --- a/appPlugins/ToolMilling.py +++ b/appPlugins/ToolMilling.py @@ -2951,7 +2951,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, disable_offset=False): + toolchange=None, plot=True, use_thread=True, disable_offset=False, from_tcl=False): """ Creates a multi-tool CNCJob out of this Geometry object. The actual work is done by the target CNCJobObject object's @@ -2969,6 +2969,7 @@ class ToolMilling(AppTool, Excellon): :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 + :param from_tcl: If True then the method is called by a Tcl command which does not use the UI :return: None """ @@ -3281,66 +3282,79 @@ class ToolMilling(AppTool, Excellon): # Toolchange Z try: - tools_dict[tooluid_key]['data']['tools_mill_toolchangez'] = self.ui.toolchangez_entry.get_value() + if not from_tcl: + tools_dict[tooluid_key]['data']['tools_mill_toolchangez'] = \ + self.ui.toolchangez_entry.get_value() except AttributeError: tools_dict[tooluid_key]['data']['tools_mill_toolchangez'] = \ self.app.defaults['tools_mill_toolchangez'] # Toolchange X-Y try: - tools_dict[tooluid_key]['data']['tools_mill_toolchangexy'] = self.ui.toolchangexy_entry.get_value() + if not from_tcl: + tools_dict[tooluid_key]['data']['tools_mill_toolchangexy'] = \ + self.ui.toolchangexy_entry.get_value() except AttributeError: tools_dict[tooluid_key]['data']['tools_mill_toolchangexy'] = \ self.app.defaults['tools_mill_toolchangexy'] # End Move Z try: - tools_dict[tooluid_key]['data']['tools_mill_endz'] = self.ui.endz_entry.get_value() + if not from_tcl: + tools_dict[tooluid_key]['data']['tools_mill_endz'] = self.ui.endz_entry.get_value() except AttributeError: tools_dict[tooluid_key]['data']['tools_mill_endz'] = self.app.defaults['tools_mill_endz'] # End Move XY try: - tools_dict[tooluid_key]['data']['tools_mill_endxy'] = self.ui.endxy_entry.get_value() + if not from_tcl: + tools_dict[tooluid_key]['data']['tools_mill_endxy'] = self.ui.endxy_entry.get_value() except AttributeError: tools_dict[tooluid_key]['data']['tools_mill_endxy'] = self.app.defaults['tools_mill_endxy'] # Probe Z try: - tools_dict[tooluid_key]['data']['tools_mill_z_pdepth'] = self.ui.pdepth_entry.get_value() + if not from_tcl: + tools_dict[tooluid_key]['data']['tools_mill_z_pdepth'] = self.ui.pdepth_entry.get_value() except AttributeError: tools_dict[tooluid_key]['data']['tools_mill_z_pdepth'] = self.app.defaults['tools_mill_z_pdepth'] # Probe FR try: - tools_dict[tooluid_key]['data'][ - 'tools_mill_feedrate_probe'] = self.ui.feedrate_probe_entry.get_value() + if not from_tcl: + tools_dict[tooluid_key]['data']['tools_mill_feedrate_probe'] = \ + self.ui.feedrate_probe_entry.get_value() except AttributeError: tools_dict[tooluid_key]['data'][ 'tools_mill_feedrate_probe'] = self.app.defaults['tools_mill_feedrate_probe'] # Exclusion Areas Enable try: - tools_dict[tooluid_key]['data']['tools_mill_area_exclusion'] = self.ui.exclusion_cb.get_value() + if not from_tcl: + tools_dict[tooluid_key]['data']['tools_mill_area_exclusion'] = self.ui.exclusion_cb.get_value() except AttributeError: tools_dict[tooluid_key]['data']['tools_mill_area_exclusion'] = False # Tcl Command most likely # Exclusion Areas Shape try: - tools_dict[tooluid_key]['data']['tools_mill_area_shape'] = self.ui.area_shape_radio.get_value() + if not from_tcl: + tools_dict[tooluid_key]['data']['tools_mill_area_shape'] = self.ui.area_shape_radio.get_value() except AttributeError: tools_dict[tooluid_key]['data']['tools_mill_area_shape'] = \ self.app.defaults['tools_mill_area_shape'] # Exclusion Areas Strategy try: - tools_dict[tooluid_key]['data']['tools_mill_area_strategy'] = self.ui.strategy_radio.get_value() + if not from_tcl: + tools_dict[tooluid_key]['data']['tools_mill_area_strategy'] = self.ui.strategy_radio.get_value() except AttributeError: tools_dict[tooluid_key]['data']['tools_mill_area_strategy'] = \ self.app.defaults['tools_mill_area_strategy'] # Exclusion Areas Overz try: - tools_dict[tooluid_key]['data']['tools_mill_area_overz'] = self.ui.over_z_entry.get_value() + if not from_tcl: + tools_dict[tooluid_key]['data']['tools_mill_area_overz'] = self.ui.over_z_entry.get_value() except AttributeError: tools_dict[tooluid_key]['data']['tools_mill_area_overz'] = \ self.app.defaults['tools_mill_area_overz'] # Preprocessor try: - tools_dict[tooluid_key]['data']['tools_mill_ppname_g'] = self.ui.pp_geo_name_cb.get_value() + if not from_tcl: + tools_dict[tooluid_key]['data']['tools_mill_ppname_g'] = self.ui.pp_geo_name_cb.get_value() except AttributeError: tools_dict[tooluid_key]['data']['tools_mill_ppname_g'] = self.app.defaults['tools_mill_ppname_g'] @@ -3352,7 +3366,10 @@ class ToolMilling(AppTool, Excellon): tool_offset = tooldia_val / 2 elif offset_type == 3: # 'custom' try: - offset_value = self.ui.offset_entry.get_value() + if not from_tcl: + offset_value = self.ui.offset_entry.get_value() + else: + offset_value = tools_dict[tooluid_key]['data']['tools_mill_offset_value'] except AttributeError: offset_value = self.app.defaults['tools_mill_offset_value'] if offset_value: @@ -3395,6 +3412,7 @@ class ToolMilling(AppTool, Excellon): is_last = True if tooluid_key == tool_lst[-1] else False last_pt = tools_dict[tooluid_key]['data']['tools_mill_endxy'] + print(tools_dict[tooluid_key]['data']['tools_mill_ppname_g']) res, start_gcode = new_cncjob_obj.geometry_tool_gcode_gen(tooluid_key, tools_dict, first_pt=first_pt, last_pt=last_pt, tolerance=tol, diff --git a/app_Main.py b/app_Main.py index 6ac3c9f2..c9cafb96 100644 --- a/app_Main.py +++ b/app_Main.py @@ -642,19 +642,20 @@ class App(QtCore.QObject): 'version', 'write_gcode' ] + # those need to be duplicated in self.defaults["util_autocomplete_keywords"] but within a string self.default_keywords = ['Berta_CNC', 'Default_no_M6', 'Desktop', 'Documents', 'FlatConfig', 'FlatPrj', 'False', 'GRBL_11', 'GRL_11_no_M6', 'GRBL_laser', 'grbl_laser_eleks_drd', 'GRBL_laser_Z', 'ISEL_CNC', 'ISEL_ICP_CNC', 'Line_xyz', 'Marlin', 'Marlin_laser_FAN_pin', 'Marlin_laser_Spindle_pin', 'NCCAD9', 'Marius', 'My Documents', 'Paste_1', 'Repetier', 'Roland_MDX_20', 'Roland_MDX_540', - 'Users', 'Toolchange_Manual', 'Toolchange_Probe_MACH3', + 'Toolchange_Manual', 'Toolchange_Probe_MACH3', 'True', 'Users', 'all', 'auto', 'axis', 'axisoffset', 'box', 'center_x', 'center_y', 'columns', 'combine', 'connect', 'contour', 'default', 'depthperpass', 'dia', 'diatol', 'dist', 'drilled_dias', 'drillz', 'dpp', - 'dwelltime', 'extracut_length', 'endxy', 'enz', 'f', 'factor', 'feedrate', - 'feedrate_z', 'GRBL_11', 'GRBL_laser', 'gridoffsety', 'gridx', 'gridy', + 'dwelltime', 'extracut_length', 'endxy', 'endz', 'f', 'factor', 'feedrate', + 'feedrate_z', 'gridoffsety', 'gridx', 'gridy', 'has_offset', 'holes', 'hpgl', 'iso_type', 'join', 'margin', 'marlin', 'method', 'milled_dias', 'minoffset', 'name', 'offset', 'opt_type', 'order', 'outname', 'overlap', 'obj_name', 'passes', 'postamble', 'pp', 'ppname_e', 'ppname_g', @@ -7660,27 +7661,31 @@ class App(QtCore.QObject): # Populate the list with the overlapped objects on the click position curr_x, curr_y = self.pos - for obj in self.all_objects_list: - # ScriptObject and DocumentObject objects can't be selected - if obj.kind == 'script' or obj.kind == 'document': - continue - - if key == 'multisel' and obj.options['name'] in self.objects_under_the_click_list: - continue - - if (curr_x >= obj.options['xmin']) and (curr_x <= obj.options['xmax']) and \ - (curr_y >= obj.options['ymin']) and (curr_y <= obj.options['ymax']): - if obj.options['name'] not in self.objects_under_the_click_list: - if obj.options['plot']: - # add objects to the objects_under_the_click list only if the object is plotted - # (active and not disabled) - self.objects_under_the_click_list.append(obj.options['name']) - try: - if self.objects_under_the_click_list: - curr_sel_obj = self.collection.get_active() - # case when there is only an object under the click and we toggle it - if len(self.objects_under_the_click_list) == 1: + for obj in self.all_objects_list: + # ScriptObject and DocumentObject objects can't be selected + if obj.kind == 'script' or obj.kind == 'document': + continue + + if key == 'multisel' and obj.options['name'] in self.objects_under_the_click_list: + continue + + if (curr_x >= obj.options['xmin']) and (curr_x <= obj.options['xmax']) and \ + (curr_y >= obj.options['ymin']) and (curr_y <= obj.options['ymax']): + if obj.options['name'] not in self.objects_under_the_click_list: + if obj.options['plot']: + # add objects to the objects_under_the_click list only if the object is plotted + # (active and not disabled) + self.objects_under_the_click_list.append(obj.options['name']) + except Exception as e: + self.log.error( + "Something went bad in App.select_objects(). Create a list of objects under click pos%s" % str(e)) + + if self.objects_under_the_click_list: + curr_sel_obj = self.collection.get_active() + # case when there is only an object under the click and we toggle it + if len(self.objects_under_the_click_list) == 1: + try: if curr_sel_obj is None: self.collection.set_active(self.objects_under_the_click_list[0]) curr_sel_obj = self.collection.get_active() @@ -7689,7 +7694,6 @@ class App(QtCore.QObject): if self.defaults['global_selection_shape'] is True: self.draw_selection_shape(curr_sel_obj) curr_sel_obj.selection_shape_drawn = True - elif curr_sel_obj.options['name'] not in self.objects_under_the_click_list: self.collection.on_objects_selection(False) self.delete_selection_shape() @@ -7701,9 +7705,7 @@ class App(QtCore.QObject): if self.defaults['global_selection_shape'] is True: self.draw_selection_shape(curr_sel_obj) curr_sel_obj.selection_shape_drawn = True - self.selected_message(curr_sel_obj=curr_sel_obj) - elif curr_sel_obj.selection_shape_drawn is False: if self.defaults['global_selection_shape'] is True: self.draw_selection_shape(curr_sel_obj) @@ -7711,14 +7713,14 @@ class App(QtCore.QObject): else: self.collection.on_objects_selection(False) self.delete_selection_shape() - if self.call_source != 'app': self.call_source = 'app' - self.selected_message(curr_sel_obj=curr_sel_obj) - - else: - # If there is no selected object + except Exception as e: + self.log.error("Something went bad in App.select_objects(). Single click selection. %s" % str(e)) + else: + # If there is no selected object + try: # make active the first element of the overlapped objects list if self.collection.get_active() is None: self.collection.set_active(self.objects_under_the_click_list[0]) @@ -7746,10 +7748,12 @@ class App(QtCore.QObject): if self.defaults['global_selection_shape'] is True: self.draw_selection_shape(curr_sel_obj) curr_sel_obj.selection_shape_drawn = True - self.selected_message(curr_sel_obj=curr_sel_obj) - - else: + except Exception as e: + self.log.error( + "Something went bad in App.select_objects(). Cycle the objects under cursor. %s" % str(e)) + else: + try: # deselect everything self.collection.on_objects_selection(False) # delete the possible selection box around a possible selected object @@ -7773,8 +7777,8 @@ class App(QtCore.QObject): # self.inform.emit("") else: self.call_source = 'app' - except Exception as e: - self.log.error("Something went bad in App.select_objects(). %s" % str(e)) + except Exception as e: + self.log.error("Something went bad in App.select_objects(). Deselect everything. %s" % str(e)) def selected_message(self, curr_sel_obj): """ diff --git a/defaults.py b/defaults.py index 0837a3ca..bd40f558 100644 --- a/defaults.py +++ b/defaults.py @@ -790,16 +790,19 @@ class FlatCAMDefaults: 'gbl, gbo, gbp, gbr, gbs, gdo, ger, gko, gm1, gm2, gm3, grb, gtl, gto, gtp, gts, ly15, ly2, ' 'mil, outline, pho, plc, pls, smb, smt, sol, spb, spt, ssb, sst, stc, sts, top, tsm', # Keyword list - "util_autocomplete_keywords": 'Desktop, Documents, FlatConfig, FlatPrj, False, ' + "util_autocomplete_keywords": 'Berta_CNC, Default_no_M6, Desktop, Documents, FlatConfig, FlatPrj, False, ' + 'GRBL_11, GRL_11_no_M6, GRBL_laser, grbl_laser_eleks_drd, GRBL_laser_Z, ' + 'ISEL_CNC, ISEL_ICP_CNC, Line_xyz, Marlin, Marlin_laser_FAN_pin, ' + 'Marlin_laser_Spindle_pin, NCCAD9, ' 'Marius, My Documents, Paste_1, ' - 'Repetier, Roland_MDX_20, True, Users, Toolchange_Custom, ' - 'Toolchange_Probe_MACH3, ' - 'Toolchange_manual, Users, all, axis, auto, axisoffset, ' + 'Repetier, Roland_MDX_20, Roland_MDX_540,' + 'Toolchange_Manual, Toolchange_Probe_MACH3, True, ' + 'Users, all, auto, axis, axisoffset, ' 'box, center_x, center_y, columns, combine, connect, contour, default, ' 'depthperpass, dia, diatol, dist, drilled_dias, drillz, dpp, dwelltime, ' - 'endxy, endz, extracut_length, f, feedrate, ' - 'feedrate_z, grbl_11, GRBL_laser, gridoffsety, gridx, gridy, has_offset, ' - 'holes, hpgl, iso_type, line_xyz, margin, marlin, method, milled_dias, ' + 'endxy, endz, extracut_length, f, factor, feedrate, ' + 'feedrate_z, gridoffsety, gridx, gridy, has_offset, ' + 'holes, hpgl, iso_type, join, margin, marlin, method, milled_dias, ' 'minoffset, name, offset, opt_type, order, outname, overlap, obj_name' 'passes, postamble, pp, ppname_e, ppname_g, preamble, radius, ref, rest, ' 'rows, shellvar_, scale_factor, spacing_columns, spacing_rows, spindlespeed, ' diff --git a/tclCommands/TclCommandCncjob.py b/tclCommands/TclCommandCncjob.py index 2dd70bcc..da1ec16a 100644 --- a/tclCommands/TclCommandCncjob.py +++ b/tclCommands/TclCommandCncjob.py @@ -119,6 +119,7 @@ class TclCommandCncjob(TclCommandSignaled): if obj is None: if muted is False: self.raise_tcl_error("Object not found: %s" % str(name)) + return "fail" else: return "fail" @@ -134,7 +135,8 @@ class TclCommandCncjob(TclCommandSignaled): args["z_move"] = args["z_move"] if "z_move" in args and args["z_move"] else \ self.app.defaults["geometry_travelz"] - args["pp"] = args["pp"] if "pp" in args and args["pp"] else self.app.defaults["tools_mill_ppname_g"] + args["pp"] = args["pp"] if "pp" in args and isinstance(args["pp"], str) else \ + self.app.defaults["tools_mill_ppname_g"] args["feedrate"] = args["feedrate"] if "feedrate" in args and args["feedrate"] else \ self.app.defaults["tools_mill_feedrate"] @@ -242,6 +244,7 @@ class TclCommandCncjob(TclCommandSignaled): for tool_uid in list(local_tools_dict.keys()): if 'data' in local_tools_dict[tool_uid]: + local_tools_dict[tool_uid]['data']['tools_mill_tooldia'] = args["dia"] local_tools_dict[tool_uid]['data']['tools_mill_cutz'] = args["z_cut"] local_tools_dict[tool_uid]['data']['tools_mill_travelz'] = args["z_move"] local_tools_dict[tool_uid]['data']['tools_mill_feedrate'] = args["feedrate"] @@ -266,6 +269,7 @@ class TclCommandCncjob(TclCommandSignaled): local_tools_dict[tool_uid]['data']['tools_mill_dwell'] = args["dwell"] local_tools_dict[tool_uid]['data']['tools_mill_dwelltime'] = args["dwelltime"] local_tools_dict[tool_uid]['data']['tools_mill_ppname_g'] = args["pp"] + self.app.milling_tool.mtool_gen_cncjob( geo_obj=obj, outname=args['outname'], @@ -273,5 +277,6 @@ class TclCommandCncjob(TclCommandSignaled): tools_in_use=[], toolchange=args["toolchange"], use_thread=False, - plot=False) + plot=False, + from_tcl=True) # self.raise_tcl_error('The object is a multi-geo geometry which is not supported in cncjob Tcl Command')