فهرست منبع

- made some optimizations in FlatCAMGerber.isolate() method

Marius Stanciu 6 سال پیش
والد
کامیت
b31d016b13
2فایلهای تغییر یافته به همراه107 افزوده شده و 97 حذف شده
  1. 106 97
      FlatCAMObj.py
  2. 1 0
      README.md

+ 106 - 97
FlatCAMObj.py

@@ -1148,97 +1148,6 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
 
         base_name = self.options["name"]
 
-        def generate_envelope(offset, invert, geometry=None, env_iso_type=2, follow=None, nr_passes=0):
-            # isolation_geometry produces an envelope that is going on the left of the geometry
-            # (the copper features). To leave the least amount of burrs on the features
-            # the tool needs to travel on the right side of the features (this is called conventional milling)
-            # the first pass is the one cutting all of the features, so it needs to be reversed
-            # the other passes overlap preceding ones and cut the left over copper. It is better for them
-            # to cut on the right side of the left over copper i.e on the left side of the features.
-
-            if follow:
-                geom = self.isolation_geometry(offset, geometry=geometry, follow=follow)
-            else:
-                try:
-                    geom = self.isolation_geometry(offset, geometry=geometry, iso_type=env_iso_type, passes=nr_passes)
-                except Exception as e:
-                    log.debug('FlatCAMGerber.isolate().generate_envelope() --> %s' % str(e))
-                    return 'fail'
-
-            if invert:
-                try:
-                    pl = []
-                    for p in geom:
-                        if p is not None:
-                            if isinstance(p, Polygon):
-                                pl.append(Polygon(p.exterior.coords[::-1], p.interiors))
-                            elif isinstance(p, LinearRing):
-                                pl.append(Polygon(p.coords[::-1]))
-                    geom = MultiPolygon(pl)
-                except TypeError:
-                    if isinstance(geom, Polygon) and geom is not None:
-                        geom = Polygon(geom.exterior.coords[::-1], geom.interiors)
-                    elif isinstance(geom, LinearRing) and geom is not None:
-                        geom = Polygon(geom.coords[::-1])
-                    else:
-                        log.debug("FlatCAMGerber.isolate().generate_envelope() Error --> Unexpected Geometry %s" %
-                                  type(geom))
-                except Exception as e:
-                    log.debug("FlatCAMGerber.isolate().generate_envelope() Error --> %s" % str(e))
-                    return 'fail'
-            return geom
-
-        # if float(self.options["isotooldia"]) < 0:
-        #     self.options["isotooldia"] = -self.options["isotooldia"]
-
-        def area_subtraction(geo):
-            new_geometry = []
-
-            name = self.ui.obj_combo.currentText()
-            subtractor_obj = self.app.collection.get_by_name(name)
-            sub_union = cascaded_union(subtractor_obj.solid_geometry)
-
-            try:
-                for geo_elem in geo:
-                    if isinstance(geo_elem, Polygon):
-                        for ring in self.poly2rings(geo_elem):
-                            new_geo = ring.difference(sub_union)
-                            if new_geo and not new_geo.is_empty:
-                                new_geometry.append(new_geo)
-                    elif isinstance(geo_elem, MultiPolygon):
-                        for poly in geo_elem:
-                            for ring in self.poly2rings(poly):
-                                new_geo = ring.difference(sub_union)
-                                if new_geo and not new_geo.is_empty:
-                                    new_geometry.append(new_geo)
-                    elif isinstance(geo_elem, LineString):
-                        new_geo = geo_elem.difference(sub_union)
-                        if new_geo:
-                            if not new_geo.is_empty:
-                                new_geometry.append(new_geo)
-                    elif isinstance(geo_elem, MultiLineString):
-                        for line_elem in geo_elem:
-                            new_geo = line_elem.difference(sub_union)
-                            if new_geo and not new_geo.is_empty:
-                                new_geometry.append(new_geo)
-            except TypeError:
-                if isinstance(geo, Polygon):
-                    for ring in self.poly2rings(geo):
-                        new_geo = ring.difference(sub_union)
-                        if new_geo:
-                            if not new_geo.is_empty:
-                                new_geometry.append(new_geo)
-                elif isinstance(geo, LineString):
-                    new_geo = geo.difference(sub_union)
-                    if new_geo and not new_geo.is_empty:
-                        new_geometry.append(new_geo)
-                elif isinstance(geo, MultiLineString):
-                    for line_elem in geo:
-                        new_geo = line_elem.difference(sub_union)
-                        if new_geo and not new_geo.is_empty:
-                            new_geometry.append(new_geo)
-            return new_geometry
-
         if combine:
             if outname is None:
                 if self.iso_type == 0:
@@ -1260,8 +1169,8 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
 
                     # if milling type is climb then the move is counter-clockwise around features
                     mill_t = 1 if milling_type == 'cl' else 0
-                    geom = generate_envelope(iso_offset, mill_t, geometry=work_geo, env_iso_type=iso_t, follow=follow,
-                                             nr_passes=i)
+                    geom = self.generate_envelope(iso_offset, mill_t, geometry=work_geo, env_iso_type=iso_t,
+                                                  follow=follow, nr_passes=i)
 
                     if geom == 'fail':
                         app_obj.inform.emit('[ERROR_NOTCL] %s' % _("Isolation geometry could not be generated."))
@@ -1349,7 +1258,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
                 # ############################################################
                 if self.ui.except_cb.get_value():
                     self.app.proc_container.update_view_text(' %s' % _("Subtracting Geo"))
-                    geo_obj.solid_geometry = area_subtraction(geo_obj.solid_geometry)
+                    geo_obj.solid_geometry = self.area_subtraction(geo_obj.solid_geometry)
 
             # TODO: Do something if this is None. Offer changing name?
             self.app.new_object("geometry", iso_name, iso_init, plot=plot)
@@ -1386,8 +1295,9 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
                     # if milling type is climb then the move is counter-clockwise around features
                     mill_t = 1 if milling_type == 'cl' else 0
                     mill_t = 1 if milling_type == 'cl' else 0
-                    geom = generate_envelope(offset, mill_t, geometry=work_geo, env_iso_type=iso_t, follow=follow,
-                                             nr_passes=i)
+                    geom = self.generate_envelope(offset, mill_t, geometry=work_geo, env_iso_type=iso_t,
+                                                  follow=follow,
+                                                  nr_passes=i)
 
                     if geom == 'fail':
                         app_obj.inform.emit('[ERROR_NOTCL] %s' %
@@ -1422,11 +1332,110 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
                     # ############################################################
                     if self.ui.except_cb.get_value():
                         self.app.proc_container.update_view_text(' %s' % _("Subtracting Geo"))
-                        geo_obj.solid_geometry = area_subtraction(geo_obj.solid_geometry)
+                        geo_obj.solid_geometry = self.area_subtraction(geo_obj.solid_geometry)
 
                 # TODO: Do something if this is None. Offer changing name?
                 self.app.new_object("geometry", iso_name, iso_init, plot=plot)
 
+    def generate_envelope(self, offset, invert, geometry=None, env_iso_type=2, follow=None, nr_passes=0):
+        # isolation_geometry produces an envelope that is going on the left of the geometry
+        # (the copper features). To leave the least amount of burrs on the features
+        # the tool needs to travel on the right side of the features (this is called conventional milling)
+        # the first pass is the one cutting all of the features, so it needs to be reversed
+        # the other passes overlap preceding ones and cut the left over copper. It is better for them
+        # to cut on the right side of the left over copper i.e on the left side of the features.
+
+        if follow:
+            geom = self.isolation_geometry(offset, geometry=geometry, follow=follow)
+        else:
+            try:
+                geom = self.isolation_geometry(offset, geometry=geometry, iso_type=env_iso_type, passes=nr_passes)
+            except Exception as e:
+                log.debug('FlatCAMGerber.isolate().generate_envelope() --> %s' % str(e))
+                return 'fail'
+
+        if invert:
+            try:
+                pl = []
+                for p in geom:
+                    if p is not None:
+                        if isinstance(p, Polygon):
+                            pl.append(Polygon(p.exterior.coords[::-1], p.interiors))
+                        elif isinstance(p, LinearRing):
+                            pl.append(Polygon(p.coords[::-1]))
+                geom = MultiPolygon(pl)
+            except TypeError:
+                if isinstance(geom, Polygon) and geom is not None:
+                    geom = Polygon(geom.exterior.coords[::-1], geom.interiors)
+                elif isinstance(geom, LinearRing) and geom is not None:
+                    geom = Polygon(geom.coords[::-1])
+                else:
+                    log.debug("FlatCAMGerber.isolate().generate_envelope() Error --> Unexpected Geometry %s" %
+                              type(geom))
+            except Exception as e:
+                log.debug("FlatCAMGerber.isolate().generate_envelope() Error --> %s" % str(e))
+                return 'fail'
+        return geom
+
+    def area_subtraction(self, geo, subtractor_geo=None):
+        """
+        Subtracts the subtractor_geo (if present else self.solid_geometry) from the geo
+
+        :param geo: target geometry from which to subtract
+        :param subtractor_geo: geometry that acts as subtractor
+        :return:
+        """
+        new_geometry = []
+        target_geo = geo
+
+        if subtractor_geo:
+            sub_union = cascaded_union(subtractor_geo)
+        else:
+            name = self.ui.obj_combo.currentText()
+            subtractor_obj = self.app.collection.get_by_name(name)
+            sub_union = cascaded_union(subtractor_obj.solid_geometry)
+
+        try:
+            for geo_elem in target_geo:
+                if isinstance(geo_elem, Polygon):
+                    for ring in self.poly2rings(geo_elem):
+                        new_geo = ring.difference(sub_union)
+                        if new_geo and not new_geo.is_empty:
+                            new_geometry.append(new_geo)
+                elif isinstance(geo_elem, MultiPolygon):
+                    for poly in geo_elem:
+                        for ring in self.poly2rings(poly):
+                            new_geo = ring.difference(sub_union)
+                            if new_geo and not new_geo.is_empty:
+                                new_geometry.append(new_geo)
+                elif isinstance(geo_elem, LineString):
+                    new_geo = geo_elem.difference(sub_union)
+                    if new_geo:
+                        if not new_geo.is_empty:
+                            new_geometry.append(new_geo)
+                elif isinstance(geo_elem, MultiLineString):
+                    for line_elem in geo_elem:
+                        new_geo = line_elem.difference(sub_union)
+                        if new_geo and not new_geo.is_empty:
+                            new_geometry.append(new_geo)
+        except TypeError:
+            if isinstance(target_geo, Polygon):
+                for ring in self.poly2rings(target_geo):
+                    new_geo = ring.difference(sub_union)
+                    if new_geo:
+                        if not new_geo.is_empty:
+                            new_geometry.append(new_geo)
+            elif isinstance(target_geo, LineString):
+                new_geo = target_geo.difference(sub_union)
+                if new_geo and not new_geo.is_empty:
+                    new_geometry.append(new_geo)
+            elif isinstance(target_geo, MultiLineString):
+                for line_elem in target_geo:
+                    new_geo = line_elem.difference(sub_union)
+                    if new_geo and not new_geo.is_empty:
+                        new_geometry.append(new_geo)
+        return new_geometry
+
     def on_plot_cb_click(self, *args):
         if self.muted_ui:
             return

+ 1 - 0
README.md

@@ -13,6 +13,7 @@ CAD program, and create G-Code for Isolation routing.
 
 - In Gerber isolation changed the UI
 - in Gerber isolation added the option to selectively isolate only certain polygons
+- made some optimizations in FlatCAMGerber.isolate() method
 
 23.11.2019