From 948c4954479cee22ea49185d1b3a1c3d1151b4c8 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Fri, 23 Aug 2019 02:15:45 +0300 Subject: [PATCH] - in Tool Cutout for the manual gaps, now the moving geometry that cuts gaps will orient itself to fit the angle of the cutout geometry --- README.md | 1 + flatcamGUI/GUIElements.py | 7 ++++ flatcamTools/ToolCutOut.py | 83 ++++++++++++++++++++++++++++++++++---- 3 files changed, 84 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 0a143e8f..3db5c348 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ CAD program, and create G-Code for Isolation routing. - fixed the Buffer Tool in Geometry Editor; made the Buffer entry field a QDoubleSpinner and set the lower limit to zero. - fixed Tool Cutout so when the target Gerber is a single Polygon then the created manual geometry will follow the shape if shape is freeform - fixed TclCommandFollow command; an older function name was used who yielded wrong results +- in Tool Cutout for the manual gaps, now the moving geometry that cuts gaps will orient itself to fit the angle of the cutout geometry 21.08.2019 diff --git a/flatcamGUI/GUIElements.py b/flatcamGUI/GUIElements.py index 84d938c6..ae2d58b0 100644 --- a/flatcamGUI/GUIElements.py +++ b/flatcamGUI/GUIElements.py @@ -1876,9 +1876,16 @@ class MyCompleter(QCompleter): QCompleter.__init__(self) self.setCompletionMode(QCompleter.PopupCompletion) self.highlighted.connect(self.setHighlighted) + # self.popup().installEventFilter(self) + + # def eventFilter(self, obj, event): + # if event.type() == QtCore.QEvent.Wheel and obj is self.popup(): + # pass + # return False def setHighlighted(self, text): self.lastSelected = text def getSelected(self): return self.lastSelected + diff --git a/flatcamTools/ToolCutOut.py b/flatcamTools/ToolCutOut.py index 82c544db..ac9711a7 100644 --- a/flatcamTools/ToolCutOut.py +++ b/flatcamTools/ToolCutOut.py @@ -292,6 +292,9 @@ class CutOut(FlatCAMTool): self.flat_geometry = [] + # this is the Geometry object generated in this class to be used for adding manual gaps + self.man_cutout_obj = None + # Signals self.ff_cutout_object_btn.clicked.connect(self.on_freeform_cutout) self.rect_cutout_object_btn.clicked.connect(self.on_rectangular_cutout) @@ -743,6 +746,15 @@ class CutOut(FlatCAMTool): "Add it and retry.")) return + name = self.man_object_combo.currentText() + # Get Geometry source object to be used as target for Manual adding Gaps + try: + self.man_cutout_obj = self.app.collection.get_by_name(str(name)) + except Exception as e: + log.debug("CutOut.on_manual_cutout() --> %s" % str(e)) + self.app.inform.emit(_("[ERROR_NOTCL] Could not retrieve Geometry object: %s") % name) + return "Could not retrieve object: %s" % name + self.app.plotcanvas.vis_disconnect('key_press', self.app.ui.keyPressEvent) self.app.plotcanvas.vis_disconnect('mouse_press', self.app.on_mouse_click_over_plot) self.app.plotcanvas.vis_disconnect('mouse_release', self.app.on_mouse_click_release_over_plot) @@ -776,23 +788,24 @@ class CutOut(FlatCAMTool): # Get source object. try: - cutout_obj = self.app.collection.get_by_name(str(name)) + self.man_cutout_obj = self.app.collection.get_by_name(str(name)) except Exception as e: log.debug("CutOut.on_manual_cutout() --> %s" % str(e)) self.app.inform.emit(_("[ERROR_NOTCL] Could not retrieve Geometry object: %s") % name) return "Could not retrieve object: %s" % name - if cutout_obj is None: - self.app.inform.emit(_("[ERROR_NOTCL] Geometry object for manual cutout not found: %s") % cutout_obj) + if self.man_cutout_obj is None: + self.app.inform.emit( + _("[ERROR_NOTCL] Geometry object for manual cutout not found: %s") % self.man_cutout_obj) return # use the snapped position as reference snapped_pos = self.app.geo_editor.snap(click_pos[0], click_pos[1]) cut_poly = self.cutting_geo(pos=(snapped_pos[0], snapped_pos[1])) - cutout_obj.subtract_polygon(cut_poly) + self.man_cutout_obj.subtract_polygon(cut_poly) - cutout_obj.plot() + self.man_cutout_obj.plot() self.app.inform.emit(_("[success] Added manual Bridge Gap.")) self.app.should_we_save = True @@ -919,11 +932,67 @@ class CutOut(FlatCAMTool): snap_x, snap_y = self.app.geo_editor.snap(x, y) - geo = self.cutting_geo(pos=(snap_x, snap_y)) + # ################################################# + # ### This section makes the cutting geo to ####### + # ### rotate if it intersects the target geo ###### + # ################################################# + cut_geo = self.cutting_geo(pos=(snap_x, snap_y)) + man_geo = self.man_cutout_obj.solid_geometry + + def get_angle(geo): + line = cut_geo.intersection(geo) + + try: + pt1_x = line.coords[0][0] + pt1_y = line.coords[0][1] + pt2_x = line.coords[1][0] + pt2_y = line.coords[1][1] + dx = pt1_x - pt2_x + dy = pt1_y - pt2_y + + if dx == 0 or dy == 0: + angle = 0 + else: + radian = math.atan(dx / dy) + angle = radian * 180 / math.pi + except Exception as e: + angle = 0 + return angle + + try: + rot_angle = 0 + for geo_el in man_geo: + if isinstance(geo_el, Polygon): + work_geo = geo_el.exterior + if cut_geo.intersects(work_geo): + rot_angle = get_angle(geo=work_geo) + else: + rot_angle = 0 + else: + rot_angle = 0 + if cut_geo.intersects(geo_el): + rot_angle = get_angle(geo=geo_el) + if rot_angle != 0: + break + except TypeError: + if isinstance(man_geo, Polygon): + work_geo = man_geo.exterior + if cut_geo.intersects(work_geo): + rot_angle = get_angle(geo=work_geo) + else: + rot_angle = 0 + else: + rot_angle = 0 + if cut_geo.intersects(man_geo): + rot_angle = get_angle(geo=man_geo) + + # rotate only if there is an angle to rotate to + if rot_angle != 0: + cut_geo = affinity.rotate(cut_geo, -rot_angle) # Remove any previous utility shape self.app.geo_editor.tool_shape.clear(update=True) - self.draw_utility_geometry(geo=geo) + self.draw_utility_geometry(geo=cut_geo) def draw_utility_geometry(self, geo): self.app.geo_editor.tool_shape.add(