diff --git a/CHANGELOG.md b/CHANGELOG.md index 4310c941..e205647c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ CHANGELOG for FlatCAM beta ================================================= +21.03.2022 + +- optimized the UI for the CNCJob object +- when loading a Gcode file in the app now the application makes an attempt in adding information's such that the CncJob UI works correctly; if so information's are not found then assumptions are made. Only for GCode that is detected as made from an Excellon object + 20.03.2022 - added a last resort option to load old projects; the result is not guaranteed if the differences are too great diff --git a/appEditors/appGCodeEditor.py b/appEditors/appGCodeEditor.py index 1d35bb41..59ad8166 100644 --- a/appEditors/appGCodeEditor.py +++ b/appEditors/appGCodeEditor.py @@ -280,14 +280,17 @@ class AppGCodeEditor(QtCore.QObject): self.ui.exc_cnc_tools_table.setItem(row_no, 1, start_item) for toolid_key, t_value in self.gcode_obj.tools.items(): - tooldia = self.gcode_obj.tools[toolid_key]['tooldia'] tool_idx += 1 row_no += 1 + tooldia = self.gcode_obj.tools[toolid_key]['tooldia'] + nr_drills = int(t_value['nr_drills']) + nr_slots = int(t_value['nr_slots']) + t_id = QtWidgets.QTableWidgetItem('%d' % int(tool_idx)) dia_item = QtWidgets.QTableWidgetItem('%.*f' % (self.decimals, float(tooldia))) - nr_drills_item = QtWidgets.QTableWidgetItem('%d' % int(t_value['nr_drills'])) - nr_slots_item = QtWidgets.QTableWidgetItem('%d' % int(t_value['nr_slots'])) + nr_drills_item = QtWidgets.QTableWidgetItem('%d' % nr_drills) + nr_slots_item = QtWidgets.QTableWidgetItem('%d' % nr_slots) try: cutz_item = QtWidgets.QTableWidgetItem('%.*f' % ( diff --git a/appGUI/ObjectUI.py b/appGUI/ObjectUI.py index 95020e8f..44eb7615 100644 --- a/appGUI/ObjectUI.py +++ b/appGUI/ObjectUI.py @@ -1373,11 +1373,19 @@ class CNCObjectUI(ObjectUI): self.custom_box.addWidget(self.param_label) self.gp_frame = FCFrame() + self.gp_frame.setSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum) self.custom_box.addWidget(self.gp_frame) grid_par = FCGridLayout(v_spacing=5, h_spacing=3) self.gp_frame.setLayout(grid_par) + self.estimated_frame = QtWidgets.QFrame() + self.estimated_frame.setContentsMargins(0, 0, 0, 0) + estimated_grid = FCGridLayout(v_spacing=5, h_spacing=3) + estimated_grid.setContentsMargins(0, 0, 0, 0) + self.estimated_frame.setLayout(estimated_grid) + grid_par.addWidget(self.estimated_frame, 4, 0, 1, 3) + # Travelled Distance self.t_distance_label = FCLabel("%s:" % _("Travelled distance")) self.t_distance_label.setToolTip( @@ -1387,9 +1395,9 @@ class CNCObjectUI(ObjectUI): self.t_distance_entry = FCEntry() self.units_label = FCLabel() - grid_par.addWidget(self.t_distance_label, 4, 0) - grid_par.addWidget(self.t_distance_entry, 4, 1) - grid_par.addWidget(self.units_label, 4, 2) + estimated_grid.addWidget(self.t_distance_label, 0, 0) + estimated_grid.addWidget(self.t_distance_entry, 0, 1) + estimated_grid.addWidget(self.units_label, 0, 2) # Estimated Time self.t_time_label = FCLabel("%s:" % _("Estimated time")) @@ -1400,19 +1408,18 @@ class CNCObjectUI(ObjectUI): self.t_time_entry = FCEntry() self.units_time_label = FCLabel() - grid_par.addWidget(self.t_time_label, 8, 0) - grid_par.addWidget(self.t_time_entry, 8, 1) - grid_par.addWidget(self.units_time_label, 8, 2) - - self.t_distance_label.hide() - self.t_distance_entry.setVisible(False) - self.t_time_label.hide() - self.t_time_entry.setVisible(False) + estimated_grid.addWidget(self.t_time_label, 2, 0) + estimated_grid.addWidget(self.t_time_entry, 2, 1) + estimated_grid.addWidget(self.units_time_label, 2, 2) separator_line = QtWidgets.QFrame() separator_line.setFrameShape(QtWidgets.QFrame.Shape.HLine) separator_line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken) - grid_par.addWidget(separator_line, 10, 0, 1, 3) + estimated_grid.addWidget(separator_line, 4, 0, 1, 3) + + self.estimated_frame.hide() + self.gp_frame.resize(self.gp_frame.minimumSizeHint()) + self.gp_frame.adjustSize() # CNC Code snippets self.snippets_cb = FCCheckBox(_("Use CNC Code Snippets")) @@ -1546,7 +1553,8 @@ class CNCObjectUI(ObjectUI): self.export_gcode_button.setToolTip( _("Opens dialog to save CNC Code file.") ) - self.export_gcode_button.setSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) + self.export_gcode_button.setSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, + QtWidgets.QSizePolicy.Policy.Minimum) g_export_lay.addWidget(self.export_gcode_button) self.review_gcode_button = QtWidgets.QToolButton() diff --git a/appObjects/FlatCAMCNCJob.py b/appObjects/FlatCAMCNCJob.py index 5d59bb15..df9689c9 100644 --- a/appObjects/FlatCAMCNCJob.py +++ b/appObjects/FlatCAMCNCJob.py @@ -365,9 +365,11 @@ class CNCJobObject(FlatCAMObj, CNCjob): tooldia = self.tools[t_id]['tooldia'] try: - offset_val = self.app.dec_format(float(dia_value['offset']), self.decimals) + self.z_cut + offset_val = self.app.dec_format(float(dia_value['offset']), self.decimals) + \ + float(dia_value['data']['tools_drill_cutz']) except KeyError: - offset_val = self.app.dec_format(float(dia_value['offset_z']), self.decimals) + self.z_cut + offset_val = self.app.dec_format(float(dia_value['offset_z']), self.decimals) + \ + float(dia_value['data']['tools_drill_cutz']) except ValueError: # for older loaded projects offset_val = self.z_cut @@ -412,7 +414,9 @@ class CNCJobObject(FlatCAMObj, CNCjob): # ## REMEMBER: THIS COLUMN IS HIDDEN IN OBJECTUI.PY # ## self.ui.exc_cnc_tools_table.setItem(row_no, 4, t_id_item_2) # Tool unique ID) self.ui.exc_cnc_tools_table.setItem(row_no, 5, cutz_item) - self.ui.exc_cnc_tools_table.setCellWidget(row_no, 6, plot_cnc_exc_item) + # add it only if there is any gcode in the tool storage + if dia_value['gcode_parsed']: + self.ui.exc_cnc_tools_table.setCellWidget(row_no, 6, plot_cnc_exc_item) row_no += 1 @@ -478,9 +482,7 @@ class CNCJobObject(FlatCAMObj, CNCjob): # this means that the object that created this CNCJob was an Excellon or Geometry try: if self.travel_distance: - self.ui.t_distance_label.show() - self.ui.t_distance_entry.setVisible(True) - self.ui.t_distance_entry.setDisabled(True) + self.ui.estimated_frame.show() self.ui.t_distance_entry.set_value(self.app.dec_format(self.travel_distance, self.decimals)) self.ui.units_label.setText(str(self.units).lower()) self.ui.units_label.setDisabled(True) diff --git a/app_Main.py b/app_Main.py index c6846f46..70801e22 100644 --- a/app_Main.py +++ b/app_Main.py @@ -11591,6 +11591,60 @@ class MenuFileHandlers(QtCore.QObject): app_obj_.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Failed to open"), filename)) return "fail" + # try to find from what kind of object this GCode was created + gcode_origin = 'Geometry' + match = re.search(r'^.*Type:\s*.*(\bGeometry\b|\bExcellon\b)', gcode, re.MULTILINE) + if match: + gcode_origin = match.group(1) + job_obj.obj_options['type'] = gcode_origin + # add at least one default tool + if 'excellon' in gcode_origin.lower(): + job_obj.tools = {1: {'data': {'tools_drill_ppname_e': 'default'}}} + if 'geometry' in gcode_origin.lower(): + job_obj.tools = {1: {'data': {'tools_mill_ppname_g': 'default'}}} + + # try to find from what kind of object this GCode was created + match = re.search(r'^.*Preprocessor:\s*.*\bGeometry\b|\bExcellon\b:\s(\b.*\b)', gcode, re.MULTILINE) + detected_preprocessor = 'default' + if match: + detected_preprocessor = match.group(1) + # determine if there is any tool data + match = re.findall(r'^.*Tool:\s*([0-9]*)\s*->\s*Dia:\s*(\d*\.?\d*)', gcode, re.MULTILINE) + if match: + job_obj.tools = {} + for m in match: + if 'excellon' in gcode_origin.lower(): + job_obj.tools[int(m[0])] = { + 'tooldia': float(m[1]), + 'nr_drills': 0, + 'nr_slots': 0, + 'offset_z': 0, + 'data': {'tools_drill_ppname_e': detected_preprocessor} + } + # if 'geometry' in gcode_origin.lower(): + # job_obj.tools[int(m[0])] = { + # 'tooldia': float(m[1]), + # 'data': { + # 'tools_mill_ppname_g': detected_preprocessor, + # 'tools_mill_offset_value': 0.0, + # 'tools_mill_job_type': _('Roughing'), + # 'tools_mill_tool_shape': "C1" + # + # } + # } + job_obj.used_tools = list(job_obj.tools.keys()) + # determine if there is any Cut Z data + match = re.findall(r'^.*Tool:\s*([0-9]*)\s*->\s*Z_Cut:\s*([\-|+]?\d*\.?\d*)', gcode, re.MULTILINE) + if match: + for m in match: + if 'excellon' in gcode_origin.lower(): + if int(m[0]) in job_obj.tools: + job_obj.tools[int(m[0])]['offset_z'] = 0.0 + job_obj.tools[int(m[0])]['data']['tools_drill_cutz'] = float(m[1]) + # if 'geometry' in gcode_origin.lower(): + # if int(m[0]) in job_obj.tools: + # job_obj.tools[int(m[0])]['data']['tools_mill_cutz'] = float(m[1]) + job_obj.gcode = gcode gcode_ret = job_obj.gcode_parse(force_parsing=force_parsing) @@ -11598,6 +11652,12 @@ class MenuFileHandlers(QtCore.QObject): self.inform.emit('[ERROR_NOTCL] %s' % _("This is not GCODE")) return "fail" + for k in job_obj.tools: + job_obj.tools[k]['gcode'] = gcode + job_obj.tools[k]['gcode_parsed'] = [] + + for k in job_obj.tools: + print(k, job_obj.tools[k]) job_obj.create_geometry() with self.app.proc_container.new('%s...' % _("Opening")): diff --git a/camlib.py b/camlib.py index 978d1773..3517bbd7 100644 --- a/camlib.py +++ b/camlib.py @@ -2837,7 +2837,7 @@ class CNCjob(Geometry): self.routing_time = 0.0 # store here the Excellon source object tools to be accessible locally - self.exc_tools = None + self.exc_tools = {} # search for toolchange parameters in the Toolchange Custom Code self.re_toolchange_custom = re.compile(r'(%[a-zA-Z0-9\-_]+%)') @@ -6663,7 +6663,7 @@ class CNCjob(Geometry): :param tool_data: when dealing with multi tool objects we need the tool data :type tool_data: dict :return: - :rtype: dict + :rtype: list """ kind = ["C", "F"] # T=travel, C=cut, F=fast, S=slow @@ -7069,6 +7069,8 @@ class CNCjob(Geometry): if tooldia == 0: for geo in gcode_parsed: + if not geo: + continue if kind == 'all': obj.add_shape(shape=geo['geom'], color=color[geo['kind'][0]][1], visible=visible) elif kind == 'travel': @@ -7084,6 +7086,9 @@ class CNCjob(Geometry): if self.coordinates_type == "G90": # For Absolute coordinates type G90 for geo in gcode_parsed: + if not geo: + continue + if geo['kind'][0] == 'T': start_position = geo['geom'].coords[0]