Przeglądaj źródła

- finished the Dots and Squares options in the Copper Thieving Tool
- working on the Lines option in Copper Thieving Tool

Marius Stanciu 6 lat temu
rodzic
commit
057ab93ef8
3 zmienionych plików z 124 dodań i 23 usunięć
  1. 5 0
      README.md
  2. 117 11
      flatcamTools/ToolCopperThieving.py
  3. 2 12
      flatcamTools/ToolDblSided.py

+ 5 - 0
README.md

@@ -9,6 +9,11 @@ CAD program, and create G-Code for Isolation routing.
 
 =================================================
 
+18.11.2019
+
+- finished the Dots and Squares options in the Copper Thieving Tool
+- working on the Lines option in Copper Thieving Tool
+
 17.11.2019
 
 - optimized the storage of the Gerber mark shapes by making them one layer only

+ 117 - 11
flatcamTools/ToolCopperThieving.py

@@ -16,6 +16,7 @@ import shapely.geometry.base as base
 from shapely.ops import cascaded_union, unary_union
 from shapely.geometry import Polygon, MultiPolygon, Point
 from shapely.geometry import box as box
+import shapely.affinity as affinity
 
 import logging
 from copy import deepcopy
@@ -760,9 +761,10 @@ class ToolCopperThieving(FlatCAMTool):
                         env_obj = cascaded_union(geo_n)
                         env_obj = env_obj.convex_hull
                 else:
-                    if isinstance(geo_n, Polygon) or \
-                            (isinstance(geo_n, list) and len(geo_n) == 1) or \
-                            (isinstance(geo_n, MultiPolygon) and len(geo_n) == 1):
+                    if isinstance(geo_n, Polygon):
+                        env_obj = geo_n.buffer(0, join_style=base.JOIN_STYLE.mitre).exterior
+                    elif isinstance(geo_n, list):
+                        geo_n = unary_union(geo_n)
                         env_obj = geo_n.buffer(0, join_style=base.JOIN_STYLE.mitre).exterior
                     elif isinstance(geo_n, MultiPolygon):
                         x0, y0, x1, y1 = geo_n.bounds
@@ -797,7 +799,7 @@ class ToolCopperThieving(FlatCAMTool):
 
             bounding_box = cascaded_union(geo_buff_list)
 
-        elif ref_selected == 'box':
+        else:   # ref_selected == 'box'
             geo_n = working_obj.solid_geometry
 
             if isinstance(working_obj, FlatCAMGeometry):
@@ -831,15 +833,119 @@ class ToolCopperThieving(FlatCAMTool):
         # ########## Generate filling geometry. ###################################################
         # #########################################################################################
 
-        if fill_type == 'solid':
-            new_solid_geometry = bounding_box.difference(clearance_geometry)
-        elif fill_type == 'dots':
-            dot_geo = Point((0, 0)).buffer(dot_dia / 2.0)
+        new_solid_geometry = bounding_box.difference(clearance_geometry)
+
+        # determine the bounding box polygon for the entire Gerber object to which we add copper thieving
+        if isinstance(geo_n, list):
+            env_obj = unary_union(geo_n).buffer(distance=margin, join_style=base.JOIN_STYLE.mitre)
+        else:
+            env_obj = geo_n.buffer(distance=margin, join_style=base.JOIN_STYLE.mitre)
+
+        x0, y0, x1, y1 = env_obj.bounds
+        bounding_box = box(x0, y0, x1, y1)
+
+        if fill_type == 'dot' or fill_type == 'square':
+            # build the MultiPolygon of dots/squares that will fill the entire bounding box
+            thieving_list = list()
+
+            if fill_type == 'dot':
+                radius = dot_dia / 2.0
+                new_x = x0 + radius
+                new_y = y0 + radius
+                while new_x <= x1 - radius:
+                    while new_y <= y1 - radius:
+                        dot_geo = Point((new_x, new_y)).buffer(radius, resolution=64)
+                        thieving_list.append(dot_geo)
+                        new_y += dot_dia + dot_spacing
+                    new_x += dot_dia + dot_spacing
+                    new_y = y0 + radius
+            else:
+                h_size = square_size / 2.0
+                new_x = x0 + h_size
+                new_y = y0 + h_size
+                while new_x <= x1 - h_size:
+                    while new_y <= y1 - h_size:
+                        a, b, c, d = (Point((new_x, new_y)).buffer(h_size)).bounds
+                        square_geo = box(a, b, c, d)
+                        thieving_list.append(square_geo)
+                        new_y += square_size + square_spacing
+                    new_x += square_size + square_spacing
+                    new_y = y0 + h_size
+
+            thieving_box_geo = MultiPolygon(thieving_list)
+            dx = bounding_box.centroid.x - thieving_box_geo.centroid.x
+            dy = bounding_box.centroid.y - thieving_box_geo.centroid.y
+
+            thieving_box_geo = affinity.translate(thieving_box_geo, xoff=dx, yoff=dy)
+
             try:
-                for bb in bounding_box:
-                    pass
+                _it = iter(new_solid_geometry)
+            except TypeError:
+                new_solid_geometry = [new_solid_geometry]
+
+            try:
+                _it = iter(thieving_box_geo)
+            except TypeError:
+                thieving_box_geo = [thieving_box_geo]
+
+            thieving_geo = list()
+            for dot_geo in thieving_box_geo:
+                for geo_t in new_solid_geometry:
+                    if dot_geo.within(geo_t):
+                        thieving_geo.append(dot_geo)
+
+            new_solid_geometry = thieving_geo
+
+        if fill_type == 'line':
+            half_thick_line = line_size / 2.0
+
+            outline_geometry = []
+            try:
+                for pol in self.grb_object.solid_geometry:
+                    if self.app.abort_flag:
+                        # graceful abort requested by the user
+                        raise FlatCAMApp.GracefulException
+
+                    outline_geometry.append(
+                        pol.buffer(c_val+half_thick_line, int(int(self.geo_steps_per_circle) / 4)).exterior
+                    )
+
+                    pol_nr += 1
+                    disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100]))
+
+                    if old_disp_number < disp_number <= 100:
+                        self.app.proc_container.update_view_text(' %s ... %d%%' %
+                                                                 (_("Buffering"), int(disp_number)))
+                        old_disp_number = disp_number
+            except TypeError:
+                # taking care of the case when the self.solid_geometry is just a single Polygon, not a list or a
+                # MultiPolygon (not an iterable)
+                outline_geometry.append(
+                    self.grb_object.solid_geometry.buffer(
+                        c_val+half_thick_line,
+                        int(int(self.geo_steps_per_circle) / 4).exterior
+                    )
+                )
+
+            self.app.proc_container.update_view_text(' %s' % _("Buffering"))
+            t = list()
+            for l in outline_geometry:
+                t.append(l.buffer(half_thick_line, resolution=int(int(self.geo_steps_per_circle) / 4)))
+            outline_geometry = unary_union(t)
+
+            try:
+                _it = iter(new_solid_geometry)
             except TypeError:
-                pass
+                new_solid_geometry = [new_solid_geometry]
+
+            # thieving_outlines = list()
+            # for geo_t in new_solid_geometry:
+            #     for interior in geo_t.interiors:
+            #         thieving_geo = interior.buffer(distance=half_thick_line)
+            #
+            #         if thieving_geo.is_valid:
+            #             thieving_outlines.append(thieving_geo)
+            new_solid_geometry = outline_geometry
 
         geo_list = self.grb_object.solid_geometry
         if isinstance(self.grb_object.solid_geometry, MultiPolygon):

+ 2 - 12
flatcamTools/ToolDblSided.py

@@ -368,22 +368,12 @@ class DblSidedTool(FlatCAMTool):
 
         xscale, yscale = {"X": (1.0, -1.0), "Y": (-1.0, 1.0)}[axis]
 
-        try:
-            dia = float(self.drill_dia.get_value())
-        except ValueError:
-            # try to convert comma to decimal point. if it's still not working error message and return
-            try:
-                dia = float(self.drill_dia.get_value().replace(',', '.'))
-                self.drill_dia.set_value(dia)
-            except ValueError:
-                self.app.inform.emit('[WARNING_NOTCL] %s' % _("Tool diameter value is missing or wrong format. "
-                                                              "Add it and retry."))
-                return
-
+        dia = float(self.drill_dia.get_value())
         if dia is '':
             self.app.inform.emit('[WARNING_NOTCL] %s' %
                                  _("No value or wrong format in Drill Dia entry. Add it and retry."))
             return
+
         tools = {"1": {"C": dia}}
 
         # holes = self.alignment_holes.get_value()