From 546f4c23612143e814303bde946c7167cad154aa Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Mon, 15 Mar 2021 00:02:33 +0200 Subject: [PATCH] - updated the Milling Plugin and all the related parts in the CNCJob Object and in all preprocessors. Now, the parent 'tools' attribute is inherited and also the GCode is stored here - made sure that old projects load but without the CNCjob objects which would have crashed the app due different data structures - the FlatCAm Evo projects load now in succession, no longer on threads --- CHANGELOG.md | 3 + appEditors/appGCodeEditor.py | 11 +- appObjects/FlatCAMCNCJob.py | 105 ++++++++++-------- appObjects/FlatCAMGeometry.py | 8 +- appObjects/FlatCAMObj.py | 201 ++++++++++++++++------------------ appPlugins/ToolMilling.py | 8 +- appPlugins/ToolReport.py | 194 ++++++++++++++++---------------- appPlugins/ToolSolderPaste.py | 18 +-- app_Main.py | 17 ++- camlib.py | 11 +- 10 files changed, 303 insertions(+), 273 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3211ce88..c0d015cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,9 @@ CHANGELOG for FlatCAM beta - Drilling Plugin - added in the UI the toolchange X,Y parameter and made it to work as expected - Milling Plugin - added in the UI the toolchange X,Y parameter and made it to work as expected - allow the old projects to be loaded without crashing the app, although the load is incomplete +- updated the Milling Plugin and all the related parts in the CNCJob Object and in all preprocessors. Now, the parent 'tools' attribute is inherited and also the GCode is stored here +- made sure that old projects load but without the CNCjob objects which would have crashed the app due different data structures +- the FlatCAm Evo projects load now in succession, no longer on threads 13.03.2021 diff --git a/appEditors/appGCodeEditor.py b/appEditors/appGCodeEditor.py index aa272376..e94a5986 100644 --- a/appEditors/appGCodeEditor.py +++ b/appEditors/appGCodeEditor.py @@ -150,7 +150,10 @@ class AppGCodeEditor(QtCore.QObject): tool_idx = 0 row_no = 0 - n = len(self.gcode_obj.cnc_tools) + 3 + # for the case when the self.tools is empty: old projects do that + if not self.gcode_obj.tools: + return + n = len(self.gcode_obj.tools) + 3 self.ui.cnc_tools_table.setRowCount(n) # add the All Gcode selection @@ -170,7 +173,7 @@ class AppGCodeEditor(QtCore.QObject): start_item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.ui.cnc_tools_table.setItem(row_no, 1, start_item) - for dia_key, dia_value in self.gcode_obj.cnc_tools.items(): + for dia_key, dia_value in self.gcode_obj.tools.items(): tool_idx += 1 row_no += 1 @@ -338,7 +341,7 @@ class AppGCodeEditor(QtCore.QObject): :rtype: """ # rows selected - if self.gcode_obj.cnc_tools: + if self.gcode_obj.options['type'].lower() == 'geometry': try: self.ui.cnc_tools_table.clicked.disconnect(self.on_row_selection_change) except (TypeError, AttributeError): @@ -434,7 +437,7 @@ class AppGCodeEditor(QtCore.QObject): text_to_be_found = None if self.gcode_obj.options['type'].lower() == 'geometry': - text_to_be_found = self.gcode_obj.cnc_tools[tool_no]['gcode'] + text_to_be_found = self.gcode_obj.tools[tool_no]['gcode'] elif self.gcode_obj.options['type'].lower() == 'excellon': tool_dia = self.app.dec_format(float(t_table.item(row, 1).text()), dec=self.decimals) for tool_id in self.gcode_obj.tools: diff --git a/appObjects/FlatCAMCNCJob.py b/appObjects/FlatCAMCNCJob.py index ce615bfe..e3f074c8 100644 --- a/appObjects/FlatCAMCNCJob.py +++ b/appObjects/FlatCAMCNCJob.py @@ -79,6 +79,7 @@ class CNCJobObject(FlatCAMObj, CNCjob): }) ''' + When self.tools is an attribute of a CNCJob object created from a Geometry object. This is a dict of dictionaries. Each dict is associated with a tool present in the file. The key is the diameter of the tools and the value is another dict that will hold the data under the following form: {tooldia: { @@ -97,11 +98,11 @@ class CNCJobObject(FlatCAMObj, CNCjob): It is populated in the GeometryObject.mtool_gen_cncjob() BEWARE: I rely on the ordered nature of the Python 3.7 dictionary. Things might change ... ''' - self.cnc_tools = {} ''' - This is a dict of dictionaries. Each dict is associated with a tool present in the file. The key is the - diameter of the tools and the value is another dict that will hold the data under the following form: + When self.tools is an attribute of a CNCJob object created from a Geometry object. + This is a dict of dictionaries. Each dict is associated with a tool present in the file. The key is the + diameter of the tools and the value is another dict that will hold the data under the following form: {tooldia: { 'tool': int, 'nr_drills': int, @@ -201,10 +202,14 @@ class CNCJobObject(FlatCAMObj, CNCjob): def build_cnc_tools_table(self): tool_idx = 0 - n = len(self.cnc_tools) + # for the case when self.tools is empty: it can happen for old projects who stored the data elsewhere + if not self.tools: + return + + n = len(self.tools) self.ui.cnc_tools_table.setRowCount(n) - for dia_key, dia_value in self.cnc_tools.items(): + for dia_key, dia_value in self.tools.items(): tool_idx += 1 row_no = tool_idx - 1 @@ -799,21 +804,22 @@ class CNCJobObject(FlatCAMObj, CNCjob): start_comment = comment_start_symbol if comment_start_symbol is not None else '(' stop_comment = comment_stop_symbol if comment_stop_symbol is not None else ')' - try: - for key in self.cnc_tools: - ppg = self.cnc_tools[key]['data']['ppname_g'] - if 'marlin' in ppg.lower() or 'repetier' in ppg.lower(): - marlin = True - break - if ppg == 'hpgl': - hpgl = True - break - if "toolchange_probe" in ppg.lower(): - probe_pp = True - break - except KeyError: - # self.app.log.debug("FlatCAMCNCJob.gcode_header() error: --> %s" % str(e)) - pass + if self.options['type'] == 'geometry': + try: + for key in self.tools: + ppg = self.tools[key]['data']['ppname_g'] + if 'marlin' in ppg.lower() or 'repetier' in ppg.lower(): + marlin = True + break + if ppg == 'hpgl': + hpgl = True + break + if "toolchange_probe" in ppg.lower(): + probe_pp = True + break + except KeyError: + # self.app.log.debug("FlatCAMCNCJob.gcode_header() error: --> %s" % str(e)) + pass try: if 'marlin' in self.options['ppname_e'].lower() or 'repetier' in self.options['ppname_e'].lower(): @@ -921,16 +927,20 @@ class CNCJobObject(FlatCAMObj, CNCjob): pass # if this dict is not empty then the object is a Geometry object - if self.cnc_tools: - first_key = next(iter(self.cnc_tools)) - include_header = self.app.preprocessors[self.cnc_tools[first_key]['data']['tools_mill_ppname_g']] - include_header = include_header.include_header + if self.options['type'].lower() == 'geometry': + # for the case that self.tools is empty: old projects + try: + first_key = list(self.tools.keys())[0] + include_header = self.app.preprocessors[self.tools[first_key]['data']['tools_mill_ppname_g']] + include_header = include_header.include_header + except TypeError: + include_header = self.app.preprocessors['default'].include_header # if this dict is not empty then the object is an Excellon object if self.options['type'].lower() == 'excellon': # for the case that self.tools is empty: old projects try: - first_key = next(iter(self.tools)) + first_key = list(self.tools.keys())[0] try: include_header = self.app.preprocessors[ self.tools[first_key]['data']['tools_drill_ppname_e'] @@ -948,11 +958,15 @@ class CNCJobObject(FlatCAMObj, CNCjob): if include_header is False: # detect if using multi-tool and make the Gcode summation correctly for each case if self.multitool is True: - for tooluid_key in self.cnc_tools: - for key, value in self.cnc_tools[tooluid_key].items(): - if key == 'gcode': - gcode += value - break + try: + if self.options['type'].lower() == 'geometry': + for tooluid_key in self.tools: + for key, value in self.tools[tooluid_key].items(): + if key == 'gcode': + gcode += value + break + except TypeError: + pass else: gcode += self.gcode @@ -982,8 +996,9 @@ class CNCJobObject(FlatCAMObj, CNCjob): gcode += value break else: - for tooluid_key in self.cnc_tools: - for key, value in self.cnc_tools[tooluid_key].items(): + # it's made from a Geometry object + for tooluid_key in self.tools: + for key, value in self.tools[tooluid_key].items(): if key == 'gcode' and value: gcode += value break @@ -999,9 +1014,9 @@ class CNCJobObject(FlatCAMObj, CNCjob): # for the case that self.tools is empty: old projects try: if self.options['type'].lower() == 'geometry': - for key in self.cnc_tools: - if 'tools_mill_ppname_g' in self.cnc_tools[key]['data']: - if 'hpgl' in self.cnc_tools[key]['data']['tools_mill_ppname_g']: + for key in self.tools: + if 'tools_mill_ppname_g' in self.tools[key]['data']: + if 'hpgl' in self.tools[key]['data']['tools_mill_ppname_g']: hpgl = True break elif self.options['type'].lower() == 'excellon': @@ -1199,9 +1214,9 @@ class CNCJobObject(FlatCAMObj, CNCjob): if self.ui.exc_cnc_tools_table.cellWidget(r, 6).isChecked(): self.plot2(tooldia=tooldia, obj=self, visible=True, gcode_parsed=gcode_parsed, kind=kind) else: - for tooluid_key in self.cnc_tools: - tooldia = float('%.*f' % (self.decimals, float(self.cnc_tools[tooluid_key]['tooldia']))) - gcode_parsed = self.cnc_tools[tooluid_key]['gcode_parsed'] + for tooluid_key in self.tools: + tooldia = float('%.*f' % (self.decimals, float(self.tools[tooluid_key]['tooldia']))) + gcode_parsed = self.tools[tooluid_key]['gcode_parsed'] # tool_uid = int(self.ui.cnc_tools_table.item(cw_row, 3).text()) for r in range(self.ui.cnc_tools_table.rowCount()): @@ -1271,13 +1286,13 @@ class CNCJobObject(FlatCAMObj, CNCjob): self.plot2(tooldia=tooldia, obj=self, visible=visible, gcode_parsed=gcode_parsed, kind=kind) else: # multiple tools usage - if self.cnc_tools: - for tooluid_key in self.cnc_tools: + if self.tools: + for tooluid_key in self.tools: tooldia = self.app.dec_format( - float(self.cnc_tools[tooluid_key]['data']['tools_mill_tooldia']), + float(self.tools[tooluid_key]['data']['tools_mill_tooldia']), self.decimals ) - gcode_parsed = self.cnc_tools[tooluid_key]['gcode_parsed'] + gcode_parsed = self.tools[tooluid_key]['gcode_parsed'] self.plot2(tooldia=tooldia, obj=self, visible=visible, gcode_parsed=gcode_parsed, kind=kind) self.shapes.redraw() @@ -1344,7 +1359,7 @@ class CNCJobObject(FlatCAMObj, CNCjob): tool_dia_copy = {} data_copy = {} - for tooluid_key, tooluid_value in self.cnc_tools.items(): + for tooluid_key, tooluid_value in self.tools.items(): for dia_key, dia_value in tooluid_value.items(): if dia_key == 'tooldia': dia_value *= factor @@ -1393,5 +1408,5 @@ class CNCJobObject(FlatCAMObj, CNCjob): }) tool_dia_copy.clear() - self.cnc_tools.clear() - self.cnc_tools = deepcopy(temp_tools_dict) + self.tools.clear() + self.tools = deepcopy(temp_tools_dict) diff --git a/appObjects/FlatCAMGeometry.py b/appObjects/FlatCAMGeometry.py index b12cb2f0..9235fb73 100644 --- a/appObjects/FlatCAMGeometry.py +++ b/appObjects/FlatCAMGeometry.py @@ -2282,7 +2282,7 @@ class GeometryObject(FlatCAMObj, Geometry): # this turn on the FlatCAMCNCJob plot for multiple tools job_obj.multitool = True job_obj.multigeo = False - job_obj.cnc_tools.clear() + job_obj.tools.clear() job_obj.segx = segx if segx else float(self.app.defaults["geometry_segx"]) job_obj.segy = segy if segy else float(self.app.defaults["geometry_segy"]) @@ -2400,7 +2400,7 @@ class GeometryObject(FlatCAMObj, Geometry): except Exception as er: app_obj.inform.emit('[ERROR] %s: %s' % (_("G-Code processing failed with error"), str(er))) - job_obj.cnc_tools.update({ + job_obj.tools.update({ tooluid_key: deepcopy(dia_cnc_dict) }) dia_cnc_dict.clear() @@ -2426,7 +2426,7 @@ class GeometryObject(FlatCAMObj, Geometry): # this turn on the FlatCAMCNCJob plot for multiple tools job_obj.multitool = True job_obj.multigeo = True - job_obj.cnc_tools.clear() + job_obj.tools.clear() job_obj.segx = segx if segx else float(self.app.defaults["geometry_segx"]) job_obj.segy = segy if segy else float(self.app.defaults["geometry_segy"]) @@ -2552,7 +2552,7 @@ class GeometryObject(FlatCAMObj, Geometry): except Exception as ee: app_obj.inform.emit('[ERROR] %s: %s' % (_("G-Code processing failed with error"), str(ee))) - job_obj.cnc_tools.update({ + job_obj.tools.update({ tooluid_key: deepcopy(dia_cnc_dict) }) dia_cnc_dict.clear() diff --git a/appObjects/FlatCAMObj.py b/appObjects/FlatCAMObj.py index 0f726f6c..d74e119f 100644 --- a/appObjects/FlatCAMObj.py +++ b/appObjects/FlatCAMObj.py @@ -546,8 +546,8 @@ class FlatCAMObj(QtCore.QObject): ymax = [] if obj_prop.kind.lower() == 'cncjob': + # CNCJob created from Excellon or Geometry object try: - # created from Excellon object for tool_k in obj_prop.tools: x0, y0, x1, y1 = unary_union(obj_prop.tools[tool_k]['solid_geometry']).bounds xmin.append(x0) @@ -556,17 +556,6 @@ class FlatCAMObj(QtCore.QObject): ymax.append(y1) except Exception as ee: log.error("FlatCAMObj.add_properties_items() cncjob --> %s" % str(ee)) - - # created from Geometry object - try: - for tool_k in obj_prop.cnc_tools: - x0, y0, x1, y1 = unary_union(obj_prop.cnc_tools[tool_k]['solid_geometry']).bounds - xmin.append(x0) - ymin.append(y0) - xmax.append(x1) - ymax.append(y1) - except Exception as ee: - log.error("FlatCAMObj.add_properties_items() cncjob --> %s" % str(ee)) else: try: if obj_prop.tools: @@ -748,104 +737,106 @@ class FlatCAMObj(QtCore.QObject): else: self.treeWidget.addChild(geo_tool, [str(k), str(v)], True) elif obj.kind.lower() == 'cncjob': - # for cncjob objects made from gerber or geometry - for tool, value in obj.cnc_tools.items(): - geo_tool = self.treeWidget.addParent( - tools, str(tool), expanded=False, color=p_color, font=font) - for k, v in value.items(): - if k == 'solid_geometry': - printed_value = _('Present') if v else _('None') - self.treeWidget.addChild(geo_tool, [_("Solid Geometry"), printed_value], True) - elif k == 'gcode': - printed_value = _('Present') if v != '' else _('None') - self.treeWidget.addChild(geo_tool, [_("GCode Text"), printed_value], True) - elif k == 'gcode_parsed': - printed_value = _('Present') if v else _('None') - self.treeWidget.addChild(geo_tool, [_("GCode Geometry"), printed_value], True) - elif k == 'data': - pass - else: - self.treeWidget.addChild(geo_tool, [str(k), str(v)], True) + # for CNCJob objects made from Gerber or Geometry + if obj.options['type'].lower() == 'geometry': + for tool, value in obj.tools.items(): + geo_tool = self.treeWidget.addParent( + tools, str(tool), expanded=False, color=p_color, font=font) + for k, v in value.items(): + if k == 'solid_geometry': + printed_value = _('Present') if v else _('None') + self.treeWidget.addChild(geo_tool, [_("Solid Geometry"), printed_value], True) + elif k == 'gcode': + printed_value = _('Present') if v != '' else _('None') + self.treeWidget.addChild(geo_tool, [_("GCode Text"), printed_value], True) + elif k == 'gcode_parsed': + printed_value = _('Present') if v else _('None') + self.treeWidget.addChild(geo_tool, [_("GCode Geometry"), printed_value], True) + elif k == 'data': + pass + else: + self.treeWidget.addChild(geo_tool, [str(k), str(v)], True) - v = value['data'] - tool_data = self.treeWidget.addParent( - geo_tool, _("Tool Data"), color=p_color, font=font) - for data_k, data_v in v.items(): - self.treeWidget.addChild(tool_data, [str(data_k).capitalize(), str(data_v)], True) + v = value['data'] + tool_data = self.treeWidget.addParent( + geo_tool, _("Tool Data"), color=p_color, font=font) + for data_k, data_v in v.items(): + self.treeWidget.addChild(tool_data, [str(data_k).capitalize(), str(data_v)], True) # for CNCJob objects made from Excellon - for tool_id, value in obj.tools.items(): - tool_dia = value['tooldia'] - exc_tool = self.treeWidget.addParent( - tools, str(tool_id), expanded=False, color=p_color, font=font - ) - self.treeWidget.addChild( - exc_tool, - [ - _('Diameter'), - '%.*f %s' % (self.decimals, tool_dia, self.app.defaults['units'].lower()) - ], - True - ) - for k, v in value.items(): - if k == 'solid_geometry': - printed_value = _('Present') if v else _('None') - self.treeWidget.addChild(exc_tool, [_("Solid Geometry"), printed_value], True) - elif k == 'nr_drills': - self.treeWidget.addChild(exc_tool, [_("Drills number"), str(v)], True) - elif k == 'nr_slots': - self.treeWidget.addChild(exc_tool, [_("Slots number"), str(v)], True) - elif k == 'gcode': - printed_value = _('Present') if v != '' else _('None') - self.treeWidget.addChild(exc_tool, [_("GCode Text"), printed_value], True) - elif k == 'gcode_parsed': - printed_value = _('Present') if v else _('None') - self.treeWidget.addChild(exc_tool, [_("GCode Geometry"), printed_value], True) - else: - pass + if obj.options['type'].lower() == 'excellon': + for tool_id, value in obj.tools.items(): + tool_dia = value['tooldia'] + exc_tool = self.treeWidget.addParent( + tools, str(tool_id), expanded=False, color=p_color, font=font + ) + self.treeWidget.addChild( + exc_tool, + [ + _('Diameter'), + '%.*f %s' % (self.decimals, tool_dia, self.app.defaults['units'].lower()) + ], + True + ) + for k, v in value.items(): + if k == 'solid_geometry': + printed_value = _('Present') if v else _('None') + self.treeWidget.addChild(exc_tool, [_("Solid Geometry"), printed_value], True) + elif k == 'nr_drills': + self.treeWidget.addChild(exc_tool, [_("Drills number"), str(v)], True) + elif k == 'nr_slots': + self.treeWidget.addChild(exc_tool, [_("Slots number"), str(v)], True) + elif k == 'gcode': + printed_value = _('Present') if v != '' else _('None') + self.treeWidget.addChild(exc_tool, [_("GCode Text"), printed_value], True) + elif k == 'gcode_parsed': + printed_value = _('Present') if v else _('None') + self.treeWidget.addChild(exc_tool, [_("GCode Geometry"), printed_value], True) + else: + pass - self.treeWidget.addChild( - exc_tool, - [ - _("Depth of Cut"), - '%.*f %s' % ( - self.decimals, - (obj.z_cut - abs(value['data']['tools_drill_offset'])), - self.app.defaults['units'].lower() - ) - ], - True - ) - self.treeWidget.addChild( - exc_tool, - [ - _("Clearance Height"), - '%.*f %s' % ( - self.decimals, - obj.z_move, - self.app.defaults['units'].lower() - ) - ], - True - ) - self.treeWidget.addChild( - exc_tool, - [ - _("Feedrate"), - '%.*f %s/min' % ( - self.decimals, - obj.feedrate, - self.app.defaults['units'].lower() - ) - ], - True - ) + self.treeWidget.addChild( + exc_tool, + [ + _("Depth of Cut"), + '%.*f %s' % ( + self.decimals, + (obj.z_cut - abs(value['data']['tools_drill_offset'])), + self.app.defaults['units'].lower() + ) + ], + True + ) + self.treeWidget.addChild( + exc_tool, + [ + _("Clearance Height"), + '%.*f %s' % ( + self.decimals, + obj.z_move, + self.app.defaults['units'].lower() + ) + ], + True + ) + self.treeWidget.addChild( + exc_tool, + [ + _("Feedrate"), + '%.*f %s/min' % ( + self.decimals, + obj.feedrate, + self.app.defaults['units'].lower() + ) + ], + True + ) - v = value['data'] - tool_data = self.treeWidget.addParent( - exc_tool, _("Tool Data"), color=p_color, font=font) - for data_k, data_v in v.items(): - self.treeWidget.addChild(tool_data, [str(data_k).capitalize(), str(data_v)], True) + v = value['data'] + tool_data = self.treeWidget.addParent( + exc_tool, _("Tool Data"), color=p_color, font=font) + for data_k, data_v in v.items(): + self.treeWidget.addChild(tool_data, [str(data_k).capitalize(), str(data_v)], True) r_time = obj.routing_time if r_time > 1: diff --git a/appPlugins/ToolMilling.py b/appPlugins/ToolMilling.py index f487239a..398c9169 100644 --- a/appPlugins/ToolMilling.py +++ b/appPlugins/ToolMilling.py @@ -2899,7 +2899,7 @@ class ToolMilling(AppTool, Excellon): # this turn on the FlatCAMCNCJob plot for multiple tools new_cncjob_obj.multitool = True new_cncjob_obj.multigeo = False - new_cncjob_obj.cnc_tools.clear() + new_cncjob_obj.tools.clear() new_cncjob_obj.segx = segx new_cncjob_obj.segy = segy @@ -3020,7 +3020,7 @@ class ToolMilling(AppTool, Excellon): except Exception as er: app_obj.inform.emit('[ERROR] %s: %s' % (_("G-Code processing failed with error"), str(er))) - new_cncjob_obj.cnc_tools.update({ + new_cncjob_obj.tools.update({ tooluid_key: deepcopy(dia_cnc_dict) }) dia_cnc_dict.clear() @@ -3046,7 +3046,7 @@ class ToolMilling(AppTool, Excellon): # this turn on the FlatCAMCNCJob plot for multiple tools new_cncjob_obj.multitool = True new_cncjob_obj.multigeo = True - new_cncjob_obj.cnc_tools.clear() + new_cncjob_obj.tools.clear() new_cncjob_obj.segx = segx new_cncjob_obj.segy = segy @@ -3180,7 +3180,7 @@ class ToolMilling(AppTool, Excellon): # object is the source of gcode # Update the CNCJob tools dictionary - new_cncjob_obj.cnc_tools.update({ + new_cncjob_obj.tools.update({ tooluid_key: deepcopy(dia_cnc_dict) }) dia_cnc_dict.clear() diff --git a/appPlugins/ToolReport.py b/appPlugins/ToolReport.py index b5935d0c..2dc8325c 100644 --- a/appPlugins/ToolReport.py +++ b/appPlugins/ToolReport.py @@ -262,8 +262,8 @@ class ObjectReport(AppTool): log.error("PropertiesTool.addItems() --> %s" % str(ee)) try: - for tool_k in obj_prop.cnc_tools: - x0, y0, x1, y1 = unary_union(obj_prop.cnc_tools[tool_k]['solid_geometry']).bounds + for tool_k in obj_prop.tools: + x0, y0, x1, y1 = unary_union(obj_prop.tools[tool_k]['solid_geometry']).bounds xmin.append(x0) ymin.append(y0) xmax.append(x1) @@ -460,104 +460,106 @@ class ObjectReport(AppTool): else: self.treeWidget.addChild(geo_tool, [str(k), str(v)], True) elif obj.kind.lower() == 'cncjob': - # for cncjob objects made from gerber or geometry - for tool, value in obj.cnc_tools.items(): - geo_tool = self.treeWidget.addParent( - tools, str(tool), expanded=True, color=p_color, font=font) - for k, v in value.items(): - if k == 'solid_geometry': - printed_value = _('Present') if v else _('None') - self.treeWidget.addChild(geo_tool, [_("Solid Geometry"), printed_value], True) - elif k == 'gcode': - printed_value = _('Present') if v != '' else _('None') - self.treeWidget.addChild(geo_tool, [_("GCode Text"), printed_value], True) - elif k == 'gcode_parsed': - printed_value = _('Present') if v else _('None') - self.treeWidget.addChild(geo_tool, [_("GCode Geometry"), printed_value], True) - elif k == 'data': - pass - else: - self.treeWidget.addChild(geo_tool, [str(k), str(v)], True) + # for CNCJob objects made from Gerber or Geometry objects + if obj.options['type'].lower() == 'geometry': + for tool, value in obj.tools.items(): + geo_tool = self.treeWidget.addParent( + tools, str(tool), expanded=True, color=p_color, font=font) + for k, v in value.items(): + if k == 'solid_geometry': + printed_value = _('Present') if v else _('None') + self.treeWidget.addChild(geo_tool, [_("Solid Geometry"), printed_value], True) + elif k == 'gcode': + printed_value = _('Present') if v != '' else _('None') + self.treeWidget.addChild(geo_tool, [_("GCode Text"), printed_value], True) + elif k == 'gcode_parsed': + printed_value = _('Present') if v else _('None') + self.treeWidget.addChild(geo_tool, [_("GCode Geometry"), printed_value], True) + elif k == 'data': + pass + else: + self.treeWidget.addChild(geo_tool, [str(k), str(v)], True) - v = value['data'] - tool_data = self.treeWidget.addParent( - geo_tool, _("Tool Data"), color=p_color, font=font) - for data_k, data_v in v.items(): - self.treeWidget.addChild(tool_data, [str(data_k).capitalize(), str(data_v)], True) + v = value['data'] + tool_data = self.treeWidget.addParent( + geo_tool, _("Tool Data"), color=p_color, font=font) + for data_k, data_v in v.items(): + self.treeWidget.addChild(tool_data, [str(data_k).capitalize(), str(data_v)], True) - # for CNCJob objects made from Excellon - for tool_id, value in obj.tools.items(): - tool_dia = obj.tools[tool_id]['tooldia'] - exc_tool = self.treeWidget.addParent( - tools, str(tool_id), expanded=False, color=p_color, font=font - ) - self.treeWidget.addChild( - exc_tool, - [ - _('Diameter'), - '%.*f %s' % (self.decimals, tool_dia, self.app.defaults['units'].lower()) - ], - True - ) - for k, v in value.items(): - if k == 'solid_geometry': - printed_value = _('Present') if v else _('None') - self.treeWidget.addChild(exc_tool, [_("Solid Geometry"), printed_value], True) - elif k == 'nr_drills': - self.treeWidget.addChild(exc_tool, [_("Drills number"), str(v)], True) - elif k == 'nr_slots': - self.treeWidget.addChild(exc_tool, [_("Slots number"), str(v)], True) - elif k == 'gcode': - printed_value = _('Present') if v != '' else _('None') - self.treeWidget.addChild(exc_tool, [_("GCode Text"), printed_value], True) - elif k == 'gcode_parsed': - printed_value = _('Present') if v else _('None') - self.treeWidget.addChild(exc_tool, [_("GCode Geometry"), printed_value], True) - else: - pass + # for CNCJob objects made from Excellon objects + if obj.options['type'].lower() == 'excellon': + for tool_id, value in obj.tools.items(): + tool_dia = obj.tools[tool_id]['tooldia'] + exc_tool = self.treeWidget.addParent( + tools, str(tool_id), expanded=False, color=p_color, font=font + ) + self.treeWidget.addChild( + exc_tool, + [ + _('Diameter'), + '%.*f %s' % (self.decimals, tool_dia, self.app.defaults['units'].lower()) + ], + True + ) + for k, v in value.items(): + if k == 'solid_geometry': + printed_value = _('Present') if v else _('None') + self.treeWidget.addChild(exc_tool, [_("Solid Geometry"), printed_value], True) + elif k == 'nr_drills': + self.treeWidget.addChild(exc_tool, [_("Drills number"), str(v)], True) + elif k == 'nr_slots': + self.treeWidget.addChild(exc_tool, [_("Slots number"), str(v)], True) + elif k == 'gcode': + printed_value = _('Present') if v != '' else _('None') + self.treeWidget.addChild(exc_tool, [_("GCode Text"), printed_value], True) + elif k == 'gcode_parsed': + printed_value = _('Present') if v else _('None') + self.treeWidget.addChild(exc_tool, [_("GCode Geometry"), printed_value], True) + else: + pass - self.treeWidget.addChild( - exc_tool, - [ - _("Depth of Cut"), - '%.*f %s' % ( - self.decimals, - (obj.z_cut - abs(value['data']['tools_drill_offset'])), - self.app.defaults['units'].lower() - ) - ], - True - ) - self.treeWidget.addChild( - exc_tool, - [ - _("Clearance Height"), - '%.*f %s' % ( - self.decimals, - obj.z_move, - self.app.defaults['units'].lower() - ) - ], - True - ) - self.treeWidget.addChild( - exc_tool, - [ - _("Feedrate"), - '%.*f %s/min' % ( - self.decimals, - obj.feedrate, - self.app.defaults['units'].lower() - ) - ], - True - ) + self.treeWidget.addChild( + exc_tool, + [ + _("Depth of Cut"), + '%.*f %s' % ( + self.decimals, + (obj.z_cut - abs(value['data']['tools_drill_offset'])), + self.app.defaults['units'].lower() + ) + ], + True + ) + self.treeWidget.addChild( + exc_tool, + [ + _("Clearance Height"), + '%.*f %s' % ( + self.decimals, + obj.z_move, + self.app.defaults['units'].lower() + ) + ], + True + ) + self.treeWidget.addChild( + exc_tool, + [ + _("Feedrate"), + '%.*f %s/min' % ( + self.decimals, + obj.feedrate, + self.app.defaults['units'].lower() + ) + ], + True + ) - v = value['data'] - tool_data = self.treeWidget.addParent( - exc_tool, _("Tool Data"), color=p_color, font=font) - for data_k, data_v in v.items(): - self.treeWidget.addChild(tool_data, [str(data_k).capitalize(), str(data_v)], True) + v = value['data'] + tool_data = self.treeWidget.addParent( + exc_tool, _("Tool Data"), color=p_color, font=font) + for data_k, data_v in v.items(): + self.treeWidget.addChild(tool_data, [str(data_k).capitalize(), str(data_v)], True) r_time = obj.routing_time if r_time > 1: diff --git a/appPlugins/ToolSolderPaste.py b/appPlugins/ToolSolderPaste.py index 2823e51d..c96a35a4 100644 --- a/appPlugins/ToolSolderPaste.py +++ b/appPlugins/ToolSolderPaste.py @@ -930,7 +930,8 @@ class SolderPaste(AppTool): # this turn on the FlatCAMCNCJob plot for multiple tools new_obj.multitool = True new_obj.multigeo = True - new_obj.cnc_tools.clear() + # new_obj object is a CNCJob object made from an Geometry object + new_obj.tools.clear() new_obj.special_group = 'solder_paste_tool' new_obj.options['xmin'] = xmin @@ -970,7 +971,8 @@ class SolderPaste(AppTool): # tell gcode_parse from which point to start drawing the lines depending on what kind of # object is the source of gcode - new_obj.cnc_tools.update({ + # new_obj is a CNCJob made from Geometry object + new_obj.tools.update({ tooluid_key: deepcopy(tool_cnc_dict) }) tool_cnc_dict.clear() @@ -1031,13 +1033,14 @@ class SolderPaste(AppTool): gcode += '(Units: ' + self.units.upper() + ')\n' + "\n" gcode += '(Created on ' + time_str + ')\n' + '\n' - for tool in obj.cnc_tools: + # obj is a CNCJob object made from an Geometry object + for tool in obj.tools: try: # it's text - gcode += obj.cnc_tools[tool]['gcode'] + gcode += obj.tools[tool]['gcode'] except TypeError: # it's StringIO - gcode += obj.cnc_tools[tool]['gcode'].getvalue() + gcode += obj.tools[tool]['gcode'].getvalue() # then append the text from GCode to the text editor # try: @@ -1101,8 +1104,9 @@ class SolderPaste(AppTool): gcode += '(Units: ' + self.units.upper() + ')\n' + "\n" gcode += '(Created on ' + time_str + ')\n' + '\n' - for tool in obj.cnc_tools: - gcode += obj.cnc_tools[tool]['gcode'] + # for CNCJob objects made from Gerber or Geometry objects + for tool in obj.tools: + gcode += obj.tools[tool]['gcode'] lines = StringIO(gcode) # ## Write diff --git a/app_Main.py b/app_Main.py index ee838f3c..143e7abf 100644 --- a/app_Main.py +++ b/app_Main.py @@ -11145,7 +11145,13 @@ class MenuFileHandlers(QtCore.QObject): self.log.debug(" **************** Started PROEJCT loading... **************** ") for obj in d['objs']: - self.log.debug( + if 'cnc_tools' in obj or 'exc_cnc_tools' in obj: + self.app.log.error( + 'MenuFileHandlers.open_project() --> %s %s. %s' % + ("Failed to open the CNCJob file:", str(obj['options']['name']), "Maybe it is an old project.")) + continue + + self.app.log.debug( "Recreating from opened project an %s object: %s" % (obj['kind'].capitalize(), obj['options']['name'])) def obj_init(new_obj, app_inst): @@ -11162,13 +11168,14 @@ class MenuFileHandlers(QtCore.QObject): new_obj.tools = { int(tool): tool_dict for tool, tool_dict in list(new_obj.tools.items()) } - except AttributeError: + except Exception: pass except Exception as erro: app_inst.log.error('MenuFileHandlers.open_project() --> ' + str(erro)) return 'fail' - app_inst.worker_task.emit({'fcn': worker_task, 'params': []}) + worker_task() + # app_inst.worker_task.emit({'fcn': worker_task, 'params': []}) # for some reason, setting ui_title does not work when this method is called from Tcl Shell # it's because the TclCommand is run in another thread (it inherit TclCommandSignaled) @@ -11176,7 +11183,9 @@ class MenuFileHandlers(QtCore.QObject): self.app.ui.set_ui_title(name="{} {}: {}".format( _("Loading Project ... restoring"), obj['kind'].upper(), obj['options']['name'])) - self.app.app_obj.new_object(obj['kind'], obj['options']['name'], obj_init, plot=plot) + ret = self.app.app_obj.new_object(obj['kind'], obj['options']['name'], obj_init, plot=plot) + if ret == 'fail': + continue self.inform.emit('[success] %s: %s' % (_("Project loaded from"), filename)) diff --git a/camlib.py b/camlib.py index 7b8eb02d..03342484 100644 --- a/camlib.py +++ b/camlib.py @@ -7603,8 +7603,9 @@ class CNCjob(Geometry): miny = np.Inf maxx = -np.Inf maxy = -np.Inf - if self.cnc_tools: - for k, v in self.cnc_tools.items(): + # for CNCJob objects made from Gerber or Geometry objects + if self.options['type'].lower() == 'geometry': + for k, v in self.tools.items(): minx = np.Inf miny = np.Inf maxx = -np.Inf @@ -7807,7 +7808,8 @@ class CNCjob(Geometry): self.create_geometry() else: - for k, v in self.cnc_tools.items(): + # for CNCJob objects made from Geometry objects + for k, v in self.tools.items(): # scale Gcode v['gcode'] = scale_g(v['gcode']) @@ -7915,7 +7917,8 @@ class CNCjob(Geometry): self.create_geometry() else: - for k, v in self.cnc_tools.items(): + # for CNCJob objects made from Gerber or Geometry objects + for k, v in self.tools.items(): # offset Gcode v['gcode'] = offset_g(v['gcode'])