From 1c06c05c227d1ae7d75dfaa9aee4320b09b60f0a Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 19 Aug 2021 15:20:23 +0300 Subject: [PATCH] - cleaned up the Geometry and Gerber object classes - more cleanup in Isolation Plugin --- CHANGELOG.md | 2 + appGUI/preferences/PreferencesUIManager.py | 2 - .../preferences/tools/ToolsISOPrefGroupUI.py | 34 - appObjects/FlatCAMGeometry.py | 1805 ----------------- appObjects/FlatCAMGerber.py | 134 +- app_Main.py | 7 +- defaults.py | 2 - 7 files changed, 35 insertions(+), 1951 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 176284c8..372de187 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ CHANGELOG for FlatCAM beta 19.08.2021 - some cleaning up in the Preferences +- cleaned up the Geometry and Gerber object classes +- more cleanup in Isolation Plugin 18.08.2021 diff --git a/appGUI/preferences/PreferencesUIManager.py b/appGUI/preferences/PreferencesUIManager.py index a8e65b44..dc17b4f6 100644 --- a/appGUI/preferences/PreferencesUIManager.py +++ b/appGUI/preferences/PreferencesUIManager.py @@ -281,8 +281,6 @@ class PreferencesUIManager: # Isolation Routing Tool "tools_iso_tooldia": self.ui.plugin_eng_pref_form.tools_iso_group.tool_dia_entry, "tools_iso_order": self.ui.plugin_eng_pref_form.tools_iso_group.order_radio, - "tools_iso_tool_vtipdia": self.ui.plugin_eng_pref_form.tools_iso_group.tipdia_entry, - "tools_iso_tool_vtipangle": self.ui.plugin_eng_pref_form.tools_iso_group.tipangle_entry, "tools_iso_tool_cutz": self.ui.plugin_eng_pref_form.tools_iso_group.cutz_entry, "tools_iso_newdia": self.ui.plugin_eng_pref_form.tools_iso_group.newdia_entry, diff --git a/appGUI/preferences/tools/ToolsISOPrefGroupUI.py b/appGUI/preferences/tools/ToolsISOPrefGroupUI.py index f80e89d3..503856a9 100644 --- a/appGUI/preferences/tools/ToolsISOPrefGroupUI.py +++ b/appGUI/preferences/tools/ToolsISOPrefGroupUI.py @@ -60,40 +60,6 @@ class ToolsISOPrefGroupUI(OptionsGroupUI): grid0.addWidget(self.order_label, 2, 0) grid0.addWidget(self.order_radio, 2, 1, 1, 2) - # Tool Type Radio Button - self.tool_type_label = FCLabel('%s:' % _('Tool Type')) - self.tool_type_label.setToolTip( - _("Default tool type:\n" - "- 'V-shape'\n" - "- Circular") - ) - - # Tip Dia - self.tipdialabel = FCLabel('%s:' % _('V-Tip Dia')) - self.tipdialabel.setToolTip( - _("The tip diameter for V-Shape Tool")) - self.tipdia_entry = FCDoubleSpinner() - self.tipdia_entry.set_precision(self.decimals) - self.tipdia_entry.set_range(0, 1000) - self.tipdia_entry.setSingleStep(0.1) - - grid0.addWidget(self.tipdialabel, 6, 0) - grid0.addWidget(self.tipdia_entry, 6, 1, 1, 2) - - # Tip Angle - self.tipanglelabel = FCLabel('%s:' % _('V-Tip Angle')) - self.tipanglelabel.setToolTip( - _("The tip angle for V-Shape Tool.\n" - "In degrees.")) - self.tipangle_entry = FCDoubleSpinner() - self.tipangle_entry.set_precision(self.decimals) - self.tipangle_entry.set_range(1, 180) - self.tipangle_entry.setSingleStep(5) - self.tipangle_entry.setWrapping(True) - - grid0.addWidget(self.tipanglelabel, 8, 0) - grid0.addWidget(self.tipangle_entry, 8, 1, 1, 2) - # Cut Z entry cutzlabel = FCLabel('%s:' % _('Cut Z')) cutzlabel.setToolTip( diff --git a/appObjects/FlatCAMGeometry.py b/appObjects/FlatCAMGeometry.py index 805b8d3a..9c14a526 100644 --- a/appObjects/FlatCAMGeometry.py +++ b/appObjects/FlatCAMGeometry.py @@ -113,9 +113,6 @@ class GeometryObject(FlatCAMObj, Geometry): tool_id of the tools and the value is another dict that will hold the data under the following form: {tooluid: { 'tooldia': 1, - 'offset': 'Path', - 'offset_value': 0.0 - 'tool_type': 'C1', 'data': self.default_tool_data 'solid_geometry': [] } @@ -174,15 +171,6 @@ class GeometryObject(FlatCAMObj, Geometry): FlatCAMObj.build_ui(self) - # Area Exception - exclusion shape added signal - # first disconnect it from any other object - try: - self.app.exc_areas.e_shape_modified.disconnect() - except (TypeError, AttributeError): - pass - # then connect it to the current build_ui() method - self.app.exc_areas.e_shape_modified.connect(self.update_exclusion_table) - self.units = self.app.defaults['units'] row_idx = 0 @@ -290,8 +278,6 @@ class GeometryObject(FlatCAMObj, Geometry): selected_row = 0 try: self.select_tools_table_row(selected_row, clearsel=True) - # update the Geometry UI - # self.update_ui() except Exception as e: # when the tools table is empty there will be this error but once the table is populated it will go away self.app.log.error('GeometryObject.build_ui() -> %s' % str(e)) @@ -305,96 +291,6 @@ class GeometryObject(FlatCAMObj, Geometry): self.ui_connect() - # self.set_tool_offset_visibility(selected_row) - - # ############################################################################################################# - # ################################### Build Exclusion Areas section ########################################### - # ############################################################################################################# - # self.ui_disconnect() - # - # e_len = len(self.app.exc_areas.exclusion_areas_storage) - # self.ui.exclusion_table.setRowCount(e_len) - # - # for area in range(e_len): - # area_dict = self.app.exc_areas.exclusion_areas_storage[area] - # - # area_id_item = QtWidgets.QTableWidgetItem('%d' % int(area_dict["idx"])) - # area_id_item.setFlags(QtCore.Qt.ItemFlag.ItemIsSelectable | QtCore.Qt.ItemFlag.ItemIsEnabled) - # self.ui.exclusion_table.setItem(area, 0, area_id_item) # Area id - # - # object_item = QtWidgets.QTableWidgetItem('%s' % area_dict["obj_type"]) - # object_item.setFlags(QtCore.Qt.ItemFlag.ItemIsSelectable | QtCore.Qt.ItemFlag.ItemIsEnabled) - # self.ui.exclusion_table.setItem(area, 1, object_item) # Origin Object - # - # # strategy_item = QtWidgets.QTableWidgetItem('%s' % area_dict["strategy"]) - # # strategy_item.setFlags(QtCore.Qt.ItemFlag.ItemIsSelectable | QtCore.Qt.ItemFlag.ItemIsEnabled) - # strategy_item = FCComboBox2(policy=False) - # strategy_item.addItems([_("Around"), _("Over")]) - # idx = 0 if area_dict["strategy"] == 'around' else 1 - # # protection against having this translated or loading a project with translated values - # if idx == -1: - # strategy_item.setCurrentIndex(0) - # else: - # strategy_item.setCurrentIndex(idx) - # self.ui.exclusion_table.setCellWidget(area, 2, strategy_item) # Strategy - # - # overz_item = QtWidgets.QTableWidgetItem('%s' % area_dict["overz"]) - # overz_item.setFlags(QtCore.Qt.ItemFlag.ItemIsSelectable | QtCore.Qt.ItemFlag.ItemIsEnabled) - # self.ui.exclusion_table.setItem(area, 3, overz_item) # Over Z - # - # # make the Overz column editable - # for row in range(e_len): - # self.ui.exclusion_table.item(row, 3).setFlags(QtCore.Qt.ItemFlag.ItemIsSelectable | - # QtCore.Qt.ItemFlag.ItemIsEditable | - # QtCore.Qt.ItemFlag.ItemIsEnabled) - # - # self.ui.exclusion_table.resizeColumnsToContents() - # self.ui.exclusion_table.resizeRowsToContents() - # - # area_vheader = self.ui.exclusion_table.verticalHeader() - # area_vheader.hide() - # self.ui.exclusion_table.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) - # - # area_hheader = self.ui.exclusion_table.horizontalHeader() - # area_hheader.setMinimumSectionSize(10) - # area_hheader.setDefaultSectionSize(70) - # - # area_hheader.setSectionResizeMode(0, QtWidgets.QHeaderView.ResizeMode.Fixed) - # area_hheader.resizeSection(0, 20) - # area_hheader.setSectionResizeMode(1, QtWidgets.QHeaderView.ResizeMode.Stretch) - # area_hheader.setSectionResizeMode(2, QtWidgets.QHeaderView.ResizeMode.ResizeToContents) - # area_hheader.setSectionResizeMode(3, QtWidgets.QHeaderView.ResizeMode.ResizeToContents) - # - # # area_hheader.setStretchLastSection(True) - # self.ui.exclusion_table.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) - # - # self.ui.exclusion_table.setColumnWidth(0, 20) - # - # self.ui.exclusion_table.setMinimumHeight(self.ui.exclusion_table.getHeight()) - # self.ui.exclusion_table.setMaximumHeight(self.ui.exclusion_table.getHeight()) - # - # # End Build Exclusion Areas - # # ----------------------------- - # - # # HACK: for whatever reasons the name in Selected tab is reverted to the original one after a successful - # rename done in the collection view but only for Geometry objects. Perhaps some references remains. - # Should be fixed. - # self.ui.name_entry.set_value(self.options['name']) - # self.ui_connect() - # - # self.ui.e_cut_entry.setDisabled(False) if self.ui.extracut_cb.get_value() else \ - # self.ui.e_cut_entry.setDisabled(True) - # - # # set the text on tool_data_label after loading the object - # sel_rows = set() - # for it in self.ui.geo_tools_table.selectedItems(): - # sel_rows.add(it.row()) - # - # if len(sel_rows) > 1: - # self.ui.tool_data_label.setText( - # "%s: %s" % (_('Parameters for'), _("Multiple Tools")) - # ) - def set_ui(self, ui): # this one adds the 'name' key and the self.ui.name_entry widget in the self.form_fields dict FlatCAMObj.set_ui(self, ui) @@ -410,83 +306,14 @@ class GeometryObject(FlatCAMObj, Geometry): self.form_fields.update({ "plot": self.ui.plot_cb, "multicolored": self.ui.multicolored_cb, - # "cutz": self.ui.cutz_entry, - # "vtipdia": self.ui.tipdia_entry, - # "vtipangle": self.ui.tipangle_entry, - # "travelz": self.ui.travelz_entry, - # "feedrate": self.ui.cncfeedrate_entry, - # "feedrate_z": self.ui.feedrate_z_entry, - # "feedrate_rapid": self.ui.feedrate_rapid_entry, - # "spindlespeed": self.ui.cncspindlespeed_entry, - # "dwell": self.ui.dwell_cb, - # "dwelltime": self.ui.dwelltime_entry, - # "multidepth": self.ui.mpass_cb, - # "ppname_g": self.ui.pp_geometry_name_cb, - # "z_pdepth": self.ui.pdepth_entry, - # "feedrate_probe": self.ui.feedrate_probe_entry, - # "depthperpass": self.ui.maxdepth_entry, - # "extracut": self.ui.extracut_cb, - # "extracut_length": self.ui.e_cut_entry, - # "toolchange": self.ui.toolchangeg_cb, - # "toolchangez": self.ui.toolchangez_entry, - # "endz": self.ui.endz_entry, - # "endxy": self.ui.endxy_entry, - # "tools_mill_tooldia": self.ui.addtool_entry, - # "area_exclusion": self.ui.exclusion_cb, - # "area_shape": self.ui.area_shape_radio, - # "area_strategy": self.ui.strategy_radio, - # "area_overz": self.ui.over_z_entry, - # "polish": self.ui.polish_cb, - # "polish_dia": self.ui.polish_dia_entry, - # "polish_pressure": self.ui.polish_pressure_entry, - # "polish_travelz": self.ui.polish_travelz_entry, - # "polish_margin": self.ui.polish_margin_entry, - # "polish_overlap": self.ui.polish_over_entry, - # "polish_method": self.ui.polish_method_combo, }) - # self.param_fields.update({ - # "vtipdia": self.ui.tipdia_entry, - # "vtipangle": self.ui.tipangle_entry, - # "cutz": self.ui.cutz_entry, - # "depthperpass": self.ui.maxdepth_entry, - # "multidepth": self.ui.mpass_cb, - # "travelz": self.ui.travelz_entry, - # "feedrate": self.ui.cncfeedrate_entry, - # "feedrate_z": self.ui.feedrate_z_entry, - # "feedrate_rapid": self.ui.feedrate_rapid_entry, - # "extracut": self.ui.extracut_cb, - # "extracut_length": self.ui.e_cut_entry, - # "spindlespeed": self.ui.cncspindlespeed_entry, - # "dwelltime": self.ui.dwelltime_entry, - # "dwell": self.ui.dwell_cb, - # "pdepth": self.ui.pdepth_entry, - # "pfeedrate": self.ui.feedrate_probe_entry, - # }) # Fill form fields only on object create self.to_form() - # update the changes in UI depending on the selected preprocessor in Preferences - # after this moment all the changes in the Posprocessor combo will be handled by the activated signal of the - # self.ui.pp_geometry_name_cb combobox - # self.on_pp_changed() - - # self.ui.tipdialabel.hide() - # self.ui.tipdia_entry.hide() - # self.ui.tipanglelabel.hide() - # self.ui.tipangle_entry.hide() - # self.ui.cutz_entry.setDisabled(False) - # store here the default data for Geometry Data self.default_data = {} - # for opt_key, opt_val in self.options.items(): - # if opt_key.find('geometry' + "_") == 0: - # oname = opt_key[len('geometry') + 1:] - # self.default_data[oname] = self.app.options[opt_key] - # elif opt_key.find('tools_') == 0: - # self.default_data[opt_key] = self.app.options[opt_key] - # fill in self.default_data values from self.options self.default_data.update(self.options) @@ -531,34 +358,10 @@ class GeometryObject(FlatCAMObj, Geometry): self.tools.clear() self.tools = deepcopy(temp_tools) - # self.ui.tool_offset_entry.hide() - # self.ui.tool_offset_lbl.hide() - - # used to store the state of the mpass_cb if the selected preprocessor for geometry is hpgl - # self.old_pp_state = self.default_data['multidepth'] - # self.old_toolchangeg_state = self.default_data['toolchange'] - if not isinstance(self.ui, GeometryObjectUI): self.app.log.debug("Expected a GeometryObjectUI, got %s" % type(self.ui)) return - # ############################################################################################################# - # ############################### TOOLS TABLE context menu #################################################### - # ############################################################################################################# - # self.ui.geo_tools_table.setupContextMenu() - # self.ui.geo_tools_table.addContextMenu( - # _("Pick from DB"), self.on_tool_add_from_db_clicked, - # icon=QtGui.QIcon(self.app.resource_location + "/plus16.png")) - # self.ui.geo_tools_table.addContextMenu( - # _("Copy"), self.on_tool_copy, - # icon=QtGui.QIcon(self.app.resource_location + "/copy16.png")) - # self.ui.geo_tools_table.addContextMenu( - # _("Delete"), lambda: self.on_tool_delete(clicked_signal=None, all_tools=None), - # icon=QtGui.QIcon(self.app.resource_location + "/trash16.png")) - - # self.ui.geo_tools_table.setColumnHidden(2, True) - # self.ui.geo_tools_table.setColumnHidden(3, True) - # ############################################################################################################# # ##################################### Setting Values######################################################### # ############################################################################################################# @@ -568,12 +371,6 @@ class GeometryObject(FlatCAMObj, Geometry): # ############################################################################################################# # ################################ Signals Connection ######################################################### # ############################################################################################################# - # self.builduiSig.connect(self.build_ui) - # - # self.ui.e_cut_entry.setDisabled(False) if self.app.defaults['geometry_extracut'] else \ - # self.ui.e_cut_entry.setDisabled(True) - # self.ui.extracut_cb.toggled.connect(lambda state: self.ui.e_cut_entry.setDisabled(not state)) - self.ui.level.toggled.connect(self.on_level_changed) # Plot state signals @@ -590,7 +387,6 @@ class GeometryObject(FlatCAMObj, Geometry): self.ui.treeWidget.itemCollapsed.connect(self.on_properties_expanded) # # Buttons Signals - # self.ui.generate_cnc_button.clicked.connect(self.on_generatecnc_button_click) self.ui.paint_tool_button.clicked.connect(lambda: self.app.paint_tool.run(toggle=True)) self.ui.generate_ncc_button.clicked.connect(lambda: self.app.ncclear_tool.run(toggle=True)) self.ui.milling_button.clicked.connect(self.on_milling_button_clicked) @@ -599,32 +395,6 @@ class GeometryObject(FlatCAMObj, Geometry): self.ui.vertex_points_btn.clicked.connect(self.on_calculate_vertex_points) self.ui.simplification_btn.clicked.connect(self.on_simplify_geometry) - # # Postprocessor change - # self.ui.pp_geometry_name_cb.activated.connect(self.on_pp_changed) - # - # # V tool shape params changed - # self.ui.tipdia_entry.valueChanged.connect(self.on_update_cutz) - # self.ui.tipangle_entry.valueChanged.connect(self.on_update_cutz) - # - # self.ui.addtool_from_db_btn.clicked.connect(self.on_tool_add_from_db_clicked) - # self.ui.apply_param_to_all.clicked.connect(self.on_apply_param_to_all_clicked) - # self.ui.cutz_entry.returnPressed.connect(self.on_cut_z_changed) - # - # # Exclusion areas signals - # self.ui.exclusion_table.horizontalHeader().sectionClicked.connect(self.on_exclusion_table_toggle_all) - # self.ui.exclusion_table.lost_focus.connect(self.on_clear_selection) - # self.ui.exclusion_table.itemClicked.connect(self.on_draw_sel_shape) - # self.ui.add_area_button.clicked.connect(self.on_add_area_click) - # self.ui.delete_area_button.clicked.connect(self.on_clear_area_click) - # self.ui.delete_sel_area_button.clicked.connect(self.on_delete_sel_areas) - # self.ui.strategy_radio.activated_custom.connect(self.on_strategy) - # - # # Tools Table signals - # self.ui.geo_tools_table.drag_drop_sig.connect(self.on_rebuild_ui) - # self.ui.geo_tools_table.horizontalHeader().sectionClicked.connect(self.on_toggle_all_rows) - # - # self.launch_job.connect(self.mtool_gen_cncjob) - self.set_offset_values() # Show/Hide Advanced Options @@ -747,188 +517,13 @@ class GeometryObject(FlatCAMObj, Geometry): self.app.worker_task.emit({'fcn': task_job, 'params': []}) - def on_rebuild_ui(self): - # read the table tools uid - current_uid_list = [] - for row in range(self.ui.geo_tools_table.rowCount()): - uid = int(self.ui.geo_tools_table.item(row, 5).text()) - current_uid_list.append(uid) - - new_tools = {} - new_uid = 1 - - for current_uid in current_uid_list: - new_tools[new_uid] = deepcopy(self.tools[current_uid]) - new_uid += 1 - - self.tools = new_tools - - # the tools table changed therefore we need to reconnect the signals to the cellWidgets - self.ui_disconnect() - self.ui_connect() - - def on_cut_z_changed(self): - self.old_cutz = self.ui.cutz_entry.get_value() - - def set_tool_offset_visibility(self, current_row): - if current_row is None: - return - try: - tool_offset = self.ui.geo_tools_table.cellWidget(current_row, 2) - if tool_offset is not None: - tool_offset_txt = tool_offset.currentText() - if tool_offset_txt == 'Custom': - self.ui.tool_offset_entry.show() - self.ui.tool_offset_lbl.show() - else: - self.ui.tool_offset_entry.hide() - self.ui.tool_offset_lbl.hide() - except Exception as e: - self.app.log.error("set_tool_offset_visibility() --> " + str(e)) - return - - def on_offset_value_edited(self): - """ - This will save the offset_value into self.tools storage whenever the offset value is edited - :return: - """ - - for current_row in self.ui.geo_tools_table.selectedItems(): - # sometime the header get selected and it has row number -1 - # we don't want to do anything with the header :) - if current_row.row() < 0: - continue - tool_uid = int(self.ui.geo_tools_table.item(current_row.row(), 5).text()) - self.set_tool_offset_visibility(current_row.row()) - - for tooluid_key, tooluid_value in self.tools.items(): - if int(tooluid_key) == tool_uid: - try: - tooluid_value['offset_value'] = float(self.ui.tool_offset_entry.get_value()) - except ValueError: - # try to convert comma to decimal point. if it's still not working error message and return - try: - tooluid_value['offset_value'] = float( - self.ui.tool_offset_entry.get_value().replace(',', '.') - ) - except ValueError: - self.app.inform.emit('[ERROR_NOTCL] %s' % _("Wrong value format entered, use a number.")) - return - def ui_connect(self): - # on any change to the widgets that matter it will be called self.gui_form_to_storage which will save the - # changes in geometry UI - # for i in self.param_fields: - # current_widget = self.param_fields[i] - # - # if isinstance(current_widget, FCCheckBox): - # current_widget.stateChanged.connect(self.gui_form_to_storage) - # elif isinstance(current_widget, FCComboBox): - # current_widget.currentIndexChanged.connect(self.gui_form_to_storage) - # elif isinstance(current_widget, FloatEntry) or isinstance(current_widget, LengthEntry) or \ - # isinstance(current_widget, FCEntry) or isinstance(current_widget, IntEntry) or \ - # isinstance(current_widget, NumericalEvalTupleEntry): - # current_widget.editingFinished.connect(self.gui_form_to_storage) - # elif isinstance(current_widget, FCSpinner) or isinstance(current_widget, FCDoubleSpinner): - # current_widget.returnPressed.connect(self.gui_form_to_storage) - # - # for row in range(self.ui.geo_tools_table.rowCount()): - # for col in [2, 3, 4]: - # self.ui.geo_tools_table.cellWidget(row, col).currentIndexChanged.connect( - # self.on_tooltable_cellwidget_change) - # - # self.ui.search_and_add_btn.clicked.connect(self.on_tool_add) - # self.ui.deltool_btn.clicked.connect(self.on_tool_delete) - - # Tools Table - # self.ui.geo_tools_table.clicked.connect(self.on_row_selection_change) - # self.ui.geo_tools_table.itemChanged.connect(self.on_tool_edit) - # - # self.ui.tool_offset_entry.returnPressed.connect(self.on_offset_value_edited) - for row in range(self.ui.geo_tools_table.rowCount()): self.ui.geo_tools_table.cellWidget(row, 6).clicked.connect(self.on_plot_cb_click_table) self.ui.plot_cb.stateChanged.connect(self.on_plot_cb_click) - # Exclusion Table widgets connect - # for row in range(self.ui.exclusion_table.rowCount()): - # self.ui.exclusion_table.cellWidget(row, 2).currentIndexChanged.connect(self.on_exclusion_table_strategy) - # - # self.ui.exclusion_table.itemChanged.connect(self.on_exclusion_table_overz) - - # common parameters update - # self.ui.toolchangeg_cb.stateChanged.connect(self.update_common_param_in_storage) - # self.ui.toolchangez_entry.editingFinished.connect(self.update_common_param_in_storage) - # self.ui.endz_entry.editingFinished.connect(self.update_common_param_in_storage) - # self.ui.endxy_entry.editingFinished.connect(self.update_common_param_in_storage) - # self.ui.pp_geometry_name_cb.currentIndexChanged.connect(self.update_common_param_in_storage) - # self.ui.exclusion_cb.stateChanged.connect(self.update_common_param_in_storage) - # self.ui.polish_cb.stateChanged.connect(self.update_common_param_in_storage) - def ui_disconnect(self): - - # on any change to the widgets that matter it will be called self.gui_form_to_storage which will save the - # changes in geometry UI - # for i in self.param_fields: - # # current_widget = self.ui.grid3.itemAt(i).widget() - # current_widget = self.param_fields[i] - # if isinstance(current_widget, FCCheckBox): - # try: - # current_widget.stateChanged.disconnect(self.gui_form_to_storage) - # except (TypeError, AttributeError): - # pass - # elif isinstance(current_widget, FCComboBox): - # try: - # current_widget.currentIndexChanged.disconnect(self.gui_form_to_storage) - # except (TypeError, AttributeError): - # pass - # elif isinstance(current_widget, LengthEntry) or isinstance(current_widget, IntEntry) or \ - # isinstance(current_widget, FCEntry) or isinstance(current_widget, FloatEntry) or \ - # isinstance(current_widget, NumericalEvalTupleEntry): - # try: - # current_widget.editingFinished.disconnect(self.gui_form_to_storage) - # except (TypeError, AttributeError): - # pass - # elif isinstance(current_widget, FCSpinner) or isinstance(current_widget, FCDoubleSpinner): - # try: - # current_widget.returnPressed.disconnect(self.gui_form_to_storage) - # except TypeError: - # pass - - # disconnect FCCombobox widgets in the Tool Table - # for row in range(self.ui.geo_tools_table.rowCount()): - # for col in [2, 3, 4]: - # try: - # self.ui.geo_tools_table.cellWidget(row, col).currentIndexChanged.disconnect() - # except (TypeError, AttributeError): - # pass - - # try: - # self.ui.search_and_add_btn.clicked.disconnect() - # except (TypeError, AttributeError): - # pass - # - # try: - # self.ui.deltool_btn.clicked.disconnect() - # except (TypeError, AttributeError): - # pass - - # try: - # self.ui.geo_tools_table.clicked.disconnect() - # except (TypeError, AttributeError): - # pass - # - # try: - # self.ui.geo_tools_table.itemChanged.disconnect() - # except (TypeError, AttributeError): - # pass - # - # try: - # self.ui.tool_offset_entry.returnPressed.disconnect() - # except (TypeError, AttributeError): - # pass - for row in range(self.ui.geo_tools_table.rowCount()): try: self.ui.geo_tools_table.cellWidget(row, 6).clicked.disconnect() @@ -940,935 +535,6 @@ class GeometryObject(FlatCAMObj, Geometry): except (TypeError, AttributeError): pass - # common parameters update - # try: - # self.ui.toolchangeg_cb.stateChanged.disconnect(self.update_common_param_in_storage) - # except (TypeError, AttributeError): - # pass - # try: - # self.ui.toolchangez_entry.editingFinished.disconnect(self.update_common_param_in_storage) - # except (TypeError, AttributeError): - # pass - # try: - # self.ui.endz_entry.editingFinished.disconnect(self.update_common_param_in_storage) - # except (TypeError, AttributeError): - # pass - # try: - # self.ui.endxy_entry.editingFinished.disconnect(self.update_common_param_in_storage) - # except (TypeError, AttributeError): - # pass - # try: - # self.ui.pp_geometry_name_cb.currentIndexChanged.disconnect(self.update_common_param_in_storage) - # except (TypeError, AttributeError): - # pass - # - # try: - # self.ui.polish_cb.stateChanged.disconnect(self.update_common_param_in_storage) - # except (TypeError, AttributeError): - # pass - # - # try: - # self.ui.exclusion_cb.stateChanged.disconnect(self.update_common_param_in_storage) - # except (TypeError, AttributeError): - # pass - # - # # Exclusion Table widgets disconnect - # for row in range(self.ui.exclusion_table.rowCount()): - # try: - # self.ui.exclusion_table.cellWidget(row, 2).currentIndexChanged.disconnect() - # except (TypeError, AttributeError): - # pass - # - # try: - # self.ui.exclusion_table.itemChanged.disconnect() - # except (TypeError, AttributeError): - # pass - - def on_toggle_all_rows(self): - """ - will toggle the selection of all rows in Tools table - - :return: - """ - sel_model = self.ui.geo_tools_table.selectionModel() - sel_indexes = sel_model.selectedIndexes() - - # it will iterate over all indexes which means all items in all columns too but I'm interested only on rows - sel_rows = set() - for idx in sel_indexes: - sel_rows.add(idx.row()) - - if len(sel_rows) == self.ui.geo_tools_table.rowCount(): - self.ui.geo_tools_table.clearSelection() - self.ui.tool_data_label.setText( - "%s: %s" % (_('Parameters for'), _("No Tool Selected")) - ) - else: - self.ui.geo_tools_table.selectAll() - self.ui.tool_data_label.setText( - "%s: %s" % (_('Parameters for'), _("Multiple Tools")) - ) - - def on_row_selection_change(self): - sel_model = self.ui.geo_tools_table.selectionModel() - sel_indexes = sel_model.selectedIndexes() - - # it will iterate over all indexes which means all items in all columns too but I'm interested only on rows - sel_rows = set() - for idx in sel_indexes: - sel_rows.add(idx.row()) - - # update UI only if only one row is selected otherwise having multiple rows selected will deform information - # for the rows other that the current one (first selected) - if len(sel_rows) == 1: - self.update_ui() - - def update_ui(self, row=None): - self.ui_disconnect() - - if row is None: - sel_rows = set() - for it in self.ui.geo_tools_table.selectedItems(): - sel_rows.add(it.row()) - sel_rows = list(sel_rows) - else: - sel_rows = row if type(row) == list else [row] - - if not sel_rows: - self.ui.generate_cnc_button.setDisabled(True) - self.ui.tool_data_label.setText( - "%s: %s" % (_('Parameters for'), _("No Tool Selected")) - ) - self.ui_connect() - return - else: - self.ui.generate_cnc_button.setDisabled(False) - - # ############################################################################################################# - # update the QLabel that shows for which Tool we have the parameters in the UI form - # ############################################################################################################# - if len(sel_rows) == 1: - current_row = sel_rows[0] - - # populate the form with the data from the tool associated with the row parameter - try: - item = self.ui.geo_tools_table.item(current_row, 5) - if type(item) is not None: - tooluid = int(item.text()) - else: - self.ui_connect() - return - except Exception as e: - self.app.log.error("Tool missing. Add a tool in Geo Tool Table. %s" % str(e)) - self.ui_connect() - return - - self.ui.tool_data_label.setText( - "%s: %s %d" % (_('Parameters for'), _("Tool"), tooluid) - ) - else: - self.ui.tool_data_label.setText( - "%s: %s" % (_('Parameters for'), _("Multiple Tools")) - ) - - for current_row in sel_rows: - self.set_tool_offset_visibility(current_row) - - # ######################################################################################################### - # determine the tool UID - # ######################################################################################################### - try: - item = self.ui.geo_tools_table.item(current_row, 5) - if type(item) is not None: - tooluid = int(item.text()) - else: - self.ui_connect() - return - except Exception as e: - self.app.log.error("Tool missing. Add a tool in Geo Tool Table. %s" % str(e)) - self.ui_connect() - return - - # ######################################################################################################### - # update the form with the V-Shape fields if V-Shape selected in the geo_plugin_table - # also modify the Cut Z form entry to reflect the calculated Cut Z from values got from V-Shape Fields - # ######################################################################################################### - try: - item = self.ui.geo_tools_table.cellWidget(current_row, 4) - if item is not None: - tool_type_txt = item.currentText() - self.ui_update_v_shape(tool_type_txt=tool_type_txt) - else: - self.ui_connect() - return - except Exception as e: - self.app.log.error("Tool missing in ui_update_v_shape(). Add a tool in Geo Tool Table. %s" % str(e)) - return - - # ######################################################################################################### - # set the FORM data - # ######################################################################################################### - try: - # set the form with data from the newly selected tool - for tooluid_key, tooluid_value in list(self.tools.items()): - if int(tooluid_key) == tooluid: - for key, value in list(tooluid_value.items()): - if key == 'data': - form_value_storage = tooluid_value['data'] - self.update_form(form_value_storage) - if key == 'offset_value': - # update the offset value in the entry even if the entry is hidden - self.ui.tool_offset_entry.set_value(tooluid_value['offset_value']) - - if key == 'tool_type' and value == 'V': - self.on_update_cutz() - except Exception as e: - self.app.log.error("GeometryObject.update_ui() -> %s " % str(e)) - - self.ui_connect() - - def on_tool_add(self, clicked_state, dia=None, new_geo=None): - self.app.log.debug("GeometryObject.on_add_tool()") - - self.ui_disconnect() - - filename = self.app.tools_database_path() - - tool_dia = dia if dia is not None else self.ui.addtool_entry.get_value() - - # construct a list of all 'tooluid' in the self.iso_tools - tool_uid_list = [int(tooluid_key) for tooluid_key in self.tools] - - # find maximum from the temp_uid, add 1 and this is the new 'tooluid' - max_uid = 0 if not tool_uid_list else max(tool_uid_list) - tooluid = int(max_uid) + 1 - - new_tools_dict = deepcopy(self.default_data) - updated_tooldia = None - - # determine the new tool diameter - if tool_dia is None or tool_dia == 0: - self.build_ui() - self.app.inform.emit('[WARNING_NOTCL] %s' % _("Please enter a tool diameter with non-zero value, " - "in Float format.")) - self.ui_connect() - return - truncated_tooldia = self.app.dec_format(tool_dia, self.decimals) - - # load the database tools from the file - try: - with open(filename) as f: - tools = f.read() - except IOError: - self.app.log.error("Could not load tools DB file.") - self.app.inform.emit('[ERROR] %s' % _("Could not load Tools DB file.")) - self.ui_connect() - self.on_tool_default_add(dia=tool_dia) - return - - try: - # store here the tools from Tools Database when searching in Tools Database - tools_db_dict = json.loads(tools) - except Exception: - e = sys.exc_info()[0] - self.app.log.error(str(e)) - self.app.inform.emit('[ERROR] %s' % _("Failed to parse Tools DB file.")) - self.ui_connect() - self.on_tool_default_add(dia=tool_dia) - return - - tool_found = 0 - - offset = 'Path' - offset_val = 0.0 - - # look in database tools - for db_tool, db_tool_val in tools_db_dict.items(): - db_tooldia = db_tool_val['tooldia'] - low_limit = float(db_tool_val['data']['tol_min']) - high_limit = float(db_tool_val['data']['tol_max']) - - # we need only tool marked for Milling Tool (Geometry Object) - if db_tool_val['data']['tool_target'] != 1: # _('Milling') - continue - - # if we find a tool with the same diameter in the Tools DB just update it's data - if truncated_tooldia == db_tooldia: - tool_found += 1 - for d in db_tool_val['data']: - if d.find('tools_mill_') == 0: - new_tools_dict[d] = db_tool_val['data'][d] - elif d.find('tools_') == 0: - # don't need data for other App Tools; this tests after 'tools_mill_' - continue - else: - new_tools_dict[d] = db_tool_val['data'][d] - # search for a tool that has a tolerance that the tool fits in - elif high_limit >= truncated_tooldia >= low_limit: - tool_found += 1 - updated_tooldia = db_tooldia - for d in db_tool_val['data']: - if d.find('tools_mill_') == 0: - new_tools_dict[d] = db_tool_val['data'][d] - elif d.find('tools_') == 0: - # don't need data for other App Tools; this tests after 'tools_mill_' - continue - else: - new_tools_dict[d] = db_tool_val['data'][d] - - # test we found a suitable tool in Tools Database or if multiple ones - if tool_found == 0: - self.app.inform.emit('[WARNING_NOTCL] %s' % _("Tool not in Tools Database. Adding a default tool.")) - self.on_tool_default_add(dia=tool_dia, new_geo=new_geo) - self.ui_connect() - return - - if tool_found > 1: - self.app.inform.emit( - '[WARNING_NOTCL] %s' % _("Cancelled.\n" - "Multiple tools for one tool diameter found in Tools Database.")) - self.ui_connect() - return - - new_tdia = deepcopy(updated_tooldia) if updated_tooldia is not None else deepcopy(truncated_tooldia) - self.tools.update({ - tooluid: { - 'tooldia': new_tdia, - 'data': deepcopy(new_tools_dict), - 'solid_geometry': self.solid_geometry - } - }) - self.ui_connect() - self.build_ui() - - # select the tool just added - for row in range(self.ui.geo_tools_table.rowCount()): - if int(self.ui.geo_tools_table.item(row, 5).text()) == tooluid: - self.ui.geo_tools_table.selectRow(row) - break - - # update the UI form - self.update_ui() - - # if there is at least one tool left in the Tools Table, enable the parameters GUI - if self.ui.geo_tools_table.rowCount() != 0: - self.ui.geo_param_frame.setDisabled(False) - - self.app.inform.emit('[success] %s' % _("New tool added to Tool Table from Tools Database.")) - - def on_tool_default_add(self, dia=None, new_geo=None, muted=None): - self.ui_disconnect() - - tooldia = dia if dia is not None else self.ui.addtool_entry.get_value() - tool_uid_list = [int(tooluid_key) for tooluid_key in self.tools] - - # find maximum from the temp_uid, add 1 and this is the new 'tooluid' - max_uid = max(tool_uid_list) if tool_uid_list else 0 - self.tooluid = int(max_uid) + 1 - - tooldia = self.app.dec_format(tooldia, self.decimals) - - # here we actually add the new tool; if there is no tool in the tool table we add a tool with default data - # otherwise we add a tool with data copied from last tool - if self.tools: - last_data = self.tools[max_uid]['data'] - # last_offset = self.tools[max_uid]['offset'] - # last_offset_value = self.tools[max_uid]['offset_value'] - # last_tool_type = self.tools[max_uid]['data']['tools_mill_tool_shape'] - - last_solid_geometry = self.tools[max_uid]['solid_geometry'] if new_geo is None else new_geo - - # if previous geometry was empty (it may happen for the first tool added) - # then copy the object.solid_geometry - if not last_solid_geometry: - last_solid_geometry = self.solid_geometry - - self.tools.update({ - self.tooluid: { - 'tooldia': tooldia, - 'data': deepcopy(last_data), - 'solid_geometry': deepcopy(last_solid_geometry) - } - }) - else: - self.tools.update({ - self.tooluid: { - 'tooldia': tooldia, - 'data': deepcopy(self.default_data), - 'solid_geometry': self.solid_geometry - } - }) - - self.tools[self.tooluid]['data']['name'] = deepcopy(self.options['name']) - - self.ui.tool_offset_entry.hide() - self.ui.tool_offset_lbl.hide() - - # we do this HACK to make sure the tools attribute to be serialized is updated in the self.ser_attrs list - try: - self.ser_attrs.remove('tools') - except TypeError: - pass - self.ser_attrs.append('tools') - - if muted is None: - self.app.inform.emit('[success] %s' % _("Tool added in Tool Table.")) - self.ui_connect() - self.build_ui() - - # if there is at least one tool left in the Tools Table, enable the parameters GUI - if self.ui.geo_tools_table.rowCount() != 0: - self.ui.geo_param_frame.setDisabled(False) - - def on_tool_add_from_db_clicked(self): - """ - Called when the user wants to add a new tool from Tools Database. It will create the Tools Database object - and display the Tools Database tab in the form needed for the Tool adding - :return: None - """ - - # if the Tools Database is already opened focus on it - for idx in range(self.app.ui.plot_tab_area.count()): - if self.app.ui.plot_tab_area.tabText(idx) == _("Tools Database"): - self.app.ui.plot_tab_area.setCurrentWidget(self.app.tools_db_tab) - break - ret_val = self.app.on_tools_database() - if ret_val == 'fail': - return - self.app.tools_db_tab.ok_to_add = True - self.app.tools_db_tab.ui.buttons_frame.hide() - self.app.tools_db_tab.ui.add_tool_from_db.show() - self.app.tools_db_tab.ui.cancel_tool_from_db.show() - - def on_tool_from_db_inserted(self, tool): - """ - Called from the Tools DB object through a App method when adding a tool from Tools Database - :param tool: a dict with the tool data - :return: None - """ - - self.ui_disconnect() - self.units = self.app.defaults['units'].upper() - - tooldia = float(tool['tooldia']) - - # construct a list of all 'tooluid' in the self.tools - tool_uid_list = [] - for tooluid_key in self.tools: - tool_uid_item = int(tooluid_key) - tool_uid_list.append(tool_uid_item) - - # find maximum from the temp_uid, add 1 and this is the new 'tooluid' - if not tool_uid_list: - max_uid = 0 - else: - max_uid = max(tool_uid_list) - self.tooluid = max_uid + 1 - - tooldia = float('%.*f' % (self.decimals, tooldia)) - - self.tools.update({ - self.tooluid: { - 'tooldia': tooldia, - 'data': deepcopy(tool['data']), - 'solid_geometry': self.solid_geometry - } - }) - - self.tools[self.tooluid]['data']['name'] = deepcopy(self.options['name']) - - self.ui.tool_offset_entry.hide() - self.ui.tool_offset_lbl.hide() - - # we do this HACK to make sure the tools attribute to be serialized is updated in the self.ser_attrs list - try: - self.ser_attrs.remove('tools') - except TypeError: - pass - self.ser_attrs.append('tools') - - self.ui_connect() - self.build_ui() - - # if there is no tool left in the Tools Table, enable the parameters appGUI - if self.ui.geo_tools_table.rowCount() != 0: - self.ui.geo_param_frame.setDisabled(False) - - def on_tool_copy(self, all_tools=None): - self.ui_disconnect() - - # find the tool_uid maximum value in the self.tools - uid_list = [] - for key in self.tools: - uid_list.append(int(key)) - try: - max_uid = max(uid_list, key=int) - except ValueError: - max_uid = 0 - - if all_tools is None: - if self.ui.geo_tools_table.selectedItems(): - for current_row in self.ui.geo_tools_table.selectedItems(): - # sometime the header get selected and it has row number -1 - # we don't want to do anything with the header :) - if current_row.row() < 0: - continue - try: - tooluid_copy = int(self.ui.geo_tools_table.item(current_row.row(), 5).text()) - self.set_tool_offset_visibility(current_row.row()) - max_uid += 1 - self.tools[int(max_uid)] = deepcopy(self.tools[tooluid_copy]) - except AttributeError: - self.app.inform.emit('[WARNING_NOTCL] %s' % _("Failed. Select a tool to copy.")) - self.ui_connect() - self.builduiSig.emit() - return - except Exception as e: - self.app.log.error("on_tool_copy() --> " + str(e)) - # deselect the table - # self.ui.geo_tools_table.clearSelection() - else: - self.app.inform.emit('[WARNING_NOTCL] %s' % _("Failed. Select a tool to copy.")) - self.ui_connect() - self.builduiSig.emit() - return - else: - # we copy all tools in geo_tools_table - try: - temp_tools = deepcopy(self.tools) - max_uid += 1 - for tooluid in temp_tools: - self.tools[int(max_uid)] = deepcopy(temp_tools[tooluid]) - temp_tools.clear() - except Exception as e: - self.app.log.error("on_tool_copy() --> " + str(e)) - - # if there are no more tools in geo tools table then hide the tool offset - if not self.tools: - self.ui.tool_offset_entry.hide() - self.ui.tool_offset_lbl.hide() - - # we do this HACK to make sure the tools attribute to be serialized is updated in the self.ser_attrs list - try: - self.ser_attrs.remove('tools') - except ValueError: - pass - self.ser_attrs.append('tools') - - self.ui_connect() - self.builduiSig.emit() - self.app.inform.emit('[success] %s' % _("Tool was copied in Tool Table.")) - - def on_tool_edit(self, current_item): - self.ui_disconnect() - - current_row = current_item.row() - try: - d = float(self.ui.geo_tools_table.item(current_row, 1).text()) - except ValueError: - # try to convert comma to decimal point. if it's still not working error message and return - try: - d = float(self.ui.geo_tools_table.item(current_row, 1).text().replace(',', '.')) - except ValueError: - self.app.inform.emit('[ERROR_NOTCL] %s' % _("Wrong value format entered, use a number.")) - return - except AttributeError: - self.ui_connect() - return - - tool_dia = float('%.*f' % (self.decimals, d)) - tooluid = int(self.ui.geo_tools_table.item(current_row, 5).text()) - - self.tools[tooluid]['tooldia'] = tool_dia - - try: - self.ser_attrs.remove('tools') - self.ser_attrs.append('tools') - except (TypeError, ValueError, RuntimeError): - pass - - self.app.inform.emit('[success] %s' % _("Tool was edited in Tool Table.")) - self.ui_connect() - self.builduiSig.emit() - - def on_tool_delete(self, clicked_signal, all_tools=None): - """ - It's important to keep the not clicked_signal parameter otherwise the signal will go to the all_tools - parameter and I might get all the tool deleted - """ - self.ui_disconnect() - - if all_tools is None: - if self.ui.geo_tools_table.selectedItems(): - for current_row in self.ui.geo_tools_table.selectedItems(): - # sometime the header get selected and it has row number -1 - # we don't want to do anything with the header :) - if current_row.row() < 0: - continue - try: - tooluid_del = int(self.ui.geo_tools_table.item(current_row.row(), 5).text()) - self.set_tool_offset_visibility(current_row.row()) - - temp_tools = deepcopy(self.tools) - for tooluid_key in self.tools: - if int(tooluid_key) == tooluid_del: - # if the self.tools has only one tool and we delete it then we move the solid_geometry - # as a property of the object otherwise there will be nothing to hold it - if len(self.tools) == 1: - self.solid_geometry = deepcopy(self.tools[tooluid_key]['solid_geometry']) - temp_tools.pop(tooluid_del, None) - self.tools = deepcopy(temp_tools) - temp_tools.clear() - except AttributeError: - self.app.inform.emit('[WARNING_NOTCL] %s' % _("Failed. Select a tool to delete.")) - self.ui_connect() - self.builduiSig.emit() - return - except Exception as e: - self.app.log.error("on_tool_delete() --> " + str(e)) - # deselect the table - # self.ui.geo_tools_table.clearSelection() - else: - self.app.inform.emit('[WARNING_NOTCL] %s' % _("Failed. Select a tool to delete.")) - self.ui_connect() - self.builduiSig.emit() - return - else: - # we delete all tools in geo_tools_table - self.tools.clear() - - self.app.plot_all() - - # if there are no more tools in geo tools table then hide the tool offset - if not self.tools: - self.ui.tool_offset_entry.hide() - self.ui.tool_offset_lbl.hide() - - # we do this HACK to make sure the tools attribute to be serialized is updated in the self.ser_attrs list - try: - self.ser_attrs.remove('tools') - except TypeError: - pass - self.ser_attrs.append('tools') - - self.ui_connect() - self.build_ui() - self.app.inform.emit('[success] %s' % _("Tool was deleted in Tool Table.")) - - obj_active = self.app.collection.get_active() - # if the object was MultiGeo and now it has no tool at all (therefore no geometry) - # we make it back SingleGeo - if self.ui.geo_tools_table.rowCount() <= 0: - obj_active.multigeo = False - obj_active.options['xmin'] = 0 - obj_active.options['ymin'] = 0 - obj_active.options['xmax'] = 0 - obj_active.options['ymax'] = 0 - - if obj_active.multigeo is True: - try: - xmin, ymin, xmax, ymax = obj_active.bounds() - obj_active.options['xmin'] = xmin - obj_active.options['ymin'] = ymin - obj_active.options['xmax'] = xmax - obj_active.options['ymax'] = ymax - except Exception: - obj_active.options['xmin'] = 0 - obj_active.options['ymin'] = 0 - obj_active.options['xmax'] = 0 - obj_active.options['ymax'] = 0 - - # if there is no tool left in the Tools Table, disable the parameters appGUI - if self.ui.geo_tools_table.rowCount() == 0: - self.ui.geo_param_frame.setDisabled(True) - - def ui_update_v_shape(self, tool_type_txt): - if tool_type_txt == 'V': - self.ui.tipdialabel.show() - self.ui.tipdia_entry.show() - self.ui.tipanglelabel.show() - self.ui.tipangle_entry.show() - self.ui.cutz_entry.setDisabled(True) - self.ui.cutzlabel.setToolTip( - _("Disabled because the tool is V-shape.\n" - "For V-shape tools the depth of cut is\n" - "calculated from other parameters like:\n" - "- 'V-tip Angle' -> angle at the tip of the tool\n" - "- 'V-tip Dia' -> diameter at the tip of the tool \n" - "- Tool Dia -> 'Dia' column found in the Tool Table\n" - "NB: a value of zero means that Tool Dia = 'V-tip Dia'") - ) - self.ui.cutz_entry.setToolTip( - _("Disabled because the tool is V-shape.\n" - "For V-shape tools the depth of cut is\n" - "calculated from other parameters like:\n" - "- 'V-tip Angle' -> angle at the tip of the tool\n" - "- 'V-tip Dia' -> diameter at the tip of the tool \n" - "- Tool Dia -> 'Dia' column found in the Tool Table\n" - "NB: a value of zero means that Tool Dia = 'V-tip Dia'") - ) - - self.on_update_cutz() - else: - self.ui.tipdialabel.hide() - self.ui.tipdia_entry.hide() - self.ui.tipanglelabel.hide() - self.ui.tipangle_entry.hide() - self.ui.cutz_entry.setDisabled(False) - self.ui.cutzlabel.setToolTip( - _("Cutting depth (negative)\n" - "below the copper surface.") - ) - self.ui.cutz_entry.setToolTip('') - - def on_update_cutz(self): - vdia = float(self.ui.tipdia_entry.get_value()) - half_vangle = float(self.ui.tipangle_entry.get_value()) / 2 - - row = self.ui.geo_tools_table.currentRow() - tool_uid_item = self.ui.geo_tools_table.item(row, 5) - if tool_uid_item is None: - return - tool_uid = int(tool_uid_item.text()) - - tool_dia_item = self.ui.geo_tools_table.item(row, 1) - if tool_dia_item is None: - return - tooldia = float(tool_dia_item.text()) - - try: - new_cutz = (tooldia - vdia) / (2 * math.tan(math.radians(half_vangle))) - except ZeroDivisionError: - new_cutz = self.old_cutz - - new_cutz = float('%.*f' % (self.decimals, new_cutz)) * -1.0 # this value has to be negative - - self.ui.cutz_entry.set_value(new_cutz) - - # store the new CutZ value into storage (self.tools) - for tooluid_key, tooluid_value in self.tools.items(): - if int(tooluid_key) == tool_uid: - tooluid_value['data']['tools_mill_cutz'] = new_cutz - - def on_tooltable_cellwidget_change(self): - cw = self.sender() - # assert isinstance(cw, FCComboBox) or isinstance(cw, FCCheckBox),\ - # "Expected a FCCombobox or a FCCheckbox got %s" % type(cw) - cw_index = self.ui.geo_tools_table.indexAt(cw.pos()) - cw_row = cw_index.row() - cw_col = cw_index.column() - current_uid = int(self.ui.geo_tools_table.item(cw_row, 5).text()) - - # store the text of the cellWidget that changed it's index in the self.tools - for tooluid_key, tooluid_value in self.tools.items(): - if int(tooluid_key) == current_uid: - cb_txt = cw.currentText() - if cw_col == 2: - tooluid_value['data']['tools_mill_offset_type'] = cb_txt - if cb_txt == 'Custom': - self.ui.tool_offset_entry.show() - self.ui.tool_offset_lbl.show() - else: - self.ui.tool_offset_entry.hide() - self.ui.tool_offset_lbl.hide() - # reset the offset_value in storage self.tools - tooluid_value['data']['tools_mill_offset_value'] = 0.0 - elif cw_col == 3: - # force toolpath type as 'Iso' if the tool type is V-Shape - if self.ui.geo_tools_table.cellWidget(cw_row, 4).currentText() == 'V': - tooluid_value['data']['tools_mill_job_type'] = _('Isolation') - idx = self.ui.geo_tools_table.cellWidget(cw_row, 3).findText(_('Isolation')) - self.ui.geo_tools_table.cellWidget(cw_row, 3).setCurrentIndex(idx) - else: - tooluid_value['data']['tools_mill_job_type'] = cb_txt - elif cw_col == 4: - tooluid_value['data']['data']['tools_mill_tool_shape'] = cb_txt - - # if the tool_type selected is V-Shape then autoselect the toolpath type as Iso - if cb_txt == 'V': - idx = self.ui.geo_tools_table.cellWidget(cw_row, 3).findText(_('Isolation')) - self.ui.geo_tools_table.cellWidget(cw_row, 3).setCurrentIndex(idx) - else: - self.ui.cutz_entry.set_value(self.old_cutz) - - self.ui_update_v_shape(tool_type_txt=self.ui.geo_tools_table.cellWidget(cw_row, 4).currentText()) - - def update_form(self, dict_storage): - for form_key in self.form_fields: - for storage_key in dict_storage: - if form_key == storage_key: - # avoid the change of the name from the data tool dictionary - if form_key == 'name': - continue - try: - self.form_fields[form_key].set_value(dict_storage[form_key]) - except Exception as e: - self.app.log.error('GeometryObject.update_form() -> %s' % str(e)) - - # this is done here because those buttons control through OptionalInputSelection if some entry's are Enabled - # or not. But due of using the ui_disconnect() status is no longer updated and I had to do it here - self.ui.ois_dwell_geo.on_cb_change() - self.ui.ois_mpass_geo.on_cb_change() - self.ui.ois_tcz_geo.on_cb_change() - - def on_apply_param_to_all_clicked(self): - if self.ui.geo_tools_table.rowCount() == 0: - # there is no tool in tool table so we can't save the GUI elements values to storage - self.app.log.debug("GeometryObject.gui_form_to_storage() --> no tool in Tools Table, aborting.") - return - - self.ui_disconnect() - - row = self.ui.geo_tools_table.currentRow() - if row < 0: - row = 0 - - # store all the data associated with the row parameter to the self.tools storage - tooldia_item = float(self.ui.geo_tools_table.item(row, 1).text()) - offset_item = self.ui.geo_tools_table.cellWidget(row, 2).currentText() - job_item = self.ui.geo_tools_table.cellWidget(row, 3).currentText() - tool_type_item = self.ui.geo_tools_table.cellWidget(row, 4).currentText() - - offset_value_item = float(self.ui.tool_offset_entry.get_value()) - - # this new dict will hold the actual useful data, another dict that is the value of key 'data' - temp_tools = {} - temp_dia = {} - temp_data = {} - - for tooluid_key, tooluid_value in self.tools.items(): - for key, value in tooluid_value.items(): - if key == 'tooldia': - temp_dia[key] = tooldia_item - # update the 'offset', 'type' and 'tool_type' sections - if key == 'offset': - temp_dia[key] = offset_item - if key == 'tool_type': - temp_dia[key] = tool_type_item - if key == 'offset_value': - temp_dia[key] = offset_value_item - - if key == 'data': - # update the 'data' section - for data_key in tooluid_value[key].keys(): - for form_key, form_value in self.form_fields.items(): - if form_key == data_key: - temp_data[data_key] = form_value.get_value() - # make sure we make a copy of the keys not in the form (we may use 'data' keys that are - # updated from self.app.defaults - if data_key not in self.form_fields: - temp_data[data_key] = value[data_key] - temp_dia[key] = deepcopy(temp_data) - temp_data.clear() - - if key == 'solid_geometry': - temp_dia[key] = deepcopy(self.tools[tooluid_key]['solid_geometry']) - - temp_tools[tooluid_key] = deepcopy(temp_dia) - temp_dia['data']['tools_mill_job_type'] = job_item - - self.tools.clear() - self.tools = deepcopy(temp_tools) - temp_tools.clear() - - self.ui_connect() - - def gui_form_to_storage(self): - self.ui_disconnect() - - if self.ui.geo_tools_table.rowCount() == 0: - # there is no tool in tool table so we can't save the GUI elements values to storage - self.app.log.debug("GeometryObject.gui_form_to_storage() --> no tool in Tools Table, aborting.") - return - - widget_changed = self.sender() - try: - widget_idx = self.ui.grid3.indexOf(widget_changed) - # those are the indexes for the V-Tip Dia and V-Tip Angle, if edited calculate the new Cut Z - if widget_idx == 1 or widget_idx == 3: - self.on_update_cutz() - except Exception as e: - self.app.log.error("GeometryObject.gui_form_to_storage() -- wdg index -> %s" % str(e)) - - # the original connect() function of the OptionalInputSelection is no longer working because of the - # ui_diconnect() so I use this 'hack' - if isinstance(widget_changed, FCCheckBox): - if widget_changed.text() == 'Multi-Depth:': - self.ui.ois_mpass_geo.on_cb_change() - - if widget_changed.text() == 'Tool change': - self.ui.ois_tcz_geo.on_cb_change() - - if widget_changed.text() == 'Dwell:': - self.ui.ois_dwell_geo.on_cb_change() - - row = self.ui.geo_tools_table.currentRow() - if row < 0: - row = 0 - - # store all the data associated with the row parameter to the self.tools storage - tooldia_item = float(self.ui.geo_tools_table.item(row, 1).text()) - offset_item = self.ui.geo_tools_table.cellWidget(row, 2).currentText() - job_item = self.ui.geo_tools_table.cellWidget(row, 3).currentText() - tool_type_item = self.ui.geo_tools_table.cellWidget(row, 4).currentText() - tooluid_item = int(self.ui.geo_tools_table.item(row, 5).text()) - - offset_value_item = float(self.ui.tool_offset_entry.get_value()) - - # this new dict will hold the actual useful data, another dict that is the value of key 'data' - temp_tools = {} - temp_dia = {} - temp_data = {} - - for tooluid_key, tooluid_value in self.tools.items(): - if int(tooluid_key) == tooluid_item: - for key, value in tooluid_value.items(): - if key == 'tooldia': - temp_dia[key] = tooldia_item - # update the 'offset', 'type' and 'tool_type' sections - if key == 'offset': - temp_dia[key] = offset_item - if key == 'tool_type': - temp_dia[key] = tool_type_item - if key == 'offset_value': - temp_dia[key] = offset_value_item - - if key == 'data': - # update the 'data' section - for data_key in tooluid_value[key].keys(): - for form_key, form_value in self.form_fields.items(): - if form_key == data_key: - temp_data[data_key] = form_value.get_value() - # make sure we make a copy of the keys not in the form (we may use 'data' keys that are - # updated from self.app.defaults - if data_key not in self.form_fields: - temp_data[data_key] = value[data_key] - temp_dia[key] = deepcopy(temp_data) - temp_data.clear() - - if key == 'solid_geometry': - temp_dia[key] = deepcopy(self.tools[tooluid_key]['solid_geometry']) - - temp_tools[tooluid_key] = deepcopy(temp_dia) - temp_dia['data']['tools_mill_job_type'] = job_item - else: - temp_tools[tooluid_key] = deepcopy(tooluid_value) - - self.tools.clear() - self.tools = deepcopy(temp_tools) - temp_tools.clear() - self.ui_connect() - - def update_common_param_in_storage(self): - for tooluid_value in self.tools.values(): - tooluid_value['data']['tools_mill_toolchange'] = self.ui.toolchangeg_cb.get_value() - tooluid_value['data']['tools_mill_toolchangez'] = self.ui.toolchangez_entry.get_value() - tooluid_value['data']['tools_mill_endz'] = self.ui.endz_entry.get_value() - tooluid_value['data']['tools_mill_endxy'] = self.ui.endxy_entry.get_value() - tooluid_value['data']['tools_mill_ppname_g'] = self.ui.pp_geometry_name_cb.get_value() - tooluid_value['data']['tools_mill_area_exclusion'] = self.ui.exclusion_cb.get_value() - tooluid_value['data']['tools_mill_polish'] = self.ui.polish_cb.get_value() - def select_tools_table_row(self, row, clearsel=None): if clearsel: self.ui.geo_tools_table.clearSelection() @@ -1928,214 +594,6 @@ class GeometryObject(FlatCAMObj, Geometry): return dwg - def get_selected_tools_table_items(self): - """ - Returns a list of lists, each list in the list is made out of row elements - - :return: List of table_tools items. - :rtype: list - """ - table_tools_items = [] - if self.multigeo: - for x in self.ui.geo_tools_table.selectedItems(): - elem = [] - txt = '' - - for column in range(0, self.ui.geo_tools_table.columnCount()): - try: - txt = self.ui.geo_tools_table.item(x.row(), column).text() - except AttributeError: - try: - txt = self.ui.geo_tools_table.cellWidget(x.row(), column).currentText() - except AttributeError: - pass - elem.append(txt) - table_tools_items.append(deepcopy(elem)) - # table_tools_items.append([self.ui.geo_tools_table.item(x.row(), column).text() - # for column in range(0, self.ui.geo_tools_table.columnCount())]) - else: - for x in self.ui.geo_tools_table.selectedItems(): - r = [] - txt = '' - - # the last 2 columns for single-geo geometry are irrelevant and create problems reading - # so we don't read them - for column in range(0, self.ui.geo_tools_table.columnCount() - 2): - # the columns have items that have text but also have items that are widgets - # for which the text they hold has to be read differently - try: - txt = self.ui.geo_tools_table.item(x.row(), column).text() - except AttributeError: - try: - txt = self.ui.geo_tools_table.cellWidget(x.row(), column).currentText() - except AttributeError: - pass - r.append(txt) - table_tools_items.append(r) - - for item in table_tools_items: - item[0] = str(item[0]) - return table_tools_items - - # def on_pp_changed(self): - # current_pp = self.ui.pp_geometry_name_cb.get_value() - # if current_pp == 'hpgl': - # self.old_pp_state = self.ui.mpass_cb.get_value() - # self.old_toolchangeg_state = self.ui.toolchangeg_cb.get_value() - # - # self.ui.mpass_cb.set_value(False) - # self.ui.mpass_cb.setDisabled(True) - # - # self.ui.toolchangeg_cb.set_value(True) - # self.ui.toolchangeg_cb.setDisabled(True) - # else: - # self.ui.mpass_cb.set_value(self.old_pp_state) - # self.ui.mpass_cb.setDisabled(False) - # - # self.ui.toolchangeg_cb.set_value(self.old_toolchangeg_state) - # self.ui.toolchangeg_cb.setDisabled(False) - # - # if "toolchange_probe" in current_pp.lower(): - # self.ui.pdepth_entry.setVisible(True) - # self.ui.pdepth_label.show() - # - # self.ui.feedrate_probe_entry.setVisible(True) - # self.ui.feedrate_probe_label.show() - # else: - # self.ui.pdepth_entry.setVisible(False) - # self.ui.pdepth_label.hide() - # - # self.ui.feedrate_probe_entry.setVisible(False) - # self.ui.feedrate_probe_label.hide() - # - # if 'marlin' in current_pp.lower() or 'custom' in current_pp.lower(): - # self.ui.fr_rapidlabel.show() - # self.ui.feedrate_rapid_entry.show() - # else: - # self.ui.fr_rapidlabel.hide() - # self.ui.feedrate_rapid_entry.hide() - # - # if 'laser' in current_pp.lower(): - # self.ui.cutzlabel.hide() - # self.ui.cutz_entry.hide() - # try: - # self.ui.mpass_cb.hide() - # self.ui.maxdepth_entry.hide() - # except AttributeError: - # pass - # - # if 'marlin' in current_pp.lower(): - # self.ui.travelzlabel.setText('%s:' % _("Focus Z")) - # self.ui.endz_label.show() - # self.ui.endz_entry.show() - # else: - # self.ui.travelzlabel.hide() - # self.ui.travelz_entry.hide() - # - # self.ui.endz_label.hide() - # self.ui.endz_entry.hide() - # - # try: - # self.ui.frzlabel.hide() - # self.ui.feedrate_z_entry.hide() - # except AttributeError: - # pass - # - # self.ui.dwell_cb.hide() - # self.ui.dwelltime_entry.hide() - # - # self.ui.spindle_label.setText('%s:' % _("Laser Power")) - # - # try: - # self.ui.tool_offset_label.hide() - # self.ui.offset_entry.hide() - # except AttributeError: - # pass - # else: - # self.ui.cutzlabel.show() - # self.ui.cutz_entry.show() - # try: - # self.ui.mpass_cb.show() - # self.ui.maxdepth_entry.show() - # except AttributeError: - # pass - # - # self.ui.travelzlabel.setText('%s:' % _('Travel Z')) - # - # self.ui.travelzlabel.show() - # self.ui.travelz_entry.show() - # - # self.ui.endz_label.show() - # self.ui.endz_entry.show() - # - # try: - # self.ui.frzlabel.show() - # self.ui.feedrate_z_entry.show() - # except AttributeError: - # pass - # self.ui.dwell_cb.show() - # self.ui.dwelltime_entry.show() - # - # self.ui.spindle_label.setText('%s:' % _('Spindle speed')) - # - # try: - # self.ui.tool_offset_lbl.show() - # self.ui.offset_entry.show() - # except AttributeError: - # pass - - def on_generatecnc_button_click(self): - self.app.log.debug("Generating CNCJob from Geometry ...") - self.app.defaults.report_usage("geometry_on_generatecnc_button") - - # this reads the values in the UI form to the self.options dictionary - self.read_form() - - self.sel_tools = {} - - try: - if self.special_group: - self.app.inform.emit( - '[WARNING_NOTCL] %s %s %s.' % - (_("This Geometry can't be processed because it is"), str(self.special_group), _("Geometry")) - ) - return - except AttributeError: - pass - - # test to see if we have tools available in the tool table - if self.ui.geo_tools_table.selectedItems(): - for x in self.ui.geo_tools_table.selectedItems(): - tooluid = int(self.ui.geo_tools_table.item(x.row(), 5).text()) - - for tooluid_key, tooluid_value in self.tools.items(): - if int(tooluid_key) == tooluid: - self.sel_tools.update({ - tooluid: deepcopy(tooluid_value) - }) - - if self.ui.polish_cb.get_value(): - self.on_polish() - else: - self.mtool_gen_cncjob() - self.ui.geo_tools_table.clearSelection() - - elif self.ui.geo_tools_table.rowCount() == 1: - tooluid = int(self.ui.geo_tools_table.item(0, 5).text()) - - for tooluid_key, tooluid_value in self.tools.items(): - if int(tooluid_key) == tooluid: - self.sel_tools.update({ - tooluid: deepcopy(tooluid_value) - }) - if self.ui.polish_cb.get_value(): - self.on_polish() - else: - self.mtool_gen_cncjob() - self.ui.geo_tools_table.clearSelection() - else: - self.app.inform.emit('[ERROR_NOTCL] %s' % _("Failed. No tool selected in the tool table ...")) - def mtool_gen_cncjob(self, outname=None, tools_dict=None, segx=None, segy=None, plot=True, use_thread=True): """ @@ -2638,101 +1096,6 @@ class GeometryObject(FlatCAMObj, Geometry): else: self.app.app_obj.new_object("cncjob", outname, job_init, plot=plot) - def on_polish(self): - - def job_thread(obj): - with obj.app.proc_container.new('%s...' % _("Working")): - tooldia = obj.ui.polish_dia_entry.get_value() - depth = obj.ui.polish_pressure_entry.get_value() - travelz = obj.ui.polish_travelz_entry.get_value() - margin = obj.ui.polish_margin_entry.get_value() - overlap = obj.ui.polish_over_entry.get_value() / 100 - paint_method = obj.ui.polish_method_combo.get_value() - - # calculate the max uid form the keys of the self.tools - max_uid = max(list(obj.tools.keys())) - new_uid = max_uid + 1 - - # add a new key in the dict - new_data = deepcopy(obj.default_data) - new_data["travelz"] = travelz - new_data["cutz"] = depth - new_dict = { - new_uid: { - 'tooldia': obj.app.dec_format(float(tooldia), obj.decimals), - 'offset': 'Path', - 'offset_value': 0.0, - 'type': _('Polish'), - 'tool_type': 'C1', - 'data': new_data, - 'solid_geometry': [] - } - } - obj.tools.update(new_dict) - obj.sel_tools.update(new_dict) - - # make a box polygon out of the bounds of the current object - # apply the margin - xmin, ymin, xmax, ymax = obj.bounds() - bbox = box(xmin-margin, ymin-margin, xmax+margin, ymax+margin) - - # paint the box - try: - # provide the app with a way to process the GUI events when in a blocking loop - QtWidgets.QApplication.processEvents() - if self.app.abort_flag: - # graceful abort requested by the user - raise grace - - # Type(cpoly) == FlatCAMRTreeStorage | None - cpoly = None - if paint_method == 0: # Standard - cpoly = self.clear_polygon(bbox, - tooldia=tooldia, - steps_per_circle=obj.circle_steps, - overlap=overlap, - contour=True, - connect=True, - prog_plot=False) - elif paint_method == 1: # Seed - cpoly = self.clear_polygon2(bbox, - tooldia=tooldia, - steps_per_circle=obj.circle_steps, - overlap=overlap, - contour=True, - connect=True, - prog_plot=False) - elif paint_method == 2: # Lines - cpoly = self.clear_polygon3(bbox, - tooldia=tooldia, - steps_per_circle=obj.circle_steps, - overlap=overlap, - contour=True, - connect=True, - prog_plot=False) - - if not cpoly or not cpoly.objects: - obj.app.inform.emit('[ERROR_NOTCL] %s' % _('Geometry could not be painted completely')) - return - - paint_geo = [g for g in cpoly.get_objects() if g and not g.is_empty] - except grace: - return "fail" - except Exception as e: - self.app.log.error("Could not Paint the polygons. %s" % str(e)) - mssg = '[ERROR] %s\n%s' % (_("Could not do Paint. Try a different combination of parameters. " - "Or a different method of Paint"), str(e)) - self.app.inform.emit(mssg) - return - - obj.sel_tools[new_uid]['solid_geometry'] = paint_geo - - # and now create the CNCJob - obj.launch_job.emit() - - # Send to worker - self.app.worker_task.emit({'fcn': job_thread, 'params': [self]}) - def scale(self, xfactor, yfactor=None, point=None): """ Scales all geometry by a given factor. @@ -2996,176 +1359,8 @@ class GeometryObject(FlatCAMObj, Geometry): self.tools.clear() self.tools = deepcopy(temp_tools_dict) - # if there is a value in the new tool field then convert that one too - try: - self.ui.addtool_entry.returnPressed.disconnect() - except TypeError: - pass - tooldia = self.ui.addtool_entry.get_value() - if tooldia: - tooldia *= factor - tooldia = float('%.*f' % (self.decimals, tooldia)) - - self.ui.addtool_entry.set_value(tooldia) - self.ui.addtool_entry.returnPressed.connect(self.on_tool_default_add) - return factor - def on_add_area_click(self): - shape_button = self.ui.area_shape_radio - overz_button = self.ui.over_z_entry - strategy_radio = self.ui.strategy_radio - cnc_button = self.ui.generate_cnc_button - solid_geo = self.solid_geometry - obj_type = self.kind - - self.app.exc_areas.on_add_area_click( - shape_button=shape_button, overz_button=overz_button, cnc_button=cnc_button, strategy_radio=strategy_radio, - solid_geo=solid_geo, obj_type=obj_type) - - def on_clear_area_click(self): - if not self.app.exc_areas.exclusion_areas_storage: - self.app.inform.emit("[WARNING_NOTCL] %s" % _("Delete failed. There are no exclusion areas to delete.")) - return - - self.app.exc_areas.on_clear_area_click() - self.app.exc_areas.e_shape_modified.emit() - - def on_delete_sel_areas(self): - sel_model = self.ui.exclusion_table.selectionModel() - sel_indexes = sel_model.selectedIndexes() - - # it will iterate over all indexes which means all items in all columns too but I'm interested only on rows - # so the duplicate rows will not be added - sel_rows = set() - for idx in sel_indexes: - sel_rows.add(idx.row()) - - if not sel_rows: - self.app.inform.emit("[WARNING_NOTCL] %s" % _("Delete failed. Nothing is selected.")) - return - - self.app.exc_areas.delete_sel_shapes(idxs=list(sel_rows)) - self.app.exc_areas.e_shape_modified.emit() - - def on_draw_sel_shape(self): - sel_model = self.ui.exclusion_table.selectionModel() - sel_indexes = sel_model.selectedIndexes() - - # it will iterate over all indexes which means all items in all columns too but I'm interested only on rows - sel_rows = set() - for idx in sel_indexes: - sel_rows.add(idx.row()) - - self.delete_sel_shape() - - if self.app.is_legacy is False: - face = self.app.defaults['global_sel_fill'][:-2] + str(hex(int(0.2 * 255)))[2:] - outline = self.app.defaults['global_sel_line'][:-2] + str(hex(int(0.8 * 255)))[2:] - else: - face = self.app.defaults['global_sel_fill'][:-2] + str(hex(int(0.4 * 255)))[2:] - outline = self.app.defaults['global_sel_line'][:-2] + str(hex(int(1.0 * 255)))[2:] - - for row in sel_rows: - sel_rect = self.app.exc_areas.exclusion_areas_storage[row]['shape'] - self.app.move_tool.sel_shapes.add(sel_rect, color=outline, face_color=face, update=True, layer=0, - tolerance=None) - if self.app.is_legacy is True: - self.app.move_tool.sel_shapes.redraw() - - def on_clear_selection(self): - self.app.delete_selection_shape() - # self.ui.exclusion_table.clearSelection() - - def delete_sel_shape(self): - self.app.delete_selection_shape() - - def update_exclusion_table(self): - self.exclusion_area_cb_is_checked = True if self.ui.exclusion_cb.isChecked() else False - - self.build_ui() - self.ui.exclusion_cb.set_value(self.exclusion_area_cb_is_checked) - - def on_strategy(self, val): - if val == 'around': - self.ui.over_z_label.setDisabled(True) - self.ui.over_z_entry.setDisabled(True) - else: - self.ui.over_z_label.setDisabled(False) - self.ui.over_z_entry.setDisabled(False) - - def on_exclusion_table_toggle_all(self): - """ - will toggle the selection of all rows in Exclusion Areas table - - :return: - """ - sel_model = self.ui.exclusion_table.selectionModel() - sel_indexes = sel_model.selectedIndexes() - - # it will iterate over all indexes which means all items in all columns too but I'm interested only on rows - sel_rows = set() - for idx in sel_indexes: - sel_rows.add(idx.row()) - - if sel_rows: - self.ui.exclusion_table.clearSelection() - self.delete_sel_shape() - else: - self.ui.exclusion_table.selectAll() - self.on_draw_sel_shape() - - def on_exclusion_table_overz(self, current_item): - self.ui_disconnect() - - current_row = current_item.row() - try: - d = float(self.ui.exclusion_table.item(current_row, 3).text()) - except ValueError: - # try to convert comma to decimal point. if it's still not working error message and return - try: - d = float(self.ui.exclusion_table.item(current_row, 3).text().replace(',', '.')) - except ValueError: - self.app.inform.emit('[ERROR_NOTCL] %s' % _("Wrong value format entered, use a number.")) - return - except AttributeError: - self.ui_connect() - return - - overz = self.app.dec_format(d, self.decimals) - idx = int(self.ui.exclusion_table.item(current_row, 0).text()) - - for area_dict in self.app.exc_areas.exclusion_areas_storage: - if area_dict['idx'] == idx: - area_dict['overz'] = overz - - self.app.inform.emit('[success] %s' % _("Value edited in Exclusion Table.")) - self.ui_connect() - self.builduiSig.emit() - - def on_exclusion_table_strategy(self): - cw = self.sender() - cw_index = self.ui.exclusion_table.indexAt(cw.pos()) - cw_row = cw_index.row() - idx = int(self.ui.exclusion_table.item(cw_row, 0).text()) - - for area_dict in self.app.exc_areas.exclusion_areas_storage: - if area_dict['idx'] == idx: - strategy = self.ui.exclusion_table.cellWidget(cw_row, 2).currentIndex() - area_dict['strategy'] = "around" if strategy == 0 else 'overz' - - self.app.inform.emit('[success] %s' % _("Value edited in Exclusion Table.")) - self.ui_connect() - self.builduiSig.emit() - - def area_disconnect(self): - try: - self.app.exc_areas.area_disconnect() - if not self.app.exc_areas.exclusion_areas_storage: - self.app.exc_areas.clear_shapes() - except Exception as err: - self.app.log.error('GeometryObject.area_disconnect() -> %s' % str(err)) - def plot_element(self, element, color=None, visible=None): if color is None: diff --git a/appObjects/FlatCAMGerber.py b/appObjects/FlatCAMGerber.py index 1d2244de..1b638c96 100644 --- a/appObjects/FlatCAMGerber.py +++ b/appObjects/FlatCAMGerber.py @@ -395,17 +395,6 @@ class GerberObject(FlatCAMObj, Gerber): except (TypeError, AttributeError): pass - @staticmethod - def buffer_handler(geo): - new_geo = geo - if isinstance(new_geo, list): - new_geo = MultiPolygon(new_geo) - - new_geo = new_geo.buffer(0.0000001) - new_geo = new_geo.buffer(-0.0000001) - - return new_geo - def on_properties(self, state): if state: self.ui.info_frame.show() @@ -436,6 +425,17 @@ class GerberObject(FlatCAMObj, Gerber): self.app.worker_task.emit({'fcn': buffer_task, 'params': []}) + @staticmethod + def buffer_handler(geo): + new_geo = geo + if isinstance(new_geo, list): + new_geo = MultiPolygon(new_geo) + + new_geo = new_geo.buffer(0.0000001) + new_geo = new_geo.buffer(-0.0000001) + + return new_geo + def on_generatenoncopper_button_click(self, *args): self.app.defaults.report_usage("gerber_on_generatenoncopper_button") @@ -552,57 +552,22 @@ class GerberObject(FlatCAMObj, Gerber): geo_obj.solid_geometry = [] - # transfer the Cut Z and Vtip and Vangle values in case that we use the V-Shape tool in Gerber UI - if geo_obj.tool_type.lower() == 'v': - new_cutz = self.app.defaults["tools_iso_tool_cutz"] - new_vtipdia = self.app.defaults["tools_iso_tool_vtipdia"] - new_vtipangle = self.app.defaults["tools_iso_tool_vtipangle"] - tool_type = 'V' - else: - new_cutz = self.app.defaults['geometry_cutz'] - new_vtipdia = self.app.defaults['tools_mill_vtipdia'] - new_vtipangle = self.app.defaults['tools_mill_vtipangle'] - tool_type = 'C1' - # store here the default data for Geometry Data default_data = {} - default_data.update({ - "name": iso_name, - "plot": self.app.defaults['geometry_plot'], - "cutz": new_cutz, - "vtipdia": new_vtipdia, - "vtipangle": new_vtipangle, - "travelz": self.app.defaults['geometry_travelz'], - "feedrate": self.app.defaults['geometry_feedrate'], - "feedrate_z": self.app.defaults['geometry_feedrate_z'], - "feedrate_rapid": self.app.defaults['geometry_feedrate_rapid'], - "dwell": self.app.defaults['geometry_dwell'], - "dwelltime": self.app.defaults['geometry_dwelltime'], - "multidepth": self.app.defaults['geometry_multidepth'], - "ppname_g": self.app.defaults['geometry_ppname_g'], - "depthperpass": self.app.defaults['geometry_depthperpass'], - "extracut": self.app.defaults['geometry_extracut'], - "extracut_length": self.app.defaults['geometry_extracut_length'], - "toolchange": self.app.defaults['geometry_toolchange'], - "toolchangez": self.app.defaults['geometry_toolchangez'], - "endz": self.app.defaults['geometry_endz'], - "spindlespeed": self.app.defaults['geometry_spindlespeed'], - "toolchangexy": self.app.defaults['geometry_toolchangexy'], - "startz": self.app.defaults['geometry_startz'] - }) + for opt_key, opt_val in app_obj.options.items(): + if opt_key.find('geometry' + "_") == 0: + oname = opt_key[len('geometry') + 1:] + default_data[oname] = self.app.options[opt_key] + if opt_key.find('tools_mill' + "_") == 0: + default_data[opt_key] = self.app.options[opt_key] - geo_obj.tools = {'1': {}} - geo_obj.tools.update({ + geo_obj.tools = { '1': { 'tooldia': dia, - 'offset': 'Path', - 'offset_value': 0.0, - 'type': 'Rough', - 'tool_type': tool_type, 'data': default_data, 'solid_geometry': geo_obj.solid_geometry } - }) + } for nr_pass in range(passes): iso_offset = dia * ((2 * nr_pass + 1) / 2.0) - (nr_pass * overlap * dia) @@ -695,59 +660,22 @@ class GerberObject(FlatCAMObj, Gerber): geo_obj.solid_geometry = geom - # transfer the Cut Z and Vtip and VAngle values in case that we use the V-Shape tool in Gerber UI - # even if the resulting geometry is not multigeo we add the tools dict which will hold the data - # required to be transfered to the Geometry object - if self.app.defaults["tools_iso_tool_type"].lower() == 'v': - new_cutz = self.app.defaults["tools_iso_tool_cutz"] - new_vtipdia = self.app.defaults["tools_iso_tool_vtipdia"] - new_vtipangle = self.app.defaults["tools_iso_tool_vtipangle"] - tool_type = 'V' - else: - new_cutz = self.app.defaults['geometry_cutz'] - new_vtipdia = self.app.defaults['tools_mill_vtipdia'] - new_vtipangle = self.app.defaults['tools_mill_vtipangle'] - tool_type = 'C1' - # store here the default data for Geometry Data default_data = {} - default_data.update({ - "name": iso_name, - "plot": self.app.defaults['geometry_plot'], - "cutz": new_cutz, - "vtipdia": new_vtipdia, - "vtipangle": new_vtipangle, - "travelz": self.app.defaults['geometry_travelz'], - "feedrate": self.app.defaults['geometry_feedrate'], - "feedrate_z": self.app.defaults['geometry_feedrate_z'], - "feedrate_rapid": self.app.defaults['geometry_feedrate_rapid'], - "dwell": self.app.defaults['geometry_dwell'], - "dwelltime": self.app.defaults['geometry_dwelltime'], - "multidepth": self.app.defaults['geometry_multidepth'], - "ppname_g": self.app.defaults['geometry_ppname_g'], - "depthperpass": self.app.defaults['geometry_depthperpass'], - "extracut": self.app.defaults['geometry_extracut'], - "extracut_length": self.app.defaults['geometry_extracut_length'], - "toolchange": self.app.defaults['geometry_toolchange'], - "toolchangez": self.app.defaults['geometry_toolchangez'], - "endz": self.app.defaults['geometry_endz'], - "spindlespeed": self.app.defaults['geometry_spindlespeed'], - "toolchangexy": self.app.defaults['geometry_toolchangexy'], - "startz": self.app.defaults['geometry_startz'] - }) + for opt_key, opt_val in app_obj.options.items(): + if opt_key.find('geometry' + "_") == 0: + oname = opt_key[len('geometry') + 1:] + default_data[oname] = self.app.options[opt_key] + if opt_key.find('tools_mill' + "_") == 0: + default_data[opt_key] = self.app.options[opt_key] - geo_obj.tools = {'1': {}} - geo_obj.tools.update({ + geo_obj.tools = { '1': { 'tooldia': dia, - 'offset': 'Path', - 'offset_value': 0.0, - 'type': 'Rough', - 'tool_type': tool_type, 'data': default_data, 'solid_geometry': geo_obj.solid_geometry } - }) + } # detect if solid_geometry is empty and this require list flattening which is "heavy" # or just looking in the lists (they are one level depth) and if any is not empty @@ -856,16 +784,11 @@ class GerberObject(FlatCAMObj, Gerber): oname = opt_key[len('geometry') + 1:] default_data[oname] = self.app.options[opt_key] if opt_key.find('tools_mill' + "_") == 0: - oname = opt_key[len('tools_mill') + 1:] - default_data[oname] = self.app.options[opt_key] + default_data[opt_key] = self.app.options[opt_key] new_obj.tools = { 1: { 'tooldia': app_obj.dec_format(float(tools_list[0]), self.decimals), - 'offset': 'Path', - 'offset_value': 0.0, - 'type': 'Rough', - 'tool_type': 'C1', 'data': deepcopy(default_data), 'solid_geometry': new_obj.solid_geometry } @@ -1051,7 +974,6 @@ class GerberObject(FlatCAMObj, Gerber): except Exception as e: self.app.log.error("GerberObject.plot() --> %s" % str(e)) - # experimental plot() when the solid_geometry is stored in the self.tools def plot_aperture(self, only_flashes=False, run_thread=False, **kwargs): """ diff --git a/app_Main.py b/app_Main.py index 4d2f8326..221c318a 100644 --- a/app_Main.py +++ b/app_Main.py @@ -4718,7 +4718,7 @@ class App(QtCore.QObject): "cncjob_al_grbl_jog_fr", "cncjob_al_grbl_travelz", # Isolation Tool - "tools_iso_tool_vtipdia", 'tools_iso_tooldia', "tools_iso_tool_cutz", + "tools_iso_tool_cutz", # Drilling Tool 'tools_drill_cutz', 'tools_drill_depthperpass', 'tools_drill_travelz', 'tools_drill_endz', @@ -4962,7 +4962,10 @@ class App(QtCore.QObject): self.inform.emit('[WARNING_NOTCL] %s' % _("Please enter a tool diameter with non-zero value, in Float format.")) return - self.collection.get_active().on_tool_add(clicked_state=False, dia=float(val)) + try: + self.collection.get_active().on_tool_add(clicked_state=False, dia=float(val)) + except Exception as err: + self.log.debug("App.on_tool_add_keypress() --> %s" % str(err)) else: self.inform.emit('[WARNING_NOTCL] %s...' % _("Adding Tool cancelled")) else: diff --git a/defaults.py b/defaults.py index 3208d1a8..5c9a5c6a 100644 --- a/defaults.py +++ b/defaults.py @@ -350,8 +350,6 @@ class FlatCAMDefaults: # Isolation Routing Plugin "tools_iso_tooldia": "0.1", "tools_iso_order": 'rev', - "tools_iso_tool_vtipdia": 0.1, - "tools_iso_tool_vtipangle": 30, "tools_iso_tool_cutz": -0.05, "tools_iso_newdia": 0.1,