Forráskód Böngészése

- added a new tool in the Geometry Editor named Explode which is the opposite of Union Tool: it will explode the polygons into lines

Marius Stanciu 6 éve
szülő
commit
da09202f5f

+ 1 - 0
README.md

@@ -17,6 +17,7 @@ CAD program, and create G-Code for Isolation routing.
 - fixed an issue with the tool table context menu in Paint Tool
 - made some changes in the GUI in Paint Tool, NCC Tool and SolderPaste Tool
 - changed some of the icons; added attributions for icons source in the About FlatCAM window
+- added a new tool in the Geometry Editor named Explode which is the opposite of Union Tool: it will explode the polygons into lines
 
 4.10.2019
 

+ 69 - 6
flatcamEditors/FlatCAMGeoEditor.py

@@ -1324,7 +1324,7 @@ class TransformEditorTool(FlatCAMTool):
                     # get mirroring coords from the point entry
                     if self.flip_ref_cb.isChecked():
                         px, py = eval('{}'.format(self.flip_ref_entry.text()))
-                    # get mirroing coords from the center of an all-enclosing bounding box
+                    # get mirroring coords from the center of an all-enclosing bounding box
                     else:
                         # first get a bounding box to fit all
                         for sha in shape_list:
@@ -2455,6 +2455,61 @@ class FCSelect(DrawTool):
         return ""
 
 
+class FCExplode(FCShapeTool):
+    def __init__(self, draw_app):
+        FCShapeTool.__init__(self, draw_app)
+        self.name = 'explode'
+
+        self.draw_app = draw_app
+
+        try:
+            QtGui.QGuiApplication.restoreOverrideCursor()
+        except Exception as e:
+            pass
+
+        self.storage = self.draw_app.storage
+        self.origin = (0, 0)
+        self.destination = None
+
+        self.draw_app.active_tool = self
+        if len(self.draw_app.get_selected()) == 0:
+            self.draw_app.app.inform.emit('[WARNING_NOTCL] %s...' %
+                                          _("No shape selected. Select a shape to explode"))
+        else:
+            self.make()
+
+    def make(self):
+        to_be_deleted_list = list()
+        lines = list()
+
+        for shape in self.draw_app.get_selected():
+            to_be_deleted_list.append(shape)
+            geo = shape.geo
+            ext_coords = list(geo.exterior.coords)
+
+            for c in range(len(ext_coords)):
+                if c < len(ext_coords) - 1:
+                    lines.append(LineString([ext_coords[c], ext_coords[c + 1]]))
+
+            for int_geo in geo.interiors:
+                int_coords = list(int_geo.coords)
+                for c in range(len(int_coords)):
+                    if c < len(int_coords):
+                        lines.append(LineString([int_coords[c], int_coords[c + 1]]))
+
+        for shape in to_be_deleted_list:
+            self.draw_app.storage.remove(shape)
+            if shape in self.draw_app.selected:
+                self.draw_app.selected.remove(shape)
+
+        geo_list = list()
+        for line in lines:
+            geo_list.append(DrawToolShape(line))
+        self.geometry = geo_list
+        self.draw_app.on_shape_complete()
+        self.draw_app.app.inform.emit('[success] %s...' % _("Done. Polygons exploded into lines."))
+
+
 class FCMove(FCShapeTool):
     def __init__(self, draw_app):
         FCShapeTool.__init__(self, draw_app)
@@ -3015,7 +3070,9 @@ class FlatCAMGeoEditor(QtCore.QObject):
             "transform": {"button": self.app.ui.geo_transform_btn,
                       "constructor": FCTransform},
             "copy": {"button": self.app.ui.geo_copy_btn,
-                     "constructor": FCCopy}
+                     "constructor": FCCopy},
+            "explode": {"button": self.app.ui.geo_explode_btn,
+                     "constructor": FCExplode}
         }
 
         # # ## Data
@@ -4041,7 +4098,8 @@ class FlatCAMGeoEditor(QtCore.QObject):
 
             if type(geometry) == LineString or type(geometry) == LinearRing:
                 plot_elements.append(self.shapes.add(shape=geometry, color=color, layer=0,
-                                                     tolerance=self.fcgeometry.drawing_tolerance))
+                                                     tolerance=self.fcgeometry.drawing_tolerance,
+                                                     linewidth=linewidth))
 
             if type(geometry) == Point:
                 pass
@@ -4098,9 +4156,14 @@ class FlatCAMGeoEditor(QtCore.QObject):
                             pl.append(Polygon(p.exterior.coords[::-1], p.interiors))
                         elif isinstance(p, LinearRing):
                             pl.append(Polygon(p.coords[::-1]))
-                        # elif isinstance(p, LineString):
-                        #     pl.append(LineString(p.coords[::-1]))
-                geom = MultiPolygon(pl)
+                        elif isinstance(p, LineString):
+                            pl.append(LineString(p.coords[::-1]))
+                try:
+                    geom = MultiPolygon(pl)
+                except TypeError:
+                    # this may happen if the geom elements are made out of LineStrings because you can't create a
+                    # MultiPolygon out of LineStrings
+                    pass
             except TypeError:
                 if isinstance(geom, Polygon) and geom is not None:
                     geom = Polygon(geom.exterior.coords[::-1], geom.interiors)

+ 4 - 0
flatcamGUI/FlatCAMGUI.py

@@ -775,6 +775,8 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
 
         self.geo_edit_toolbar.addSeparator()
         self.geo_union_btn = self.geo_edit_toolbar.addAction(QtGui.QIcon('share/union32.png'), _('Polygon Union'))
+        self.geo_explode_btn = self.geo_edit_toolbar.addAction(QtGui.QIcon('share/explode32.png'), _('Polygon Explode'))
+
         self.geo_intersection_btn = self.geo_edit_toolbar.addAction(QtGui.QIcon('share/intersection32.png'),
                                                                     _('Polygon Intersection'))
         self.geo_subtract_btn = self.geo_edit_toolbar.addAction(QtGui.QIcon('share/subtract32.png'),
@@ -2174,6 +2176,8 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
 
         self.geo_edit_toolbar.addSeparator()
         self.geo_union_btn = self.geo_edit_toolbar.addAction(QtGui.QIcon('share/union32.png'), _('Polygon Union'))
+        self.geo_explode_btn = self.geo_edit_toolbar.addAction(QtGui.QIcon('share/explode32.png'), _('Polygon Explode'))
+
         self.geo_intersection_btn = self.geo_edit_toolbar.addAction(QtGui.QIcon('share/intersection32.png'),
                                                                     _('Polygon Intersection'))
         self.geo_subtract_btn = self.geo_edit_toolbar.addAction(QtGui.QIcon('share/subtract32.png'),

+ 14 - 4
flatcamGUI/PlotCanvasLegacy.py

@@ -810,7 +810,8 @@ class ShapeCollectionLegacy:
             self.axes = self.app.plotcanvas.new_axes(axes_name)
 
     def add(self, shape=None, color=None, face_color=None, alpha=None, visible=True,
-            update=False, layer=1, tolerance=0.01, obj=None, gcode_parsed=None, tool_tolerance=None, tooldia=None):
+            update=False, layer=1, tolerance=0.01, obj=None, gcode_parsed=None, tool_tolerance=None, tooldia=None,
+            linewidth=None):
         """
         This function will add shapes to the shape collection
 
@@ -826,6 +827,7 @@ class ShapeCollectionLegacy:
         :param gcode_parsed: not used; just for compatibility with VIsPy canvas
         :param tool_tolerance: just for compatibility with VIsPy canvas
         :param tooldia:
+        :param linewidth: the width of the line
         :return:
         """
         self._color = color[:-2] if color is not None else None
@@ -853,6 +855,7 @@ class ShapeCollectionLegacy:
                 self.shape_dict.update({
                     'color': self._color,
                     'face_color': self._face_color,
+                    'linewidth': linewidth,
                     'alpha': self._alpha,
                     'shape': sh
                 })
@@ -865,6 +868,7 @@ class ShapeCollectionLegacy:
             self.shape_dict.update({
                 'color': self._color,
                 'face_color': self._face_color,
+                'linewidth': linewidth,
                 'alpha': self._alpha,
                 'shape': shape
             })
@@ -928,15 +932,21 @@ class ShapeCollectionLegacy:
                 elif obj_type == 'geometry':
                     if type(local_shapes[element]['shape']) == Polygon:
                         x, y = local_shapes[element]['shape'].exterior.coords.xy
-                        self.axes.plot(x, y, local_shapes[element]['color'], linestyle='-')
+                        self.axes.plot(x, y, local_shapes[element]['color'],
+                                       linestyle='-',
+                                       linewidth=local_shapes[element]['linewidth'])
                         for ints in local_shapes[element]['shape'].interiors:
                             x, y = ints.coords.xy
-                            self.axes.plot(x, y, local_shapes[element]['color'], linestyle='-')
+                            self.axes.plot(x, y, local_shapes[element]['color'],
+                                           linestyle='-',
+                                           linewidth=local_shapes[element]['linewidth'])
                     elif type(local_shapes[element]['shape']) == LineString or \
                             type(local_shapes[element]['shape']) == LinearRing:
 
                         x, y = local_shapes[element]['shape'].coords.xy
-                        self.axes.plot(x, y, local_shapes[element]['color'], linestyle='-')
+                        self.axes.plot(x, y, local_shapes[element]['color'],
+                                       linestyle='-',
+                                       linewidth=local_shapes[element]['linewidth'])
 
                 elif obj_type == 'gerber':
                     if self.obj.options["multicolored"]:

+ 3 - 1
flatcamGUI/VisPyVisuals.py

@@ -235,7 +235,7 @@ class ShapeCollectionVisual(CompoundVisual):
         self.freeze()
 
     def add(self, shape=None, color=None, face_color=None, alpha=None, visible=True,
-            update=False, layer=1, tolerance=0.01):
+            update=False, layer=1, tolerance=0.01, linewidth=None):
         """
         Adds shape to collection
         :return:
@@ -253,6 +253,8 @@ class ShapeCollectionVisual(CompoundVisual):
             Layer number. 0 - lowest.
         :param tolerance: float
             Geometry simplifying tolerance
+        :param linewidth: int
+            Not used, for compatibility
         :return: int
             Index of shape
         """

BIN
share/explode32.png