diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 69783a4b..a446cedd 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -2367,7 +2367,8 @@ class App(QtCore.QObject): # ################################################################################## self.dblsidedtool = None - self.measurement_tool = None + self.distance_tool = None + self.distance_min_tool = None self.panelize_tool = None self.film_tool = None self.paste_tool = None @@ -2773,15 +2774,15 @@ class App(QtCore.QObject): self.on_fileopengerber(name=file_name) return - # if it reached here without already returning then the app was registered with a file that it does not - # recognize therefore we must quit but take into consideration the app reboot from within, in that case - # the args_to_process will contain the path to the FlatCAM.exe (cx_freezed executable) + # if it reached here without already returning then the app was registered with a file that it does not + # recognize therefore we must quit but take into consideration the app reboot from within, in that case + # the args_to_process will contain the path to the FlatCAM.exe (cx_freezed executable) - for arg in args_to_process: - if 'FlatCAM.exe' in arg: - continue - else: - sys.exit(2) + for arg in args_to_process: + if 'FlatCAM.exe' in arg: + continue + else: + sys.exit(2) def set_ui_title(self, name): """ @@ -2894,10 +2895,15 @@ class App(QtCore.QObject): self.dblsidedtool = DblSidedTool(self) self.dblsidedtool.install(icon=QtGui.QIcon('share/doubleside16.png'), separator=True) - self.measurement_tool = Distance(self) - self.measurement_tool.install(icon=QtGui.QIcon('share/measure16.png'), pos=self.ui.menuedit, - before=self.ui.menueditorigin, - separator=True) + self.distance_tool = Distance(self) + self.distance_tool.install(icon=QtGui.QIcon('share/measure16.png'), pos=self.ui.menuedit, + before=self.ui.menueditorigin, + separator=False) + + self.distance_min_tool = DistanceMin(self) + self.distance_min_tool.install(icon=QtGui.QIcon('share/measure16.png'), pos=self.ui.menuedit, + before=self.ui.menueditorigin, + separator=True) self.panelize_tool = Panelize(self) self.panelize_tool.install(icon=QtGui.QIcon('share/panel16.png')) @@ -2926,15 +2932,15 @@ class App(QtCore.QObject): self.cutout_tool = CutOut(self) self.cutout_tool.install(icon=QtGui.QIcon('share/cut16_bis.png'), pos=self.ui.menutool, - before=self.measurement_tool.menuAction) + before=self.sub_tool.menuAction) self.ncclear_tool = NonCopperClear(self) self.ncclear_tool.install(icon=QtGui.QIcon('share/ncc16.png'), pos=self.ui.menutool, - before=self.measurement_tool.menuAction, separator=True) + before=self.sub_tool.menuAction, separator=True) self.paint_tool = ToolPaint(self) self.paint_tool.install(icon=QtGui.QIcon('share/paint16.png'), pos=self.ui.menutool, - before=self.measurement_tool.menuAction, separator=True) + before=self.sub_tool.menuAction, separator=True) self.transform_tool = ToolTransform(self) self.transform_tool.install(icon=QtGui.QIcon('share/transform.png'), pos=self.ui.menuoptions, separator=True) diff --git a/README.md b/README.md index d9fc3f1d..aa68490d 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,12 @@ CAD program, and create G-Code for Isolation routing. ================================================= +30.09.2019 + +- modified the Distance Tool such that the numbe of decimals all over the tool is set in one place by the self.decimals +- added a new tool named Minimum Distance Tool who will calculate the minimum distance between two objects; key shortcut: SHIFT + M +- finished the Minimum Distance Tool in case of using it at the object level (not in Editors) + 29.09.2019 - work done for the GUI layout of the Rule Check Tool diff --git a/flatcamGUI/FlatCAMGUI.py b/flatcamGUI/FlatCAMGUI.py index adb21c80..ab2be44a 100644 --- a/flatcamGUI/FlatCAMGUI.py +++ b/flatcamGUI/FlatCAMGUI.py @@ -1185,6 +1185,10 @@ class FlatCAMGUI(QtWidgets.QMainWindow): SHIFT+G  %s + + SHIFT+M +  %s + SHIFT+P  %s @@ -1334,7 +1338,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow): _("Flip on X_axis"), _("Flip on Y_axis"), _("Zoom Out"), _("Zoom In"), _("Select All"), _("Copy Obj"), _("Open Excellon File"), _("Open Gerber File"), _("New Project"), _("Distance Tool"), _("Open Project"), _("Save Project As"), _("Toggle Plot Area"), _("Copy Obj_Name"), - _("Toggle Code Editor"), _("Toggle the axis"), _("Open Preferences Window"), + _("Toggle Code Editor"), _("Toggle the axis"), _("Distance Minimum Tool"), _("Open Preferences Window"), _("Rotate by 90 degree CCW"), _("Run a Script"), _("Toggle the workspace"), _("Skew on X axis"), _("Skew on Y axis"), _("Calculators Tool"), _("2-Sided PCB Tool"), _("Transformations Tool"), _("Solder Paste Dispensing Tool"), @@ -1445,6 +1449,10 @@ class FlatCAMGUI(QtWidgets.QMainWindow):     + + SHIFT+M +  %s + SHIFT+X  %s @@ -1514,9 +1522,10 @@ class FlatCAMGUI(QtWidgets.QMainWindow): _("Geo Paint Tool"), _("Jump to Location (x, y)"), _("Toggle Corner Snap"), _("Move Geo Item"), _("Within Add Arc will cycle through the ARC modes"), _("Draw a Polygon"), _("Draw a Circle"), _("Draw a Path"), _("Draw Rectangle"), _("Polygon Subtraction Tool"), _("Add Text Tool"), - _("Polygon Union Tool"), _("Flip shape on X axis"), _("Flip shape on Y axis"), _("Skew shape on X axis"), - _("Skew shape on Y axis"), _("Editor Transformation Tool"), _("Offset shape on X axis"), - _("Offset shape on Y axis"), _("Distance Tool"), _("Save Object and Exit Editor"), _("Polygon Cut Tool"), + _("Polygon Union Tool"), _("Flip shape on X axis"), _("Flip shape on Y axis"), _("Distance Minimum Tool"), + _("Skew shape on X axis"), _("Skew shape on Y axis"), _("Editor Transformation Tool"), + _("Offset shape on X axis"), _("Offset shape on Y axis"), _("Distance Tool"), + _("Save Object and Exit Editor"), _("Polygon Cut Tool"), _("Rotate Geometry"), _("Finish drawing for certain tools"), _("Abort and return to Select"), _("Delete Shape") ) @@ -1566,6 +1575,14 @@ class FlatCAMGUI(QtWidgets.QMainWindow):     + + SHIFT+M +  %s + + +   +   + Del  %s @@ -1592,7 +1609,8 @@ class FlatCAMGUI(QtWidgets.QMainWindow): """ % ( _("EXCELLON EDITOR"), _("Add Drill Array"), _("Copy Drill(s)"), _("Add Drill"), _("Jump to Location (x, y)"), _("Move Drill(s)"), _("Add Slot Array"), _("Resize Drill(s)"), - _("Add a new Tool"), _("Add Slot"), _("Delete Drill(s)"), _("Alternate: Delete Tool(s)"), + _("Add a new Tool"), _("Add Slot"), _("Distance Minimum Tool"), + _("Delete Drill(s)"), _("Alternate: Delete Tool(s)"), _("Abort and return to Select"), _("Save Object and Exit Editor") ) @@ -1665,14 +1683,22 @@ class FlatCAMGUI(QtWidgets.QMainWindow): Del  %s + + ESC +  %s +     - ESC + SHIFT+M  %s + +   +   + CTRL+E  %s @@ -1705,7 +1731,8 @@ class FlatCAMGUI(QtWidgets.QMainWindow): _("Jump to Location (x, y)"), _("Move"), _("Add Region"), _("Add Pad"), _("Within Track & Region Tools will cycle in REVERSE the bend modes"), _("Scale"), _("Add Track"), _("Within Track & Region Tools will cycle FORWARD the bend modes"), _("Delete"), - _("Alternate: Delete Apertures"), _("Abort and return to Select"), _("Eraser Tool"), + _("Alternate: Delete Apertures"), _("Abort and return to Select"), _("Distance Minimum Tool"), + _("Eraser Tool"), _("Save Object and Exit Editor"), _("Mark Area Tool"), _("Poligonize Tool"), _("Transformation Tool") ) @@ -2340,7 +2367,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.app.on_file_new_click() if key == QtCore.Qt.Key_M: - self.app.measurement_tool.run() + self.app.distance_tool.run() if key == QtCore.Qt.Key_O: self.app.on_file_openproject() @@ -2367,6 +2394,11 @@ class FlatCAMGUI(QtWidgets.QMainWindow): if key == QtCore.Qt.Key_G: self.app.on_toggle_axis() + # Run Distance Minimum Tool + if key == QtCore.Qt.Key_M: + self.app.distance_min_tool.run() + return + # Open Preferences Window if key == QtCore.Qt.Key_P: self.app.on_preferences() @@ -2642,7 +2674,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow): # toggle the measurement tool if key == QtCore.Qt.Key_M or key == 'M': - self.app.measurement_tool.run() + self.app.distance_tool.run() return # Cut Action Tool @@ -2665,6 +2697,11 @@ class FlatCAMGUI(QtWidgets.QMainWindow): return elif modifiers == QtCore.Qt.ShiftModifier: + # Run Distance Minimum Tool + if key == QtCore.Qt.Key_M or key == 'M': + self.app.distance_min_tool.run() + return + # Skew on X axis if key == QtCore.Qt.Key_X or key == 'X': self.app.geo_editor.transform_tool.on_skewx_key() @@ -2910,11 +2947,14 @@ class FlatCAMGUI(QtWidgets.QMainWindow): # toggle the measurement tool if key == QtCore.Qt.Key_M or key == 'M': - self.app.measurement_tool.run() + self.app.distance_tool.run() return elif modifiers == QtCore.Qt.ShiftModifier: - pass + # Run Distance Minimum Tool + if key == QtCore.Qt.Key_M or key == 'M': + self.app.distance_min_tool.run() + return elif modifiers == QtCore.Qt.AltModifier: # Mark Area Tool if key == QtCore.Qt.Key_A or key == 'A': @@ -3135,11 +3175,14 @@ class FlatCAMGUI(QtWidgets.QMainWindow): # toggle the measurement tool if key == QtCore.Qt.Key_M or key == 'M': - self.app.measurement_tool.run() + self.app.distance_tool.run() return elif modifiers == QtCore.Qt.ShiftModifier: - pass + # Run Distance Minimum Tool + if key == QtCore.Qt.Key_M or key == 'M': + self.app.distance_min_tool.run() + return elif modifiers == QtCore.Qt.AltModifier: pass elif modifiers == QtCore.Qt.NoModifier: @@ -3365,7 +3408,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow): elif modifiers == QtCore.Qt.NoModifier: if key == QtCore.Qt.Key_Escape or key == 'Escape': # abort the measurement action - self.app.measurement_tool.deactivate_measure_tool() + self.app.distance_tool.deactivate_measure_tool() self.app.inform.emit(_("Distance Tool exit...")) return @@ -3373,6 +3416,10 @@ class FlatCAMGUI(QtWidgets.QMainWindow): self.app.ui.grid_snap_btn.trigger() return + # Jump to coords + if key == QtCore.Qt.Key_J or key == 'J': + self.app.on_jump_to() + def createPopupMenu(self): menu = super().createPopupMenu() diff --git a/flatcamTools/ToolDistance.py b/flatcamTools/ToolDistance.py index 3c1bd13b..99d17cc1 100644 --- a/flatcamTools/ToolDistance.py +++ b/flatcamTools/ToolDistance.py @@ -121,6 +121,12 @@ class Distance(FlatCAMTool): self.original_call_source = 'app' + # store here the event connection ID's + self.mm = None + self.mr = None + + self.decimals = 4 + # VisPy visuals if self.app.is_legacy is False: self.sel_shapes = ShapeCollection(parent=self.app.plotcanvas.view.scene, layers=1) @@ -310,37 +316,44 @@ class Distance(FlatCAMTool): # Reset here the relative coordinates so there is a new reference on the click position if self.rel_point1 is None: - self.app.ui.rel_position_label.setText("Dx: %.4f   Dy: " - "%.4f    " % (0.0, 0.0)) + self.app.ui.rel_position_label.setText("Dx: %.*f   Dy: " + "%.*f    " % + (self.decimals, 0.0, self.decimals, 0.0)) self.rel_point1 = pos else: self.rel_point2 = copy(self.rel_point1) self.rel_point1 = pos if len(self.points) == 1: - self.start_entry.set_value("(%.4f, %.4f)" % pos) + self.start_entry.set_value("(%.*f, %.*f)" % (self.decimals, pos[0], self.decimals, pos[1])) self.app.inform.emit(_("MEASURING: Click on the Destination point ...")) elif len(self.points) == 2: dx = self.points[1][0] - self.points[0][0] dy = self.points[1][1] - self.points[0][1] d = sqrt(dx ** 2 + dy ** 2) - self.stop_entry.set_value("(%.4f, %.4f)" % pos) + self.stop_entry.set_value("(%.*f, %.*f)" % (self.decimals, pos[0], self.decimals, pos[1])) self.app.inform.emit(_("MEASURING: Result D(x) = {d_x} | D(y) = {d_y} | Distance = {d_z}").format( - d_x='%4f' % abs(dx), d_y='%4f' % abs(dy), d_z='%4f' % abs(d))) + d_x='%*f' % (self.decimals, abs(dx)), + d_y='%*f' % (self.decimals, abs(dy)), + d_z='%*f' % (self.decimals, abs(d))) + ) - self.distance_x_entry.set_value('%.4f' % abs(dx)) - self.distance_y_entry.set_value('%.4f' % abs(dy)) + self.distance_x_entry.set_value('%.*f' % (self.decimals, abs(dx))) + self.distance_y_entry.set_value('%.*f' % (self.decimals, abs(dy))) try: angle = math.degrees(math.atan(dy / dx)) - self.angle_entry.set_value('%.4f' % angle) + self.angle_entry.set_value('%.*f' % (self.decimals, angle)) except Exception as e: pass - self.total_distance_entry.set_value('%.4f' % abs(d)) - self.app.ui.rel_position_label.setText("Dx: {0:.4f}   Dy: " - "{0:.4f}    ".format(pos[0], pos[1])) + self.total_distance_entry.set_value('%.*f' % (self.decimals, abs(d))) + self.app.ui.rel_position_label.setText( + "Dx: {}   Dy: {}    ".format( + '%.*f' % (self.decimals, pos[0]), '%.*f' % (self.decimals, pos[1]) + ) + ) self.deactivate_measure_tool() def on_mouse_move_meas(self, event): @@ -368,8 +381,11 @@ class Distance(FlatCAMTool): else: pos = (pos_canvas[0], pos_canvas[1]) - self.app.ui.position_label.setText("    X: {0:.4f}   " - "Y: {0:.4f}".format(pos[0], pos[1])) + self.app.ui.position_label.setText( + "    X: {}   Y: {}".format( + '%.*f' % (self.decimals, pos[0]), '%.*f' % (self.decimals, pos[1]) + ) + ) if self.rel_point1 is not None: dx = pos[0] - float(self.rel_point1[0]) @@ -378,8 +394,11 @@ class Distance(FlatCAMTool): dx = pos[0] dy = pos[1] - self.app.ui.rel_position_label.setText("Dx: {0:.4f}   Dy: " - "{0:.4f}    ".format(dx, dy)) + self.app.ui.rel_position_label.setText( + "Dx: {}   Dy: {}    ".format( + '%.*f' % (self.decimals, dx), '%.*f' % (self.decimals, dy) + ) + ) # update utility geometry if len(self.points) == 1: @@ -387,7 +406,7 @@ class Distance(FlatCAMTool): # and display the temporary angle try: angle = math.degrees(math.atan(dy / dx)) - self.angle_entry.set_value('%.4f' % angle) + self.angle_entry.set_value('%.*f' % (self.decimals, angle)) except Exception as e: pass diff --git a/flatcamTools/ToolDistanceMin.py b/flatcamTools/ToolDistanceMin.py new file mode 100644 index 00000000..69393325 --- /dev/null +++ b/flatcamTools/ToolDistanceMin.py @@ -0,0 +1,254 @@ +# ########################################################## +# FlatCAM: 2D Post-processing for Manufacturing # +# http://flatcam.org # +# File Author: Marius Adrian Stanciu (c) # +# Date: 09/29/2019 # +# MIT Licence # +# ########################################################## + +from FlatCAMTool import FlatCAMTool +from FlatCAMObj import * +from flatcamGUI.VisPyVisuals import * + +from shapely.ops import nearest_points + +from math import sqrt + +import gettext +import FlatCAMTranslation as fcTranslate +import builtins + +fcTranslate.apply_language('strings') +if '_' not in builtins.__dict__: + _ = gettext.gettext + + +class DistanceMin(FlatCAMTool): + + toolName = _("Minimum Distance Tool") + + def __init__(self, app): + FlatCAMTool.__init__(self, app) + + self.app = app + self.canvas = self.app.plotcanvas + self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().lower() + + # ## Title + title_label = QtWidgets.QLabel("%s
" % self.toolName) + self.layout.addWidget(title_label) + + # ## Form Layout + form_layout = QtWidgets.QFormLayout() + self.layout.addLayout(form_layout) + + self.units_label = QtWidgets.QLabel('%s:' % _("Units")) + self.units_label.setToolTip(_("Those are the units in which the distance is measured.")) + self.units_value = QtWidgets.QLabel("%s" % str({'mm': _("METRIC (mm)"), 'in': _("INCH (in)")}[self.units])) + self.units_value.setDisabled(True) + + self.start_label = QtWidgets.QLabel("%s:" % _('First object point')) + self.start_label.setToolTip(_("This is first object point coordinates.\n" + "This is the start point for measuring distance.")) + + self.stop_label = QtWidgets.QLabel("%s:" % _('Second object point')) + self.stop_label.setToolTip(_("This is second object point coordinates.\n" + "This is the end point for measuring distance.")) + + self.distance_x_label = QtWidgets.QLabel('%s:' % _("Dx")) + self.distance_x_label.setToolTip(_("This is the distance measured over the X axis.")) + + self.distance_y_label = QtWidgets.QLabel('%s:' % _("Dy")) + self.distance_y_label.setToolTip(_("This is the distance measured over the Y axis.")) + + self.angle_label = QtWidgets.QLabel('%s:' % _("Angle")) + self.angle_label.setToolTip(_("This is orientation angle of the measuring line.")) + + self.total_distance_label = QtWidgets.QLabel("%s:" % _('DISTANCE')) + self.total_distance_label.setToolTip(_("This is the point to point Euclidean distance.")) + + self.half_point_label = QtWidgets.QLabel("%s:" % _('Half Point')) + self.half_point_label.setToolTip(_("This is the middle point of the point to point Euclidean distance.")) + + self.start_entry = FCEntry() + self.start_entry.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) + self.start_entry.setToolTip(_("This is first object point coordinates.\n" + "This is the start point for measuring distance.")) + + self.stop_entry = FCEntry() + self.stop_entry.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) + self.stop_entry.setToolTip(_("This is second object point coordinates.\n" + "This is the end point for measuring distance.")) + + self.distance_x_entry = FCEntry() + self.distance_x_entry.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) + self.distance_x_entry.setToolTip(_("This is the distance measured over the X axis.")) + + self.distance_y_entry = FCEntry() + self.distance_y_entry.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) + self.distance_y_entry.setToolTip(_("This is the distance measured over the Y axis.")) + + self.angle_entry = FCEntry() + self.angle_entry.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) + self.angle_entry.setToolTip(_("This is orientation angle of the measuring line.")) + + self.total_distance_entry = FCEntry() + self.total_distance_entry.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) + self.total_distance_entry.setToolTip(_("This is the point to point Euclidean distance.")) + + self.half_point_entry = FCEntry() + self.half_point_entry.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) + self.half_point_entry.setToolTip(_("This is the middle point of the point to point Euclidean distance.")) + + self.measure_btn = QtWidgets.QPushButton(_("Measure")) + self.layout.addWidget(self.measure_btn) + + self.jump_hp_btn = QtWidgets.QPushButton(_("Jump to Half Point")) + self.layout.addWidget(self.jump_hp_btn) + self.jump_hp_btn.setDisabled(True) + + form_layout.addRow(self.units_label, self.units_value) + form_layout.addRow(self.start_label, self.start_entry) + form_layout.addRow(self.stop_label, self.stop_entry) + form_layout.addRow(self.distance_x_label, self.distance_x_entry) + form_layout.addRow(self.distance_y_label, self.distance_y_entry) + form_layout.addRow(self.angle_label, self.angle_entry) + form_layout.addRow(self.total_distance_label, self.total_distance_entry) + form_layout.addRow(self.half_point_label, self.half_point_entry) + + # initial view of the layout + self.start_entry.set_value('(0, 0)') + self.stop_entry.set_value('(0, 0)') + self.distance_x_entry.set_value('0.0') + self.distance_y_entry.set_value('0.0') + self.angle_entry.set_value('0.0') + self.total_distance_entry.set_value('0.0') + self.half_point_entry.set_value('(0, 0)') + + self.layout.addStretch() + + self.decimals = 4 + self.h_point = (0, 0) + + self.measure_btn.clicked.connect(self.activate_measure_tool) + self.jump_hp_btn.clicked.connect(self.on_jump_to_half_point) + + def run(self, toggle=False): + self.app.report_usage("ToolDistance()") + + if self.app.tool_tab_locked is True: + return + + self.app.ui.notebook.setTabText(2, _("Minimum Distance Tool")) + + # if the splitter is hidden, display it + if self.app.ui.splitter.sizes()[0] == 0: + self.app.ui.splitter.setSizes([1, 1]) + + if toggle: + pass + + self.set_tool_ui() + self.app.inform.emit('MEASURING: %s' % + _("Select two objects and no more, to measure the distance between them ...")) + + def install(self, icon=None, separator=None, **kwargs): + FlatCAMTool.install(self, icon, separator, shortcut='SHIFT+M', **kwargs) + + def set_tool_ui(self): + # Remove anything else in the GUI + self.app.ui.tool_scroll_area.takeWidget() + + # Put oneself in the GUI + self.app.ui.tool_scroll_area.setWidget(self) + + # Switch notebook to tool page + self.app.ui.notebook.setCurrentWidget(self.app.ui.tool_tab) + + self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().lower() + + # initial view of the layout + self.start_entry.set_value('(0, 0)') + self.stop_entry.set_value('(0, 0)') + + self.distance_x_entry.set_value('0.0') + self.distance_y_entry.set_value('0.0') + self.angle_entry.set_value('0.0') + self.total_distance_entry.set_value('0.0') + self.half_point_entry.set_value('(0, 0)') + + self.jump_hp_btn.setDisabled(True) + + log.debug("Distance Tool --> tool initialized") + + def activate_measure_tool(self): + # ENABLE the Measuring TOOL + self.jump_hp_btn.setDisabled(False) + + self.units = self.app.ui.general_defaults_form.general_app_group.units_radio.get_value().lower() + + if self.app.call_source == 'app': + selected_objs = self.app.collection.get_selected() + if len(selected_objs) != 2: + self.app.inform.emit('[WARNING_NOTCL] %s %s' % + (_("Select two objects and no more. Currently the selection has objects: "), + str(len(selected_objs)))) + return + else: + first_pos, last_pos = nearest_points(selected_objs[0].solid_geometry, selected_objs[1].solid_geometry) + + self.start_entry.set_value("(%.*f, %.*f)" % (self.decimals, first_pos.x, self.decimals, first_pos.y)) + self.stop_entry.set_value("(%.*f, %.*f)" % (self.decimals, last_pos.x, self.decimals, last_pos.y)) + + dx = first_pos.x - last_pos.x + dy = first_pos.y - last_pos.y + + self.distance_x_entry.set_value('%.*f' % (self.decimals, abs(dx))) + self.distance_y_entry.set_value('%.*f' % (self.decimals, abs(dy))) + + try: + angle = math.degrees(math.atan(dy / dx)) + self.angle_entry.set_value('%.*f' % (self.decimals, angle)) + except Exception as e: + pass + + d = sqrt(dx ** 2 + dy ** 2) + self.total_distance_entry.set_value('%.*f' % (self.decimals, abs(d))) + + self.h_point = (first_pos.x + (abs(dx) / 2), first_pos.y + (abs(dy) / 2)) + if d != 0: + self.half_point_entry.set_value( + "(%.*f, %.*f)" % (self.decimals, self.h_point[0], self.decimals, self.h_point[1]) + ) + else: + self.half_point_entry.set_value( + "(%.*f, %.*f)" % (self.decimals, 0.0, self.decimals, 0.0) + ) + elif self.app.call_source == 'geo_editor': + pass + elif self.app.call_source == 'exc_editor': + pass + elif self.app.call_source == 'grb_editor': + pass + + if d != 0: + self.app.inform.emit(_("MEASURING: Result D(x) = {d_x} | D(y) = {d_y} | Distance = {d_z}").format( + d_x='%*f' % (self.decimals, abs(dx)), + d_y='%*f' % (self.decimals, abs(dy)), + d_z='%*f' % (self.decimals, abs(d))) + ) + else: + self.app.inform.emit('[WARNING_NOTCL] %s: %s' % + (_("Objects intersects or touch at"), + "(%.*f, %.*f)" % (self.decimals, self.h_point[0], self.decimals, self.h_point[1]))) + + def on_jump_to_half_point(self): + self.app.on_jump_to(custom_location=self.h_point) + self.app.inform.emit('[success] %s: %s' % + (_("Jumped to the half point between the two selected objects"), + "(%.*f, %.*f)" % (self.decimals, self.h_point[0], self.decimals, self.h_point[1]))) + + def set_meas_units(self, units): + self.meas.units_label.setText("[" + self.app.options["units"].lower() + "]") + +# end of file diff --git a/flatcamTools/ToolOptimal.py b/flatcamTools/ToolOptimal.py index 619cb10c..554d42f3 100644 --- a/flatcamTools/ToolOptimal.py +++ b/flatcamTools/ToolOptimal.py @@ -1,3 +1,11 @@ +# ########################################################## +# FlatCAM: 2D Post-processing for Manufacturing # +# http://flatcam.org # +# File Author: Marius Adrian Stanciu (c) # +# Date: 09/27/2019 # +# MIT Licence # +# ########################################################## + from FlatCAMTool import FlatCAMTool from FlatCAMObj import * from shapely.geometry import Point diff --git a/flatcamTools/__init__.py b/flatcamTools/__init__.py index 953c1774..f12e59a2 100644 --- a/flatcamTools/__init__.py +++ b/flatcamTools/__init__.py @@ -11,6 +11,8 @@ from flatcamTools.ToolFilm import Film from flatcamTools.ToolImage import ToolImage from flatcamTools.ToolDistance import Distance +from flatcamTools.ToolDistanceMin import DistanceMin + from flatcamTools.ToolMove import ToolMove from flatcamTools.ToolNonCopperClear import NonCopperClear