From 49120c088ee9393a5f4a6a013194b2487990149a Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Tue, 23 Apr 2019 13:13:10 +0300 Subject: [PATCH] - Gerber Editor: made Add Pad repeat until user exits the Add Pad through either mouse right click, or ESC key or deselecting the Add Pad menu item - Gerber and Geometry Editors: fixed some issues with the Add Arc/Add Semidisc; in mode 132, the norm() function was not the one from numpy but from a FlatCAM Class. Also fixed some of the texts and made sure that when changing the mode, the current points are reset to prepare for the newly selected mode. --- FlatCAMApp.py | 2 +- README.md | 2 ++ camlib.py | 6 +++- flatcamEditors/FlatCAMGeoEditor.py | 37 ++++++++++++++-------- flatcamEditors/FlatCAMGrbEditor.py | 50 ++++++++++++++++++++---------- 5 files changed, 65 insertions(+), 32 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index c05d27c7..4c195ccb 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -4508,7 +4508,7 @@ class App(QtCore.QObject): jump_loc = self.plotcanvas.vispy_canvas.translate_coords_2((location[0], location[1])) cursor.setPos(canvas_origin.x() + jump_loc[0], (canvas_origin.y() + jump_loc[1])) - self.inform.emit(_("Done.")) + self.inform.emit(_("[success] Done.")) def on_copy_object(self): self.report_usage("on_copy_object()") diff --git a/README.md b/README.md index c4227757..d2f06309 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ CAD program, and create G-Code for Isolation routing. 23.04.2019 - Gerber Editor: added two new tools: Add Disc and Add SemiDisc (porting of Circle and Arc from Geometry Editor) +- Gerber Editor: made Add Pad repeat until user exits the Add Pad through either mouse right click, or ESC key or deselecting the Add Pad menu item +- Gerber and Geometry Editors: fixed some issues with the Add Arc/Add Semidisc; in mode 132, the norm() function was not the one from numpy but from a FlatCAM Class. Also fixed some of the texts and made sure that when changing the mode, the current points are reset to prepare for the newly selected mode. 22.04.2019 diff --git a/camlib.py b/camlib.py index 178a66fe..7340501b 100644 --- a/camlib.py +++ b/camlib.py @@ -7701,7 +7701,11 @@ def three_point_circle(p1, p2, p3): b2 = dot((p3 - p2), array([[0, 1], [-1, 0]], dtype=float32)) # Params - T = solve(transpose(array([-b1, b2])), a1 - a2) + try: + T = solve(transpose(array([-b1, b2])), a1 - a2) + except Exception as e: + log.debug("camlib.three_point_circle() --> %s" % str(e)) + return # Center center = a1 + b1 * T[0] diff --git a/flatcamEditors/FlatCAMGeoEditor.py b/flatcamEditors/FlatCAMGeoEditor.py index 4af68b11..f5973f5e 100644 --- a/flatcamEditors/FlatCAMGeoEditor.py +++ b/flatcamEditors/FlatCAMGeoEditor.py @@ -22,7 +22,7 @@ from shapely.ops import cascaded_union import shapely.affinity as affinity from numpy import arctan2, Inf, array, sqrt, sign, dot -from numpy.linalg import norm +from numpy.linalg import norm as numpy_norm from rtree import index as rtindex from flatcamGUI.GUIElements import OptionalInputSection, FCCheckBox, FCEntry, FCComboBox, FCTextAreaRich, \ @@ -1939,14 +1939,15 @@ class FCCircle(FCShapeTool): self.cursor = QtGui.QCursor(QtGui.QPixmap('share/aero_circle.png')) QtGui.QGuiApplication.setOverrideCursor(self.cursor) - self.start_msg = _("Click on CENTER ...") + self.start_msg = _("Click on Center point ...") + self.draw_app.app.inform.emit(_("Click on Center point ...")) self.steps_per_circ = self.draw_app.app.defaults["geometry_circle_steps"] def click(self, point): self.points.append(point) if len(self.points) == 1: - self.draw_app.app.inform.emit(_("Click on Circle perimeter point to complete ...")) + self.draw_app.app.inform.emit(_("Click on Perimeter point to complete ...")) return "Click on perimeter to complete ..." if len(self.points) == 2: @@ -1983,7 +1984,8 @@ class FCArc(FCShapeTool): DrawTool.__init__(self, draw_app) self.name = 'arc' - self.start_msg = _("Click on CENTER ...") + self.start_msg = _("Click on Center point ...") + self.draw_app.app.inform.emit(_("Click on Center point ...")) # Direction of rotation between point 1 and 2. # 'cw' or 'ccw'. Switch direction by hitting the @@ -2007,14 +2009,14 @@ class FCArc(FCShapeTool): elif self.mode == '132': self.draw_app.app.inform.emit(_("Click on Point3 ...")) else: - self.draw_app.app.inform.emit(_("Click on Stop point to complete ...")) + self.draw_app.app.inform.emit(_("Click on Stop point ...")) return "Click on 1st point ..." if len(self.points) == 2: if self.mode == 'c12': self.draw_app.app.inform.emit(_("Click on Stop point to complete ...")) elif self.mode == '132': - self.draw_app.app.inform.emit(_("Click on Point2 ...")) + self.draw_app.app.inform.emit(_("Click on Point2 to complete ...")) else: self.draw_app.app.inform.emit(_("Click on Center point to complete ...")) return "Click on 2nd point to complete ..." @@ -2031,15 +2033,20 @@ class FCArc(FCShapeTool): return _('Direction: %s') % self.direction.upper() if key == 'M' or key == QtCore.Qt.Key_M: + # delete the possible points made before this action; we want to start anew + self.points[:] = [] + # and delete the utility geometry made up until this point + self.draw_app.delete_utility_geometry() + if self.mode == 'c12': self.mode = '12c' return _('Mode: Start -> Stop -> Center. Click on Start point ...') elif self.mode == '12c': self.mode = '132' - return _('Mode: Point1 -> Point3 -> Point2. Click on 1st point ...') + return _('Mode: Point1 -> Point3 -> Point2. Click on Point1 ...') else: self.mode = 'c12' - return _('Mode: Center -> Start -> Stop. Click on Center ...') + return _('Mode: Center -> Start -> Stop. Click on Center point ...') def utility_geometry(self, data=None): if len(self.points) == 1: # Show the radius @@ -2068,7 +2075,11 @@ class FCArc(FCShapeTool): p3 = array(self.points[1]) p2 = array(data) - center, radius, t = three_point_circle(p1, p2, p3) + try: + center, radius, t = three_point_circle(p1, p2, p3) + except TypeError: + return + direction = 'cw' if sign(t) > 0 else 'ccw' startangle = arctan2(p1[1] - center[1], p1[0] - center[0]) @@ -2090,7 +2101,7 @@ class FCArc(FCShapeTool): # Perpendicular vector b = dot(c, array([[0, -1], [1, 0]], dtype=float32)) - b /= norm(b) + b /= numpy_norm(b) # Distance t = distance(data, a) @@ -2103,7 +2114,7 @@ class FCArc(FCShapeTool): # Center = a + bt center = a + b * t - radius = norm(center - p1) + radius = numpy_norm(center - p1) startangle = arctan2(p1[1] - center[1], p1[0] - center[0]) stopangle = arctan2(p2[1] - center[1], p2[0] - center[0]) @@ -2153,7 +2164,7 @@ class FCArc(FCShapeTool): # Perpendicular vector b = dot(c, array([[0, -1], [1, 0]], dtype=float32)) - b /= norm(b) + b /= numpy_norm(b) # Distance t = distance(pc, a) @@ -2166,7 +2177,7 @@ class FCArc(FCShapeTool): # Center = a + bt center = a + b * t - radius = norm(center - p1) + radius = numpy_norm(center - p1) startangle = arctan2(p1[1] - center[1], p1[0] - center[0]) stopangle = arctan2(p2[1] - center[1], p2[0] - center[0]) diff --git a/flatcamEditors/FlatCAMGrbEditor.py b/flatcamEditors/FlatCAMGrbEditor.py index ed2c5612..6fe396f7 100644 --- a/flatcamEditors/FlatCAMGrbEditor.py +++ b/flatcamEditors/FlatCAMGrbEditor.py @@ -17,6 +17,8 @@ from flatcamEditors.FlatCAMGeoEditor import FCShapeTool, DrawTool, DrawToolShape from FlatCAMObj import FlatCAMGerber from FlatCAMTool import FlatCAMTool +from numpy.linalg import norm as numpy_norm + import gettext import FlatCAMTranslation as fcTranslate @@ -860,9 +862,7 @@ class FCTrack(FCRegion): """ def __init__(self, draw_app): FCRegion.__init__(self, draw_app) - self.name = 'track' - self.draw_app = draw_app try: @@ -1078,15 +1078,17 @@ class FCDisc(FCShapeTool): self.storage_obj = self.draw_app.storage_dict[self.draw_app.last_aperture_selected]['solid_geometry'] - self.start_msg = _("Click on CENTER ...") + self.start_msg = _("Click on Center point ...") + self.draw_app.app.inform.emit(_("Click on Center point ...")) + self.steps_per_circ = self.draw_app.app.defaults["gerber_circle_steps"] def click(self, point): self.points.append(point) if len(self.points) == 1: - self.draw_app.app.inform.emit(_("Click on perimeter point to complete ...")) - return "Click on perimeter to complete ..." + self.draw_app.app.inform.emit(_("Click on Perimeter point to complete ...")) + return "Click on Perimeter to complete ..." if len(self.points) == 2: self.make() @@ -1130,7 +1132,8 @@ class FCSemiDisc(FCShapeTool): DrawTool.__init__(self, draw_app) self.name = 'semidisc' - self.start_msg = _("Click on CENTER ...") + self.start_msg = _("Click on Center point ...") + self.draw_app.app.inform.emit(_("Click on Center point ...")) # Direction of rotation between point 1 and 2. # 'cw' or 'ccw'. Switch direction by hitting the @@ -1159,14 +1162,14 @@ class FCSemiDisc(FCShapeTool): elif self.mode == '132': self.draw_app.app.inform.emit(_("Click on Point3 ...")) else: - self.draw_app.app.inform.emit(_("Click on Stop point to complete ...")) + self.draw_app.app.inform.emit(_("Click on Stop point ...")) return "Click on 1st point ..." if len(self.points) == 2: if self.mode == 'c12': self.draw_app.app.inform.emit(_("Click on Stop point to complete ...")) elif self.mode == '132': - self.draw_app.app.inform.emit(_("Click on Point2 ...")) + self.draw_app.app.inform.emit(_("Click on Point2 to complete ...")) else: self.draw_app.app.inform.emit(_("Click on Center point to complete ...")) return "Click on 2nd point to complete ..." @@ -1183,15 +1186,20 @@ class FCSemiDisc(FCShapeTool): return _('Direction: %s') % self.direction.upper() if key == 'M' or key == QtCore.Qt.Key_M: + # delete the possible points made before this action; we want to start anew + self.points = [] + # and delete the utility geometry made up until this point + self.draw_app.delete_utility_geometry() + if self.mode == 'c12': self.mode = '12c' return _('Mode: Start -> Stop -> Center. Click on Start point ...') elif self.mode == '12c': self.mode = '132' - return _('Mode: Point1 -> Point3 -> Point2. Click on 1st point ...') + return _('Mode: Point1 -> Point3 -> Point2. Click on Point1 ...') else: self.mode = 'c12' - return _('Mode: Center -> Start -> Stop. Click on Center ...') + return _('Mode: Center -> Start -> Stop. Click on Center point ...') def utility_geometry(self, data=None): if len(self.points) == 1: # Show the radius @@ -1220,7 +1228,11 @@ class FCSemiDisc(FCShapeTool): p3 = array(self.points[1]) p2 = array(data) - center, radius, t = three_point_circle(p1, p2, p3) + try: + center, radius, t = three_point_circle(p1, p2, p3) + except TypeError: + return + direction = 'cw' if sign(t) > 0 else 'ccw' radius += (self.buf_val / 2) @@ -1234,7 +1246,6 @@ class FCSemiDisc(FCShapeTool): else: # '12c' p1 = array(self.points[0]) p2 = array(self.points[1]) - # Midpoint a = (p1 + p2) / 2.0 @@ -1243,7 +1254,7 @@ class FCSemiDisc(FCShapeTool): # Perpendicular vector b = dot(c, array([[0, -1], [1, 0]], dtype=float32)) - b /= norm(b) + b /= numpy_norm(b) # Distance t = distance(data, a) @@ -1256,7 +1267,7 @@ class FCSemiDisc(FCShapeTool): # Center = a + bt center = a + b * t - radius = norm(center - p1) + (self.buf_val / 2) + radius = numpy_norm(center - p1) + (self.buf_val / 2) startangle = arctan2(p1[1] - center[1], p1[0] - center[0]) stopangle = arctan2(p2[1] - center[1], p2[0] - center[0]) @@ -1308,7 +1319,7 @@ class FCSemiDisc(FCShapeTool): # Perpendicular vector b = dot(c, array([[0, -1], [1, 0]], dtype=float32)) - b /= norm(b) + b /= numpy_norm(b) # Distance t = distance(pc, a) @@ -1321,7 +1332,7 @@ class FCSemiDisc(FCShapeTool): # Center = a + bt center = a + b * t - radius = norm(center - p1) + (self.buf_val / 2) + radius = numpy_norm(center - p1) + (self.buf_val / 2) startangle = arctan2(p1[1] - center[1], p1[0] - center[0]) stopangle = arctan2(p2[1] - center[1], p2[0] - center[0]) @@ -3181,7 +3192,11 @@ class FlatCAMGrbEditor(QtCore.QObject): if key_modifier == modifier_to_use: self.select_tool(self.active_tool.name) else: - self.select_tool("select") + # return to Select tool but not for FCPad + if isinstance(self.active_tool, FCPad): + self.select_tool(self.active_tool.name) + else: + self.select_tool("select") return if isinstance(self.active_tool, FCApertureSelect): @@ -3234,6 +3249,7 @@ class FlatCAMGrbEditor(QtCore.QObject): # MS: always return to the Select Tool if modifier key is not pressed # else return to the current tool but not for FCTrack + if isinstance(self.active_tool, FCTrack): self.select_tool(self.active_tool.name) else: