瀏覽代碼

- wip in adding Exclusion areas in Geometry object; each Geometry object has now a storage for shapes (exclusion shapes, should I make them more general?)

Marius Stanciu 5 年之前
父節點
當前提交
91493b2fbc
共有 6 個文件被更改,包括 152 次插入40 次删除
  1. 4 0
      CHANGELOG.md
  2. 6 1
      FlatCAMApp.py
  3. 53 17
      FlatCAMTool.py
  4. 2 2
      flatcamGUI/PlotCanvasLegacy.py
  5. 70 12
      flatcamObjects/FlatCAMGeometry.py
  6. 17 8
      flatcamTools/ToolNCC.py

+ 4 - 0
CHANGELOG.md

@@ -7,6 +7,10 @@ CHANGELOG for FlatCAM beta
 
 
 =================================================
 =================================================
 
 
+6.05.2020
+
+- wip in adding Exclusion areas in Geometry object; each Geometry object has now a storage for shapes (exclusion shapes, should I make them more general?)
+
 5.05.2020
 5.05.2020
 
 
 - fixed an issue that made the preprocessors comboxes in Preferences not to load and display the saved value fro the file
 - fixed an issue that made the preprocessors comboxes in Preferences not to load and display the saved value fro the file

+ 6 - 1
FlatCAMApp.py

@@ -5119,12 +5119,17 @@ class App(QtCore.QObject):
 
 
                     for obj_active in self.collection.get_selected():
                     for obj_active in self.collection.get_selected():
                         # if the deleted object is GerberObject then make sure to delete the possible mark shapes
                         # if the deleted object is GerberObject then make sure to delete the possible mark shapes
-                        if isinstance(obj_active, GerberObject):
+                        if obj_active.kind == 'gerber':
                             for el in obj_active.mark_shapes:
                             for el in obj_active.mark_shapes:
                                 obj_active.mark_shapes[el].clear(update=True)
                                 obj_active.mark_shapes[el].clear(update=True)
                                 obj_active.mark_shapes[el].enabled = False
                                 obj_active.mark_shapes[el].enabled = False
                                 # obj_active.mark_shapes[el] = None
                                 # obj_active.mark_shapes[el] = None
                                 del el
                                 del el
+                        # if the deleted object is GerberObject then make sure to delete the possible mark shapes
+                        if obj_active.kind == 'geometry':
+                            obj_active.exclusion_shapes.clear(update=True)
+                            obj_active.exclusion_shapes.enabled = False
+                            del obj_active.exclusion_shapes
                         elif isinstance(obj_active, CNCJobObject):
                         elif isinstance(obj_active, CNCJobObject):
                             try:
                             try:
                                 obj_active.text_col.enabled = False
                                 obj_active.text_col.enabled = False

+ 53 - 17
FlatCAMTool.py

@@ -110,6 +110,11 @@ class FlatCAMTool(QtWidgets.QWidget):
         :return:
         :return:
         """
         """
 
 
+        if 'shapes_storage' in kwargs:
+            s_storage = kwargs['shapes_storage']
+        else:
+            s_storage = self.app.tool_shapes
+
         if 'color' in kwargs:
         if 'color' in kwargs:
             color = kwargs['color']
             color = kwargs['color']
         else:
         else:
@@ -139,10 +144,9 @@ class FlatCAMTool(QtWidgets.QWidget):
 
 
         color_t = face_color[:-2] + str(hex(int(face_alpha * 255)))[2:]
         color_t = face_color[:-2] + str(hex(int(face_alpha * 255)))[2:]
 
 
-        self.app.tool_shapes.add(sel_rect, color=color, face_color=color_t, update=True,
-                                 layer=0, tolerance=None)
+        s_storage.add(sel_rect, color=color, face_color=color_t, update=True, layer=0, tolerance=None)
         if self.app.is_legacy is True:
         if self.app.is_legacy is True:
-            self.app.tool_shapes.redraw()
+            s_storage.redraw()
 
 
     def draw_selection_shape_polygon(self, points, **kwargs):
     def draw_selection_shape_polygon(self, points, **kwargs):
         """
         """
@@ -151,6 +155,12 @@ class FlatCAMTool(QtWidgets.QWidget):
         :param kwargs:
         :param kwargs:
         :return:
         :return:
         """
         """
+
+        if 'shapes_storage' in kwargs:
+            s_storage = kwargs['shapes_storage']
+        else:
+            s_storage = self.app.tool_shapes
+
         if 'color' in kwargs:
         if 'color' in kwargs:
             color = kwargs['color']
             color = kwargs['color']
         else:
         else:
@@ -165,6 +175,7 @@ class FlatCAMTool(QtWidgets.QWidget):
             face_alpha = kwargs['face_alpha']
             face_alpha = kwargs['face_alpha']
         else:
         else:
             face_alpha = 0.3
             face_alpha = 0.3
+
         if len(points) < 3:
         if len(points) < 3:
             sel_rect = LineString(points)
             sel_rect = LineString(points)
         else:
         else:
@@ -175,14 +186,24 @@ class FlatCAMTool(QtWidgets.QWidget):
 
 
         color_t = face_color[:-2] + str(hex(int(face_alpha * 255)))[2:]
         color_t = face_color[:-2] + str(hex(int(face_alpha * 255)))[2:]
 
 
-        self.app.tool_shapes.add(sel_rect, color=color, face_color=color_t, update=True,
-                                 layer=0, tolerance=None)
+        s_storage.add(sel_rect, color=color, face_color=color_t, update=True, layer=0, tolerance=None)
         if self.app.is_legacy is True:
         if self.app.is_legacy is True:
-            self.app.tool_shapes.redraw()
+            s_storage.redraw()
 
 
-    def delete_tool_selection_shape(self):
-        self.app.tool_shapes.clear()
-        self.app.tool_shapes.redraw()
+    def delete_tool_selection_shape(self, **kwargs):
+        """
+
+        :param kwargs:
+        :return:
+        """
+
+        if 'shapes_storage' in kwargs:
+            s_storage = kwargs['shapes_storage']
+        else:
+            s_storage = self.app.tool_shapes
+
+        s_storage.clear()
+        s_storage.redraw()
 
 
     def draw_moving_selection_shape_poly(self, points, data, **kwargs):
     def draw_moving_selection_shape_poly(self, points, data, **kwargs):
         """
         """
@@ -192,6 +213,12 @@ class FlatCAMTool(QtWidgets.QWidget):
         :param kwargs:
         :param kwargs:
         :return:
         :return:
         """
         """
+
+        if 'shapes_storage' in kwargs:
+            s_storage = kwargs['shapes_storage']
+        else:
+            s_storage = self.app.move_tool.sel_shapes
+
         if 'color' in kwargs:
         if 'color' in kwargs:
             color = kwargs['color']
             color = kwargs['color']
         else:
         else:
@@ -226,18 +253,27 @@ class FlatCAMTool(QtWidgets.QWidget):
         color_t_error = "#00000000"
         color_t_error = "#00000000"
 
 
         if geo.is_valid and not geo.is_empty:
         if geo.is_valid and not geo.is_empty:
-            self.app.move_tool.sel_shapes.add(geo, color=color, face_color=color_t, update=True,
-                                              layer=0, tolerance=None)
+            s_storage.add(geo, color=color, face_color=color_t, update=True, layer=0, tolerance=None)
         elif not geo.is_valid:
         elif not geo.is_valid:
-            self.app.move_tool.sel_shapes.add(geo, color="red", face_color=color_t_error, update=True,
-                                              layer=0, tolerance=None)
+            s_storage.add(geo, color="red", face_color=color_t_error, update=True, layer=0, tolerance=None)
 
 
         if self.app.is_legacy is True:
         if self.app.is_legacy is True:
-            self.app.move_tool.sel_shapes.redraw()
+            s_storage.redraw()
+
+    def delete_moving_selection_shape(self, **kwargs):
+        """
+
+        :param kwargs:
+        :return:
+        """
+
+        if 'shapes_storage' in kwargs:
+            s_storage = kwargs['shapes_storage']
+        else:
+            s_storage = self.app.move_tool.sel_shapes
 
 
-    def delete_moving_selection_shape(self):
-        self.app.move_tool.sel_shapes.clear()
-        self.app.move_tool.sel_shapes.redraw()
+        s_storage.clear()
+        s_storage.redraw()
 
 
     def confirmation_message(self, accepted, minval, maxval):
     def confirmation_message(self, accepted, minval, maxval):
         if accepted is False:
         if accepted is False:

+ 2 - 2
flatcamGUI/PlotCanvasLegacy.py

@@ -948,10 +948,10 @@ class ShapeCollectionLegacy:
         """
         """
 
 
         :param obj:             This is the object to which the shapes collection is attached and for
         :param obj:             This is the object to which the shapes collection is attached and for
-        which it will have to draw shapes
+                                which it will have to draw shapes
         :param app:             This is the FLatCAM.App usually, needed because we have to access attributes there
         :param app:             This is the FLatCAM.App usually, needed because we have to access attributes there
         :param name:            This is the name given to the Matplotlib axes; it needs to be unique due of
         :param name:            This is the name given to the Matplotlib axes; it needs to be unique due of
-        Matplotlib requurements
+                                Matplotlib requurements
         :param annotation_job:  Make this True if the job needed is just for annotation
         :param annotation_job:  Make this True if the job needed is just for annotation
         :param linewidth:       THe width of the line (outline where is the case)
         :param linewidth:       THe width of the line (outline where is the case)
         """
         """

+ 70 - 12
flatcamObjects/FlatCAMGeometry.py

@@ -16,6 +16,7 @@ import shapely.affinity as affinity
 from camlib import Geometry
 from camlib import Geometry
 
 
 from flatcamObjects.FlatCAMObj import *
 from flatcamObjects.FlatCAMObj import *
+from flatcamGUI.VisPyVisuals import ShapeCollection
 import FlatCAMTool
 import FlatCAMTool
 
 
 import ezdxf
 import ezdxf
@@ -163,6 +164,18 @@ class GeometryObject(FlatCAMObj, Geometry):
         self.points = []
         self.points = []
         self.poly_drawn = False
         self.poly_drawn = False
 
 
+        # Storage for shapes, storage that can be used by FlatCAm tools for utility geometry
+        # VisPy visuals
+        if self.app.is_legacy is False:
+            try:
+                self.exclusion_shapes = ShapeCollection(parent=self.app.plotcanvas.view.scene, layers=1)
+            except AttributeError:
+                self.exclusion_shapes = None
+        else:
+            from flatcamGUI.PlotCanvasLegacy import ShapeCollectionLegacy
+            self.exclusion_shapes = ShapeCollectionLegacy(
+                obj=self, app=self.app, name="exclusion" + self.options['name'])
+
         # Attributes to be included in serialization
         # Attributes to be included in serialization
         # Always append to it because it carries contents
         # Always append to it because it carries contents
         # from predecessors.
         # from predecessors.
@@ -363,7 +376,7 @@ class GeometryObject(FlatCAMObj, Geometry):
             "endxy": self.ui.endxy_entry,
             "endxy": self.ui.endxy_entry,
             "cnctooldia": self.ui.addtool_entry,
             "cnctooldia": self.ui.addtool_entry,
             "area_exclusion": self.ui.exclusion_cb,
             "area_exclusion": self.ui.exclusion_cb,
-            "area_shape":self.ui.area_shape_radio,
+            "area_shape": self.ui.area_shape_radio,
             "area_strategy": self.ui.strategy_radio,
             "area_strategy": self.ui.strategy_radio,
             "area_overz": self.ui.over_z_entry,
             "area_overz": self.ui.over_z_entry,
         })
         })
@@ -1149,8 +1162,7 @@ class GeometryObject(FlatCAMObj, Geometry):
                   "- 'V-tip Angle' -> angle at the tip of the tool\n"
                   "- 'V-tip Angle' -> angle at the tip of the tool\n"
                   "- 'V-tip Dia' -> diameter 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"
                   "- Tool Dia -> 'Dia' column found in the Tool Table\n"
-                  "NB: a value of zero means that Tool Dia = 'V-tip Dia'"
-                )
+                  "NB: a value of zero means that Tool Dia = 'V-tip Dia'")
             )
             )
             self.ui.cutz_entry.setToolTip(
             self.ui.cutz_entry.setToolTip(
                 _("Disabled because the tool is V-shape.\n"
                 _("Disabled because the tool is V-shape.\n"
@@ -1159,8 +1171,7 @@ class GeometryObject(FlatCAMObj, Geometry):
                   "- 'V-tip Angle' -> angle at the tip of the tool\n"
                   "- 'V-tip Angle' -> angle at the tip of the tool\n"
                   "- 'V-tip Dia' -> diameter 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"
                   "- Tool Dia -> 'Dia' column found in the Tool Table\n"
-                  "NB: a value of zero means that Tool Dia = 'V-tip Dia'"
-                  )
+                  "NB: a value of zero means that Tool Dia = 'V-tip Dia'")
             )
             )
 
 
             self.update_cutz()
             self.update_cutz()
@@ -1172,8 +1183,7 @@ class GeometryObject(FlatCAMObj, Geometry):
             self.ui.cutz_entry.setDisabled(False)
             self.ui.cutz_entry.setDisabled(False)
             self.ui.cutzlabel.setToolTip(
             self.ui.cutzlabel.setToolTip(
                 _("Cutting depth (negative)\n"
                 _("Cutting depth (negative)\n"
-                  "below the copper surface."
-                )
+                  "below the copper surface.")
             )
             )
             self.ui.cutz_entry.setToolTip('')
             self.ui.cutz_entry.setToolTip('')
 
 
@@ -2636,7 +2646,11 @@ class GeometryObject(FlatCAMObj, Geometry):
                     self.exclusion_areas_list.append(new_rectangle)
                     self.exclusion_areas_list.append(new_rectangle)
 
 
                     # add a temporary shape on canvas
                     # add a temporary shape on canvas
-                    FlatCAMTool.FlatCAMTool.draw_tool_selection_shape(self, old_coords=(x0, y0), coords=(x1, y1))
+                    FlatCAMTool.FlatCAMTool.draw_tool_selection_shape(
+                        self, old_coords=(x0, y0), coords=(x1, y1),
+                        color="#FF7400",
+                        face_color="#FF7400BF",
+                        shapes_storage=self.exclusion_shapes)
 
 
                     self.first_click = False
                     self.first_click = False
                     return
                     return
@@ -2672,7 +2686,11 @@ class GeometryObject(FlatCAMObj, Geometry):
                         # do not add invalid polygons even if they are drawn by utility geometry
                         # do not add invalid polygons even if they are drawn by utility geometry
                         if pol.is_valid:
                         if pol.is_valid:
                             self.exclusion_areas_list.append(pol)
                             self.exclusion_areas_list.append(pol)
-                            FlatCAMTool.FlatCAMTool.draw_selection_shape_polygon(self, points=self.points)
+                            FlatCAMTool.FlatCAMTool.draw_selection_shape_polygon(
+                                self, points=self.points,
+                                color="#FF7400",
+                                face_color="#FF7400BF",
+                                shapes_storage=self.exclusion_shapes)
                             self.app.inform.emit(
                             self.app.inform.emit(
                                 _("Zone added. Click to start adding next zone or right click to finish."))
                                 _("Zone added. Click to start adding next zone or right click to finish."))
 
 
@@ -2680,7 +2698,7 @@ class GeometryObject(FlatCAMObj, Geometry):
                     self.poly_drawn = False
                     self.poly_drawn = False
                     return
                     return
 
 
-            FlatCAMTool.FlatCAMTool.delete_tool_selection_shape(self)
+            # FlatCAMTool.FlatCAMTool.delete_tool_selection_shape(self, shapes_storage=self.exclusion_shapes)
 
 
             if self.app.is_legacy is False:
             if self.app.is_legacy is False:
                 self.app.plotcanvas.graph_event_disconnect('mouse_release', self.on_mouse_release)
                 self.app.plotcanvas.graph_event_disconnect('mouse_release', self.on_mouse_release)
@@ -2702,6 +2720,29 @@ class GeometryObject(FlatCAMObj, Geometry):
 
 
             if len(self.exclusion_areas_list) == 0:
             if len(self.exclusion_areas_list) == 0:
                 return
                 return
+            else:
+                self.exclusion_areas_list = MultiPolygon(self.exclusion_areas_list)
+
+            self.app.inform.emit(
+                "[success] %s" % _("Exclusion areas added. Checking overlap with the object geometry ..."))
+            if self.exclusion_areas_list.intersects(MultiPolygon(self.solid_geometry)):
+                self.exclusion_areas_list = []
+                self.app.inform.emit(
+                    "[ERROR_NOTCL] %s" % _("Failed. Exclusion areas intersects the object geometry ..."))
+                return
+            else:
+                self.app.inform.emit(
+                    "[success] %s" % _("Exclusion areas added."))
+                self.ui.generate_cnc_button.setStyleSheet("""
+                                        QPushButton
+                                        {
+                                            font-weight: bold;
+                                            color: orange;
+                                        }
+                                        """)
+                self.ui.generate_cnc_button.setToolTip(
+                    '%s %s' % (_("Generate the CNC Job object."), _("With Exclusion areas."))
+                )
 
 
     def area_disconnect(self):
     def area_disconnect(self):
         if self.app.is_legacy is False:
         if self.app.is_legacy is False:
@@ -2723,7 +2764,7 @@ class GeometryObject(FlatCAMObj, Geometry):
         self.exclusion_areas_list = []
         self.exclusion_areas_list = []
 
 
         FlatCAMTool.FlatCAMTool.delete_moving_selection_shape(self)
         FlatCAMTool.FlatCAMTool.delete_moving_selection_shape(self)
-        FlatCAMTool.FlatCAMTool.delete_tool_selection_shape(self)
+        # FlatCAMTool.FlatCAMTool.delete_tool_selection_shape(self, shapes_storage=self.exclusion_shapes)
 
 
         self.app.call_source = "app"
         self.app.call_source = "app"
         self.app.inform.emit("[WARNING_NOTCL] %s" % _("Cancelled. Area exclusion drawing was interrupted."))
         self.app.inform.emit("[WARNING_NOTCL] %s" % _("Cancelled. Area exclusion drawing was interrupted."))
@@ -2775,16 +2816,33 @@ class GeometryObject(FlatCAMObj, Geometry):
             if self.first_click:
             if self.first_click:
                 self.app.delete_selection_shape()
                 self.app.delete_selection_shape()
                 self.app.draw_moving_selection_shape(old_coords=(self.cursor_pos[0], self.cursor_pos[1]),
                 self.app.draw_moving_selection_shape(old_coords=(self.cursor_pos[0], self.cursor_pos[1]),
+                                                     color="#FF7400",
+                                                     face_color="#FF7400BF",
                                                      coords=(curr_pos[0], curr_pos[1]))
                                                      coords=(curr_pos[0], curr_pos[1]))
         else:
         else:
             FlatCAMTool.FlatCAMTool.delete_moving_selection_shape(self)
             FlatCAMTool.FlatCAMTool.delete_moving_selection_shape(self)
             FlatCAMTool.FlatCAMTool.draw_moving_selection_shape_poly(
             FlatCAMTool.FlatCAMTool.draw_moving_selection_shape_poly(
-                self, points=self.points, data=(curr_pos[0], curr_pos[1]))
+                self, points=self.points,
+                color="#FF7400",
+                face_color="#FF7400BF",
+                data=(curr_pos[0], curr_pos[1]))
 
 
     def on_clear_area_click(self):
     def on_clear_area_click(self):
         self.exclusion_areas_list = []
         self.exclusion_areas_list = []
         FlatCAMTool.FlatCAMTool.delete_moving_selection_shape(self)
         FlatCAMTool.FlatCAMTool.delete_moving_selection_shape(self)
         self.app.delete_selection_shape()
         self.app.delete_selection_shape()
+        FlatCAMTool.FlatCAMTool.delete_tool_selection_shape(self, shapes_storage=self.exclusion_shapes)
+
+        # restore the default StyleSheet
+        self.ui.generate_cnc_button.setStyleSheet("")
+        # update the StyleSheet
+        self.ui.generate_cnc_button.setStyleSheet("""
+                                QPushButton
+                                {
+                                    font-weight: bold;
+                                }
+                                """)
+        self.ui.generate_cnc_button.setToolTip('%s' % _("Generate the CNC Job object."))
 
 
     @staticmethod
     @staticmethod
     def merge(geo_list, geo_final, multigeo=None):
     def merge(geo_list, geo_final, multigeo=None):

+ 17 - 8
flatcamTools/ToolNCC.py

@@ -2066,6 +2066,7 @@ class NonCopperClear(FlatCAMTool, Gerber):
 
 
             # unfortunately for this function to work time efficient,
             # unfortunately for this function to work time efficient,
             # if the Gerber was loaded without buffering then it require the buffering now.
             # if the Gerber was loaded without buffering then it require the buffering now.
+            # TODO 'buffering status' should be a property of the object not the project property
             if self.app.defaults['gerber_buffering'] == 'no':
             if self.app.defaults['gerber_buffering'] == 'no':
                 self.solid_geometry = ncc_obj.solid_geometry.buffer(0)
                 self.solid_geometry = ncc_obj.solid_geometry.buffer(0)
             else:
             else:
@@ -2158,6 +2159,7 @@ class NonCopperClear(FlatCAMTool, Gerber):
                 self.app.inform.emit('[WARNING_NOTCL] %s ...' % _("Buffering"))
                 self.app.inform.emit('[WARNING_NOTCL] %s ...' % _("Buffering"))
                 sol_geo = sol_geo.buffer(distance=ncc_offset)
                 sol_geo = sol_geo.buffer(distance=ncc_offset)
                 self.app.inform.emit('[success] %s ...' % _("Buffering finished"))
                 self.app.inform.emit('[success] %s ...' % _("Buffering finished"))
+
             empty = self.get_ncc_empty_area(target=sol_geo, boundary=bounding_box)
             empty = self.get_ncc_empty_area(target=sol_geo, boundary=bounding_box)
             if empty == 'fail':
             if empty == 'fail':
                 return 'fail'
                 return 'fail'
@@ -2203,14 +2205,15 @@ class NonCopperClear(FlatCAMTool, Gerber):
         """
         """
         Clear the excess copper from the entire object.
         Clear the excess copper from the entire object.
 
 
-        :param ncc_obj: ncc cleared object
+        :param ncc_obj:         ncc cleared object
         :param sel_obj:
         :param sel_obj:
-        :param ncctooldia: a tuple or single element made out of diameters of the tools to be used to ncc clear
-        :param isotooldia: a tuple or single element made out of diameters of the tools to be used for isolation
-        :param outname: name of the resulting object
-        :param order:
-        :param tools_storage: whether to use the current tools_storage self.ncc_tools or a different one.
-        Usage of the different one is related to when this function is called from a TcL command.
+        :param ncctooldia:      a tuple or single element made out of diameters of the tools to be used to ncc clear
+        :param isotooldia:      a tuple or single element made out of diameters of the tools to be used for isolation
+        :param outname:         name of the resulting object
+        :param order:           Tools order
+        :param tools_storage:   whether to use the current tools_storage self.ncc_tools or a different one.
+                                Usage of the different one is related to when this function is called
+                                from a TcL command.
 
 
         :param run_threaded: If True the method will be run in a threaded way suitable for GUI usage; if False it will
         :param run_threaded: If True the method will be run in a threaded way suitable for GUI usage; if False it will
         run non-threaded for TclShell usage
         run non-threaded for TclShell usage
@@ -3870,6 +3873,11 @@ class NonCopperClear(FlatCAMTool, Gerber):
         Returns the complement of target geometry within
         Returns the complement of target geometry within
         the given boundary polygon. If not specified, it defaults to
         the given boundary polygon. If not specified, it defaults to
         the rectangular bounding box of target geometry.
         the rectangular bounding box of target geometry.
+
+        :param target:      The geometry that is to be 'inverted'
+        :param boundary:    A polygon that surrounds the entire solid geometry and from which we subtract in order to
+                            create a "negative" geometry (geometry to be emptied of copper)
+        :return:
         """
         """
         if isinstance(target, Polygon):
         if isinstance(target, Polygon):
             geo_len = 1
             geo_len = 1
@@ -3882,6 +3890,7 @@ class NonCopperClear(FlatCAMTool, Gerber):
             boundary = target.envelope
             boundary = target.envelope
         else:
         else:
             boundary = boundary
             boundary = boundary
+
         try:
         try:
             ret_val = boundary.difference(target)
             ret_val = boundary.difference(target)
         except Exception:
         except Exception:
@@ -3889,10 +3898,10 @@ class NonCopperClear(FlatCAMTool, Gerber):
                 for el in target:
                 for el in target:
                     # provide the app with a way to process the GUI events when in a blocking loop
                     # provide the app with a way to process the GUI events when in a blocking loop
                     QtWidgets.QApplication.processEvents()
                     QtWidgets.QApplication.processEvents()
-
                     if self.app.abort_flag:
                     if self.app.abort_flag:
                         # graceful abort requested by the user
                         # graceful abort requested by the user
                         raise grace
                         raise grace
+
                     boundary = boundary.difference(el)
                     boundary = boundary.difference(el)
                     pol_nr += 1
                     pol_nr += 1
                     disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100]))
                     disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100]))