From 01dcfb69a6944b99965a327e958729fa866ebf89 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Tue, 5 Jun 2018 22:13:33 +0300 Subject: [PATCH] - remade the functions into a Tool framework - renamed the other current files that holds 'Tools' to start with Tool like Tcl commands start with TclCommand --- FlatCAMApp.py | 221 +--------------- FlatCAMGUI.py | 23 +- DblSidedTool.py => ToolDblSided.py | 0 MeasurementTool.py => ToolMeasurement.py | 0 ToolTransform.py | 319 +++++++++++++++++++++++ 5 files changed, 331 insertions(+), 232 deletions(-) rename DblSidedTool.py => ToolDblSided.py (100%) rename MeasurementTool.py => ToolMeasurement.py (100%) create mode 100644 ToolTransform.py diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 58ea32bf..3fe46be8 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -36,8 +36,9 @@ from FlatCAMShell import FCShell from FlatCAMDraw import FlatCAMDraw from FlatCAMProcess import * from GUIElements import FCInputDialog -from MeasurementTool import Measurement -from DblSidedTool import DblSidedTool +from ToolMeasurement import Measurement +from ToolDblSided import DblSidedTool +from ToolTransform import ToolTransform import tclCommands from camlib import * @@ -537,11 +538,6 @@ class App(QtCore.QObject): self.ui.menuoptions_transfer_p2a.triggered.connect(self.on_options_project2app) self.ui.menuoptions_transfer_o2p.triggered.connect(self.on_options_object2project) self.ui.menuoptions_transfer_p2o.triggered.connect(self.on_options_project2object) - self.ui.menuoptions_transform_flipx.triggered.connect(self.on_flipx) - self.ui.menuoptions_transform_flipy.triggered.connect(self.on_flipy) - self.ui.menuoptions_transform_skewx.triggered.connect(self.on_skewx) - self.ui.menuoptions_transform_skewy.triggered.connect(self.on_skewy) - self.ui.menuoptions_transform_rotate.triggered.connect(self.on_rotate) self.ui.menuviewdisableall.triggered.connect(self.disable_plots) self.ui.menuviewdisableother.triggered.connect(lambda: self.disable_plots(except_current=True)) self.ui.menuviewenable.triggered.connect(self.enable_all_plots) @@ -586,10 +582,12 @@ class App(QtCore.QObject): self.dblsidedtool = DblSidedTool(self) self.dblsidedtool.install(icon=QtGui.QIcon('share/doubleside16.png'), separator=True) - self.measeurement_tool = Measurement(self) - self.measeurement_tool.install(icon=QtGui.QIcon('share/measure16.png')) + self.measurement_tool = Measurement(self) + self.measurement_tool.install(icon=QtGui.QIcon('share/measure16.png')) + self.ui.measure_btn.triggered.connect(self.measurement_tool.run) - self.ui.measure_btn.triggered.connect(self.measeurement_tool.run) + self.transform_tool = ToolTransform(self) + self.transform_tool.install(icon=QtGui.QIcon('share/transform.png'), pos=self.ui.menuedit) self.draw = FlatCAMDraw(self, disabled=True) @@ -1491,209 +1489,6 @@ class App(QtCore.QObject): # self.options2form() - def on_flipx(self): - obj_list = self.collection.get_selected() - xminlist = [] - yminlist = [] - xmaxlist = [] - ymaxlist = [] - - if not obj_list: - self.inform.emit("WARNING: No object selected.") - msg = "Please Select an object to flip!" - warningbox = QtGui.QMessageBox() - warningbox.setText(msg) - warningbox.setWindowTitle("Warning ...") - warningbox.setWindowIcon(QtGui.QIcon('share/warning.png')) - warningbox.setStandardButtons(QtGui.QMessageBox.Ok) - warningbox.setDefaultButton(QtGui.QMessageBox.Ok) - warningbox.exec_() - else: - # first get a bounding box to fit all - for obj in obj_list: - xmin, ymin, xmax, ymax = obj.bounds() - xminlist.append(xmin) - yminlist.append(ymin) - xmaxlist.append(xmax) - ymaxlist.append(ymax) - - # get the minimum x,y and maximum x,y for all objects selected - xminimal = min(xminlist) - yminimal = min(yminlist) - xmaximal = max(xmaxlist) - ymaximal = max(ymaxlist) - - px = 0.5 * (xminimal + xmaximal) - py = 0.5 * (yminimal + ymaximal) - - # execute mirroring - for obj in obj_list: - obj.mirror('X', [px, py]) - obj.plot() - self.inform.emit('Flipped on the X axis ...') - - def on_flipy(self): - obj_list = self.collection.get_selected() - xminlist = [] - yminlist = [] - xmaxlist = [] - ymaxlist = [] - - if not obj_list: - self.inform.emit("WARNING: No object selected.") - msg = "Please Select an object to flip!" - warningbox = QtGui.QMessageBox() - warningbox.setText(msg) - warningbox.setWindowTitle("Warning ...") - warningbox.setWindowIcon(QtGui.QIcon('share/warning.png')) - warningbox.setStandardButtons(QtGui.QMessageBox.Ok) - warningbox.setDefaultButton(QtGui.QMessageBox.Ok) - warningbox.exec_() - else: - # first get a bounding box to fit all - for obj in obj_list: - xmin, ymin, xmax, ymax = obj.bounds() - xminlist.append(xmin) - yminlist.append(ymin) - xmaxlist.append(xmax) - ymaxlist.append(ymax) - - # get the minimum x,y and maximum x,y for all objects selected - xminimal = min(xminlist) - yminimal = min(yminlist) - xmaximal = max(xmaxlist) - ymaximal = max(ymaxlist) - - px = 0.5 * (xminimal + xmaximal) - py = 0.5 * (yminimal + ymaximal) - - # execute mirroring - for obj in obj_list: - obj.mirror('Y', [px, py]) - obj.plot() - self.inform.emit('Flipped on the Y axis ...') - - def on_rotate(self, preset=None): - obj_list = self.collection.get_selected() - xminlist = [] - yminlist = [] - xmaxlist = [] - ymaxlist = [] - - if not obj_list: - self.inform.emit("WARNING: No object selected.") - msg = "Please Select an object to rotate!" - warningbox = QtGui.QMessageBox() - warningbox.setText(msg) - warningbox.setWindowTitle("Warning ...") - warningbox.setWindowIcon(QtGui.QIcon('share/warning.png')) - warningbox.setStandardButtons(QtGui.QMessageBox.Ok) - warningbox.setDefaultButton(QtGui.QMessageBox.Ok) - warningbox.exec_() - else: - if preset is not None: - rotatebox = FCInputDialog() - num, ok = rotatebox.get_value(title='Transform', message='Enter the Angle value', - min=-360, max=360, decimals=3) - else: - num = preset - ok = True - - if ok: - for sel_obj in obj_list: - # first get a bounding box to fit all - for obj in obj_list: - xmin, ymin, xmax, ymax = obj.bounds() - xminlist.append(xmin) - yminlist.append(ymin) - xmaxlist.append(xmax) - ymaxlist.append(ymax) - - # get the minimum x,y and maximum x,y for all objects selected - xminimal = min(xminlist) - yminimal = min(yminlist) - xmaximal = max(xmaxlist) - ymaximal = max(ymaxlist) - - for sel_obj in obj_list: - px = 0.5 * (xminimal + xmaximal) - py = 0.5 * (yminimal + ymaximal) - - sel_obj.rotate(-num, point=(px, py)) - sel_obj.plot() - self.inform.emit('Object was rotated ...') - - def on_skewx(self): - obj_list = self.collection.get_selected() - xminlist = [] - yminlist = [] - - if not obj_list: - self.inform.emit("WARNING: No object selected.") - msg = "Please Select an object to skew/shear!" - warningbox = QtGui.QMessageBox() - warningbox.setText(msg) - warningbox.setWindowTitle("Warning ...") - warningbox.setWindowIcon(QtGui.QIcon('share/warning.png')) - warningbox.setStandardButtons(QtGui.QMessageBox.Ok) - warningbox.setDefaultButton(QtGui.QMessageBox.Ok) - warningbox.exec_() - else: - skewxbox = FCInputDialog() - num, ok = skewxbox.get_value(title='Transform', message='Enter the Angle value', - min=-360, max=360, decimals=3) - if ok: - # first get a bounding box to fit all - for obj in obj_list: - xmin, ymin, xmax, ymax = obj.bounds() - xminlist.append(xmin) - yminlist.append(ymin) - - # get the minimum x,y and maximum x,y for all objects selected - xminimal = min(xminlist) - yminimal = min(yminlist) - - for obj in obj_list: - obj.skew(num, 0, point=(xminimal, yminimal)) - obj.plot() - self.inform.emit('Object was skewed on X axis ...') - - def on_skewy(self): - obj_list = self.collection.get_selected() - xminlist = [] - yminlist = [] - - - if not obj_list: - self.inform.emit("WARNING: No object selected.") - msg = "Please Select an object to skew/shear!" - warningbox = QtGui.QMessageBox() - warningbox.setText(msg) - warningbox.setWindowTitle("Warning ...") - warningbox.setWindowIcon(QtGui.QIcon('share/warning.png')) - warningbox.setStandardButtons(QtGui.QMessageBox.Ok) - warningbox.setDefaultButton(QtGui.QMessageBox.Ok) - warningbox.exec_() - else: - skewybox = FCInputDialog() - num, ok = skewybox.get_value(title='Transform', message='Enter the Angle value', - min=-360, max=360, decimals=3) - if ok: - # first get a bounding box to fit all - for obj in obj_list: - xmin, ymin, xmax, ymax = obj.bounds() - xminlist.append(xmin) - yminlist.append(ymin) - - # get the minimum x,y and maximum x,y for all objects selected - xminimal = min(xminlist) - yminimal = min(yminlist) - - for obj in obj_list: - obj.skew(0, num, point=(xminimal, yminimal)) - obj.plot() - self.inform.emit('Object was skewed on Y axis ...') - def on_delete(self): """ Delete the currently selected FlatCAMObjs. diff --git a/FlatCAMGUI.py b/FlatCAMGUI.py index 7531a91b..0c3829d5 100644 --- a/FlatCAMGUI.py +++ b/FlatCAMGUI.py @@ -98,10 +98,12 @@ class FlatCAMGUI(QtGui.QMainWindow): self.menueditnew = self.menuedit.addAction(QtGui.QIcon('share/new_geo16.png'), 'New Geometry') self.menueditedit = self.menuedit.addAction(QtGui.QIcon('share/edit16.png'), 'Edit Geometry') self.menueditok = self.menuedit.addAction(QtGui.QIcon('share/edit_ok16.png'), 'Update Geometry') - #self.menueditok. - #self.menueditcancel = self.menuedit.addAction(QtGui.QIcon('share/cancel_edit16.png'), "Cancel Edit") + # Separator + self.menuedit.addSeparator() self.menueditjoin = self.menuedit.addAction(QtGui.QIcon('share/join16.png'), 'Join Geometry') self.menueditdelete = self.menuedit.addAction(QtGui.QIcon('share/trash16.png'), 'Delete') + self.menuedit.addSeparator() + ### Options ### self.menuoptions = self.menu.addMenu('&Options') @@ -113,23 +115,6 @@ class FlatCAMGUI(QtGui.QMainWindow): self.menuoptions_transfer_a2o = self.menuoptions_transfer.addAction("Application to Object") self.menuoptions_transfer_o2a = self.menuoptions_transfer.addAction("Object to Application") - ### Transform Object ### - self.menuoptions_transform = self.menuoptions.addMenu(QtGui.QIcon('share/transform.png'), '&Transform Object') - self.menuoptions_transform_flipx = self.menuoptions_transform.addAction(QtGui.QIcon('share/flipx.png'), - "Flip Selection on &X axis") - self.menuoptions_transform_flipy = self.menuoptions_transform.addAction(QtGui.QIcon('share/flipy.png'), - "Flip Selection on &Y axis") - # Separator - self.menuoptions_transform.addSeparator() - self.menuoptions_transform_skewx = self.menuoptions_transform.addAction(QtGui.QIcon('share/skewx.png'), - "&Skew Selection on X axis") - self.menuoptions_transform_skewy = self.menuoptions_transform.addAction(QtGui.QIcon('share/skewy.png'), - "S&kew Selection on Y axis") - # Separator - self.menuoptions_transform.addSeparator() - self.menuoptions_transform_rotate = self.menuoptions_transform.addAction(QtGui.QIcon('share/rotate.png'), - "&Rotate Selection") - ### View ### self.menuview = self.menu.addMenu('&View') self.menuviewdisableall = self.menuview.addAction(QtGui.QIcon('share/clear_plot16.png'), 'Disable all plots') diff --git a/DblSidedTool.py b/ToolDblSided.py similarity index 100% rename from DblSidedTool.py rename to ToolDblSided.py diff --git a/MeasurementTool.py b/ToolMeasurement.py similarity index 100% rename from MeasurementTool.py rename to ToolMeasurement.py diff --git a/ToolTransform.py b/ToolTransform.py new file mode 100644 index 00000000..a168421e --- /dev/null +++ b/ToolTransform.py @@ -0,0 +1,319 @@ +from PyQt4 import QtGui, QtCore +from PyQt4 import Qt +from GUIElements import FCEntry, FCButton +from FlatCAMTool import FlatCAMTool +from FlatCAMObj import FlatCAMGerber, FlatCAMExcellon, FlatCAMGeometry + + +class ToolTransform(FlatCAMTool): + + toolName = "Object Transformation" + rotateName = "Rotate Transformation" + skewName = "Skew/Shear Transformation" + flipName = "Flip Transformation" + + def __init__(self, app): + FlatCAMTool.__init__(self, app) + + self.transform_lay = QtGui.QVBoxLayout() + self.layout.addLayout(self.transform_lay) + ## Title + title_label = QtGui.QLabel("%s
" % self.toolName) + self.transform_lay.addWidget(title_label) + + self.empty_label = QtGui.QLabel("") + self.empty_label.setFixedWidth(80) + self.empty_label1 = QtGui.QLabel("") + self.empty_label1.setFixedWidth(80) + self.empty_label2 = QtGui.QLabel("") + self.empty_label2.setFixedWidth(80) + self.transform_lay.addWidget(self.empty_label) + + ## Rotate Title + rotate_title_label = QtGui.QLabel("%s" % self.rotateName) + self.transform_lay.addWidget(rotate_title_label) + + ## Form Layout + form_layout = QtGui.QFormLayout() + self.transform_lay.addLayout(form_layout) + + self.rotate_entry = FCEntry() + self.rotate_entry.setFixedWidth(70) + self.rotate_entry.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) + self.rotate_label = QtGui.QLabel("Angle:") + self.rotate_label.setToolTip( + "Angle for Rotation action, in degrees.\n" + "Float number between -360 and 359.\n" + "Positive numbers for CW motion.\n" + "Negative numbers for CCW motion." + ) + self.rotate_label.setFixedWidth(80) + + self.rotate_button = FCButton() + self.rotate_button.set_value("Rotate") + self.rotate_button.setToolTip( + "Rotate the selected object(s).\n" + "The point of reference is the middle of\n" + "the bounding box for all selected objects.\n" + ) + self.rotate_button.setFixedWidth(70) + + form_layout.addRow(self.rotate_label, self.rotate_entry) + form_layout.addRow(self.empty_label, self.rotate_button) + + self.transform_lay.addWidget(self.empty_label1) + + ## Skew Title + skew_title_label = QtGui.QLabel("%s" % self.skewName) + self.transform_lay.addWidget(skew_title_label) + + ## Form Layout + form1_layout = QtGui.QFormLayout() + self.transform_lay.addLayout(form1_layout) + + self.skewx_entry = FCEntry() + self.skewx_entry.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) + self.skewx_entry.setFixedWidth(70) + self.skewx_label = QtGui.QLabel("Angle:") + self.skewx_label.setToolTip( + "Angle for Skew action, in degrees.\n" + "Float number between -360 and 359." + ) + self.skewx_label.setFixedWidth(80) + + self.skewx_button = FCButton() + self.skewx_button.set_value("Skew_X") + self.skewx_button.setToolTip( + "Skew/shear the selected object(s).\n" + "The point of reference is the middle of\n" + "the bounding box for all selected objects.\n") + self.skewx_button.setFixedWidth(70) + + self.skewy_entry = FCEntry() + self.skewy_entry.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) + self.skewy_entry.setFixedWidth(70) + self.skewy_label = QtGui.QLabel("Angle:") + self.skewy_label.setToolTip( + "Angle for Skew action, in degrees.\n" + "Float number between -360 and 359." + ) + self.skewy_label.setFixedWidth(80) + + self.skewy_button = FCButton() + self.skewy_button.set_value("Skew_Y") + self.skewy_button.setToolTip( + "Skew/shear the selected object(s).\n" + "The point of reference is the middle of\n" + "the bounding box for all selected objects.\n") + self.skewy_button.setFixedWidth(70) + + form1_layout.addRow(self.skewx_label, self.skewx_entry) + form1_layout.addRow(self.empty_label, self.skewx_button) + form1_layout.addRow(self.skewy_label, self.skewy_entry) + form1_layout.addRow(self.empty_label, self.skewy_button) + + self.transform_lay.addWidget(self.empty_label2) + + ## Flip Title + flip_title_label = QtGui.QLabel("%s" % self.flipName) + self.transform_lay.addWidget(flip_title_label) + + ## Form Layout + form2_layout = QtGui.QFormLayout() + self.transform_lay.addLayout(form2_layout) + + self.flipx_button = FCButton() + self.flipx_button.set_value("Flip_X") + self.flipx_button.setToolTip( + "Flip the selected object(s) over the X axis.\n" + "Does not create a new object.\n " + ) + self.flipx_button.setFixedWidth(70) + + self.flipy_button = FCButton() + self.flipy_button.set_value("Flip_Y") + self.flipy_button.setToolTip( + "Flip the selected object(s) over the X axis.\n" + "Does not create a new object.\n " + ) + self.flipy_button.setFixedWidth(70) + + form2_layout.setSpacing(16) + form2_layout.addRow(self.flipx_button, self.flipy_button) + + self.transform_lay.addStretch() + + ## Signals + self.rotate_button.clicked.connect(self.on_rotate) + self.skewx_button.clicked.connect(self.on_skewx) + self.skewy_button.clicked.connect(self.on_skewy) + self.flipx_button.clicked.connect(self.on_flipx) + self.flipy_button.clicked.connect(self.on_flipy) + + self.rotate_entry.returnPressed.connect(self.on_rotate) + self.skewx_entry.returnPressed.connect(self.on_skewx) + self.skewy_entry.returnPressed.connect(self.on_skewy) + + ## Initialize form + self.rotate_entry.set_value('0') + self.skewx_entry.set_value('0') + self.skewy_entry.set_value('0') + + def on_rotate(self): + value = float(self.rotate_entry.get_value()) + self.on_rotate_action(value) + return + + def on_flipx(self): + self.on_flip("Y") + return + + def on_flipy(self): + self.on_flip("X") + return + + def on_skewx(self): + value = float(self.skewx_entry.get_value()) + self.on_skew("X", value) + return + + def on_skewy(self): + value = float(self.skewy_entry.get_value()) + self.on_skew("Y", value) + return + + def on_rotate_action(self, num): + obj_list = self.app.collection.get_selected() + xminlist = [] + yminlist = [] + xmaxlist = [] + ymaxlist = [] + + if not obj_list: + self.app.inform.emit("WARNING: No object selected.") + msg = "Please Select an object to rotate!" + warningbox = QtGui.QMessageBox() + warningbox.setText(msg) + warningbox.setWindowTitle("Warning ...") + warningbox.setWindowIcon(QtGui.QIcon('share/warning.png')) + warningbox.setStandardButtons(QtGui.QMessageBox.Ok) + warningbox.setDefaultButton(QtGui.QMessageBox.Ok) + warningbox.exec_() + else: + try: + # first get a bounding box to fit all + for obj in obj_list: + xmin, ymin, xmax, ymax = obj.bounds() + xminlist.append(xmin) + yminlist.append(ymin) + xmaxlist.append(xmax) + ymaxlist.append(ymax) + + # get the minimum x,y and maximum x,y for all objects selected + xminimal = min(xminlist) + yminimal = min(yminlist) + xmaximal = max(xmaxlist) + ymaximal = max(ymaxlist) + + for sel_obj in obj_list: + px = 0.5 * (xminimal + xmaximal) + py = 0.5 * (yminimal + ymaximal) + + sel_obj.rotate(-num, point=(px, py)) + sel_obj.plot() + self.app.inform.emit('Object was rotated ...') + except Exception as e: + self.app.inform.emit("[ERROR] Due of %s, rotation movement was not executed." % str(e)) + return + + def on_flip(self, axis): + obj_list = self.app.collection.get_selected() + xminlist = [] + yminlist = [] + xmaxlist = [] + ymaxlist = [] + + if not obj_list: + self.app.inform.emit("WARNING: No object selected.") + msg = "Please Select an object to flip!" + warningbox = QtGui.QMessageBox() + warningbox.setText(msg) + warningbox.setWindowTitle("Warning ...") + warningbox.setWindowIcon(QtGui.QIcon('share/warning.png')) + warningbox.setStandardButtons(QtGui.QMessageBox.Ok) + warningbox.setDefaultButton(QtGui.QMessageBox.Ok) + warningbox.exec_() + return + else: + try: + # first get a bounding box to fit all + for obj in obj_list: + xmin, ymin, xmax, ymax = obj.bounds() + xminlist.append(xmin) + yminlist.append(ymin) + xmaxlist.append(xmax) + ymaxlist.append(ymax) + + # get the minimum x,y and maximum x,y for all objects selected + xminimal = min(xminlist) + yminimal = min(yminlist) + xmaximal = max(xmaxlist) + ymaximal = max(ymaxlist) + + px = 0.5 * (xminimal + xmaximal) + py = 0.5 * (yminimal + ymaximal) + + # execute mirroring + for obj in obj_list: + if axis is 'X': + obj.mirror('X', [px, py]) + obj.plot() + self.app.inform.emit('Flipped on the Y axis ...') + elif axis is 'Y': + obj.mirror('Y', [px, py]) + obj.plot() + self.app.inform.emit('Flipped on the X axis ...') + + except Exception as e: + self.app.inform.emit("[ERROR] Due of %s, Flip action was not executed.") + return + + def on_skew(self, axis, num): + obj_list = self.app.collection.get_selected() + xminlist = [] + yminlist = [] + + if not obj_list: + self.app.inform.emit("WARNING: No object selected.") + msg = "Please Select an object to skew/shear!" + warningbox = QtGui.QMessageBox() + warningbox.setText(msg) + warningbox.setWindowTitle("Warning ...") + warningbox.setWindowIcon(QtGui.QIcon('share/warning.png')) + warningbox.setStandardButtons(QtGui.QMessageBox.Ok) + warningbox.setDefaultButton(QtGui.QMessageBox.Ok) + warningbox.exec_() + else: + try: + # first get a bounding box to fit all + for obj in obj_list: + xmin, ymin, xmax, ymax = obj.bounds() + xminlist.append(xmin) + yminlist.append(ymin) + + # get the minimum x,y and maximum x,y for all objects selected + xminimal = min(xminlist) + yminimal = min(yminlist) + + for obj in obj_list: + if axis is 'X': + obj.skew(num, 0, point=(xminimal, yminimal)) + elif axis is 'Y': + obj.skew(0, num, point=(xminimal, yminimal)) + obj.plot() + self.app.inform.emit('Object was skewed on %s axis ...' % str(axis)) + except Exception as e: + self.app.inform.emit("[ERROR] Due of %s, Skew action was not executed." % str(e)) + return + +# end of file \ No newline at end of file