Przeglądaj źródła

- Gerber Editor: added support for Gerber polarity change commands (LPD, LPC)

Marius Stanciu 6 lat temu
rodzic
commit
80c5cf86b7
3 zmienionych plików z 189 dodań i 70 usunięć
  1. 1 0
      README.md
  2. 174 70
      camlib.py
  3. 14 0
      flatcamEditors/FlatCAMGrbEditor.py

+ 1 - 0
README.md

@@ -21,6 +21,7 @@ CAD program, and create G-Code for Isolation routing.
 - updated the shortcut list with the Gerber Editor shortcut keys
 - updated the shortcut list with the Gerber Editor shortcut keys
 - Gerber Editor: fixed error when adding an aperture with code value lower than the ones that already exists
 - Gerber Editor: fixed error when adding an aperture with code value lower than the ones that already exists
 - when adding an aperture with code '0' (zero) it will automatically be set with size zero and type: 'REG' (from region); here we store all the regions from a Gerber file, the ones without a declared aperture
 - when adding an aperture with code '0' (zero) it will automatically be set with size zero and type: 'REG' (from region); here we store all the regions from a Gerber file, the ones without a declared aperture
+- Gerber Editor: added support for Gerber polarity change commands (LPD, LPC)
 
 
 11.04.2019
 11.04.2019
 
 

+ 174 - 70
camlib.py

@@ -2169,6 +2169,10 @@ class Gerber (Geometry):
         # applying a union for every new polygon.
         # applying a union for every new polygon.
         poly_buffer = []
         poly_buffer = []
 
 
+        # made True when the LPC command is encountered in Gerber parsing
+        # it allows adding data into the clear_geometry key of the self.apertures[aperture] dict
+        self.is_lpc = False
+
         # store here the follow geometry
         # store here the follow geometry
         follow_buffer = []
         follow_buffer = []
 
 
@@ -2243,19 +2247,26 @@ class Gerber (Geometry):
                         if not geo.is_empty:
                         if not geo.is_empty:
                             follow_buffer.append(geo)
                             follow_buffer.append(geo)
                             try:
                             try:
-                                self.apertures[current_aperture]['follow_geometry'].append(geo)
+                                self.apertures[last_path_aperture]['follow_geometry'].append(geo)
                             except KeyError:
                             except KeyError:
-                                self.apertures[current_aperture]['follow_geometry'] = []
-                                self.apertures[current_aperture]['follow_geometry'].append(geo)
+                                self.apertures[last_path_aperture]['follow_geometry'] = []
+                                self.apertures[last_path_aperture]['follow_geometry'].append(geo)
 
 
                         geo = LineString(path).buffer(width / 1.999, int(self.steps_per_circle / 4))
                         geo = LineString(path).buffer(width / 1.999, int(self.steps_per_circle / 4))
                         if not geo.is_empty:
                         if not geo.is_empty:
                             poly_buffer.append(geo)
                             poly_buffer.append(geo)
-                            try:
-                                self.apertures[current_aperture]['solid_geometry'].append(geo)
-                            except KeyError:
-                                self.apertures[current_aperture]['solid_geometry'] = []
-                                self.apertures[current_aperture]['solid_geometry'].append(geo)
+                            if self.is_lpc is True:
+                                try:
+                                    self.apertures[last_path_aperture]['clear_geometry'].append(geo)
+                                except KeyError:
+                                    self.apertures[last_path_aperture]['clear_geometry'] = []
+                                    self.apertures[last_path_aperture]['clear_geometry'].append(geo)
+                            else:
+                                try:
+                                    self.apertures[last_path_aperture]['solid_geometry'].append(geo)
+                                except KeyError:
+                                    self.apertures[last_path_aperture]['solid_geometry'] = []
+                                    self.apertures[last_path_aperture]['solid_geometry'].append(geo)
 
 
                         path = [path[-1]]
                         path = [path[-1]]
 
 
@@ -2264,10 +2275,12 @@ class Gerber (Geometry):
                     # TODO: Remove when bug fixed
                     # TODO: Remove when bug fixed
                     if len(poly_buffer) > 0:
                     if len(poly_buffer) > 0:
                         if current_polarity == 'D':
                         if current_polarity == 'D':
+                            self.is_lpc = True
                             # self.follow_geometry = self.follow_geometry.union(cascaded_union(follow_buffer))
                             # self.follow_geometry = self.follow_geometry.union(cascaded_union(follow_buffer))
                             self.solid_geometry = self.solid_geometry.union(cascaded_union(poly_buffer))
                             self.solid_geometry = self.solid_geometry.union(cascaded_union(poly_buffer))
 
 
                         else:
                         else:
+                            self.is_lpc = False
                             # self.follow_geometry = self.follow_geometry.difference(cascaded_union(follow_buffer))
                             # self.follow_geometry = self.follow_geometry.difference(cascaded_union(follow_buffer))
                             self.solid_geometry = self.solid_geometry.difference(cascaded_union(poly_buffer))
                             self.solid_geometry = self.solid_geometry.difference(cascaded_union(poly_buffer))
 
 
@@ -2420,11 +2433,18 @@ class Gerber (Geometry):
                                 int(self.steps_per_circle))
                                 int(self.steps_per_circle))
                             if not flash.is_empty:
                             if not flash.is_empty:
                                 poly_buffer.append(flash)
                                 poly_buffer.append(flash)
-                                try:
-                                    self.apertures[current_aperture]['solid_geometry'].append(flash)
-                                except KeyError:
-                                    self.apertures[current_aperture]['solid_geometry'] = []
-                                    self.apertures[current_aperture]['solid_geometry'].append(flash)
+                                if self.is_lpc is True:
+                                    try:
+                                        self.apertures[current_aperture]['clear_geometry'].append(flash)
+                                    except KeyError:
+                                        self.apertures[current_aperture]['clear_geometry'] = []
+                                        self.apertures[current_aperture]['clear_geometry'].append(flash)
+                                else:
+                                    try:
+                                        self.apertures[current_aperture]['solid_geometry'].append(flash)
+                                    except KeyError:
+                                        self.apertures[current_aperture]['solid_geometry'] = []
+                                        self.apertures[current_aperture]['solid_geometry'].append(flash)
                         except IndexError:
                         except IndexError:
                             log.warning("Line %d: %s -> Nothing there to flash!" % (line_num, gline))
                             log.warning("Line %d: %s -> Nothing there to flash!" % (line_num, gline))
 
 
@@ -2467,11 +2487,18 @@ class Gerber (Geometry):
                             geo = LineString(path).buffer(width / 1.999, int(self.steps_per_circle / 4))
                             geo = LineString(path).buffer(width / 1.999, int(self.steps_per_circle / 4))
                             if not geo.is_empty:
                             if not geo.is_empty:
                                 poly_buffer.append(geo)
                                 poly_buffer.append(geo)
-                                try:
-                                    self.apertures[last_path_aperture]['solid_geometry'].append(geo)
-                                except KeyError:
-                                    self.apertures[last_path_aperture]['solid_geometry'] = []
-                                    self.apertures[last_path_aperture]['solid_geometry'].append(geo)
+                                if self.is_lpc is True:
+                                    try:
+                                        self.apertures[last_path_aperture]['clear_geometry'].append(geo)
+                                    except KeyError:
+                                        self.apertures[last_path_aperture]['clear_geometry'] = []
+                                        self.apertures[last_path_aperture]['clear_geometry'].append(geo)
+                                else:
+                                    try:
+                                        self.apertures[last_path_aperture]['solid_geometry'].append(geo)
+                                    except KeyError:
+                                        self.apertures[last_path_aperture]['solid_geometry'] = []
+                                        self.apertures[last_path_aperture]['solid_geometry'].append(geo)
 
 
                             path = [path[-1]]
                             path = [path[-1]]
 
 
@@ -2497,11 +2524,18 @@ class Gerber (Geometry):
                         geo = LineString(path).buffer(width/1.999, int(self.steps_per_circle / 4))
                         geo = LineString(path).buffer(width/1.999, int(self.steps_per_circle / 4))
                         if not geo.is_empty:
                         if not geo.is_empty:
                             poly_buffer.append(geo)
                             poly_buffer.append(geo)
-                            try:
-                                self.apertures[last_path_aperture]['solid_geometry'].append(geo)
-                            except KeyError:
-                                self.apertures[last_path_aperture]['solid_geometry'] = []
-                                self.apertures[last_path_aperture]['solid_geometry'].append(geo)
+                            if self.is_lpc is True:
+                                try:
+                                    self.apertures[last_path_aperture]['clear_geometry'].append(geo)
+                                except KeyError:
+                                    self.apertures[last_path_aperture]['clear_geometry'] = []
+                                    self.apertures[last_path_aperture]['clear_geometry'].append(geo)
+                            else:
+                                try:
+                                    self.apertures[last_path_aperture]['solid_geometry'].append(geo)
+                                except KeyError:
+                                    self.apertures[last_path_aperture]['solid_geometry'] = []
+                                    self.apertures[last_path_aperture]['solid_geometry'].append(geo)
 
 
                         path = [path[-1]]
                         path = [path[-1]]
 
 
@@ -2525,11 +2559,18 @@ class Gerber (Geometry):
                                     self.apertures[current_aperture]['follow_geometry'].append(geo)
                                     self.apertures[current_aperture]['follow_geometry'].append(geo)
 
 
                                 poly_buffer.append(geo)
                                 poly_buffer.append(geo)
-                                try:
-                                    self.apertures[current_aperture]['solid_geometry'].append(geo)
-                                except KeyError:
-                                    self.apertures[current_aperture]['solid_geometry'] = []
-                                    self.apertures[current_aperture]['solid_geometry'].append(geo)
+                                if self.is_lpc is True:
+                                    try:
+                                        self.apertures[current_aperture]['clear_geometry'].append(geo)
+                                    except KeyError:
+                                        self.apertures[current_aperture]['clear_geometry'] = []
+                                        self.apertures[current_aperture]['clear_geometry'].append(geo)
+                                else:
+                                    try:
+                                        self.apertures[current_aperture]['solid_geometry'].append(geo)
+                                    except KeyError:
+                                        self.apertures[current_aperture]['solid_geometry'] = []
+                                        self.apertures[current_aperture]['solid_geometry'].append(geo)
                             continue
                             continue
 
 
                     # Only one path defines region?
                     # Only one path defines region?
@@ -2578,11 +2619,18 @@ class Gerber (Geometry):
                                 self.apertures['0']['solid_geometry'] = []
                                 self.apertures['0']['solid_geometry'] = []
                             used_aperture = '0'
                             used_aperture = '0'
 
 
-                        try:
-                            self.apertures[used_aperture]['solid_geometry'].append(region)
-                        except KeyError:
-                            self.apertures[used_aperture]['solid_geometry'] = []
-                            self.apertures[used_aperture]['solid_geometry'].append(region)
+                        if self.is_lpc is True:
+                            try:
+                                self.apertures[used_aperture]['clear_geometry'].append(region)
+                            except KeyError:
+                                self.apertures[used_aperture]['clear_geometry'] = []
+                                self.apertures[used_aperture]['clear_geometry'].append(region)
+                        else:
+                            try:
+                                self.apertures[used_aperture]['solid_geometry'].append(region)
+                            except KeyError:
+                                self.apertures[used_aperture]['solid_geometry'] = []
+                                self.apertures[used_aperture]['solid_geometry'].append(region)
 
 
                     path = [[current_x, current_y]]  # Start new path
                     path = [[current_x, current_y]]  # Start new path
                     continue
                     continue
@@ -2653,11 +2701,18 @@ class Gerber (Geometry):
 
 
                                         geo = shply_box(minx, miny, maxx, maxy)
                                         geo = shply_box(minx, miny, maxx, maxy)
                                         poly_buffer.append(geo)
                                         poly_buffer.append(geo)
-                                        try:
-                                            self.apertures[current_aperture]['solid_geometry'].append(geo)
-                                        except KeyError:
-                                            self.apertures[current_aperture]['solid_geometry'] = []
-                                            self.apertures[current_aperture]['solid_geometry'].append(geo)
+                                        if self.is_lpc is True:
+                                            try:
+                                                self.apertures[current_aperture]['clear_geometry'].append(geo)
+                                            except KeyError:
+                                                self.apertures[current_aperture]['clear_geometry'] = []
+                                                self.apertures[current_aperture]['clear_geometry'].append(geo)
+                                        else:
+                                            try:
+                                                self.apertures[current_aperture]['solid_geometry'].append(geo)
+                                            except KeyError:
+                                                self.apertures[current_aperture]['solid_geometry'] = []
+                                                self.apertures[current_aperture]['solid_geometry'].append(geo)
                                 except:
                                 except:
                                     pass
                                     pass
                             last_path_aperture = current_aperture
                             last_path_aperture = current_aperture
@@ -2742,19 +2797,33 @@ class Gerber (Geometry):
                                 if self.apertures[last_path_aperture]["type"] != 'R':
                                 if self.apertures[last_path_aperture]["type"] != 'R':
                                     if not geo.is_empty:
                                     if not geo.is_empty:
                                         poly_buffer.append(geo)
                                         poly_buffer.append(geo)
-                                        try:
-                                            self.apertures[last_path_aperture]['solid_geometry'].append(geo)
-                                        except KeyError:
-                                            self.apertures[last_path_aperture]['solid_geometry'] = []
-                                            self.apertures[last_path_aperture]['solid_geometry'].append(geo)
+                                        if self.is_lpc is True:
+                                            try:
+                                                self.apertures[last_path_aperture]['clear_geometry'].append(geo)
+                                            except KeyError:
+                                                self.apertures[last_path_aperture]['clear_geometry'] = []
+                                                self.apertures[last_path_aperture]['clear_geometry'].append(geo)
+                                        else:
+                                            try:
+                                                self.apertures[last_path_aperture]['solid_geometry'].append(geo)
+                                            except KeyError:
+                                                self.apertures[last_path_aperture]['solid_geometry'] = []
+                                                self.apertures[last_path_aperture]['solid_geometry'].append(geo)
                             except Exception as e:
                             except Exception as e:
                                 log.debug("camlib.Gerber.parse_lines() --> %s" % str(e))
                                 log.debug("camlib.Gerber.parse_lines() --> %s" % str(e))
                                 poly_buffer.append(geo)
                                 poly_buffer.append(geo)
-                                try:
-                                    self.apertures[last_path_aperture]['solid_geometry'].append(geo)
-                                except KeyError:
-                                    self.apertures[last_path_aperture]['solid_geometry'] = []
-                                    self.apertures[last_path_aperture]['solid_geometry'].append(geo)
+                                if self.is_lpc is True:
+                                    try:
+                                        self.apertures[last_path_aperture]['clear_geometry'].append(geo)
+                                    except KeyError:
+                                        self.apertures[last_path_aperture]['clear_geometry'] = []
+                                        self.apertures[last_path_aperture]['clear_geometry'].append(geo)
+                                else:
+                                    try:
+                                        self.apertures[last_path_aperture]['solid_geometry'].append(geo)
+                                    except KeyError:
+                                        self.apertures[last_path_aperture]['solid_geometry'] = []
+                                        self.apertures[last_path_aperture]['solid_geometry'].append(geo)
 
 
                         # if linear_x or linear_y are None, ignore those
                         # if linear_x or linear_y are None, ignore those
                         if linear_x is not None and linear_y is not None:
                         if linear_x is not None and linear_y is not None:
@@ -2797,18 +2866,32 @@ class Gerber (Geometry):
                                 try:
                                 try:
                                     if self.apertures[last_path_aperture]["type"] != 'R':
                                     if self.apertures[last_path_aperture]["type"] != 'R':
                                         poly_buffer.append(geo)
                                         poly_buffer.append(geo)
+                                        if self.is_lpc is True:
+                                            try:
+                                                self.apertures[last_path_aperture]['clear_geometry'].append(geo)
+                                            except KeyError:
+                                                self.apertures[last_path_aperture]['clear_geometry'] = []
+                                                self.apertures[last_path_aperture]['clear_geometry'].append(geo)
+                                        else:
+                                            try:
+                                                self.apertures[last_path_aperture]['solid_geometry'].append(geo)
+                                            except KeyError:
+                                                self.apertures[last_path_aperture]['solid_geometry'] = []
+                                                self.apertures[last_path_aperture]['solid_geometry'].append(geo)
+                                except:
+                                    poly_buffer.append(geo)
+                                    if self.is_lpc is True:
+                                        try:
+                                            self.apertures[last_path_aperture]['clear_geometry'].append(geo)
+                                        except KeyError:
+                                            self.apertures[last_path_aperture]['clear_geometry'] = []
+                                            self.apertures[last_path_aperture]['clear_geometry'].append(geo)
+                                    else:
                                         try:
                                         try:
                                             self.apertures[last_path_aperture]['solid_geometry'].append(geo)
                                             self.apertures[last_path_aperture]['solid_geometry'].append(geo)
                                         except KeyError:
                                         except KeyError:
                                             self.apertures[last_path_aperture]['solid_geometry'] = []
                                             self.apertures[last_path_aperture]['solid_geometry'] = []
                                             self.apertures[last_path_aperture]['solid_geometry'].append(geo)
                                             self.apertures[last_path_aperture]['solid_geometry'].append(geo)
-                                except:
-                                    poly_buffer.append(geo)
-                                    try:
-                                        self.apertures[last_path_aperture]['solid_geometry'].append(geo)
-                                    except KeyError:
-                                        self.apertures[last_path_aperture]['solid_geometry'] = []
-                                        self.apertures[last_path_aperture]['solid_geometry'].append(geo)
 
 
                         # Reset path starting point
                         # Reset path starting point
                         path = [[linear_x, linear_y]]
                         path = [[linear_x, linear_y]]
@@ -2832,11 +2915,18 @@ class Gerber (Geometry):
                         )
                         )
                         if not flash.is_empty:
                         if not flash.is_empty:
                             poly_buffer.append(flash)
                             poly_buffer.append(flash)
-                            try:
-                                self.apertures[current_aperture]['solid_geometry'].append(flash)
-                            except KeyError:
-                                self.apertures[current_aperture]['solid_geometry'] = []
-                                self.apertures[current_aperture]['solid_geometry'].append(flash)
+                            if self.is_lpc is True:
+                                try:
+                                    self.apertures[current_aperture]['clear_geometry'].append(flash)
+                                except KeyError:
+                                    self.apertures[current_aperture]['clear_geometry'] = []
+                                    self.apertures[current_aperture]['clear_geometry'].append(flash)
+                            else:
+                                try:
+                                    self.apertures[current_aperture]['solid_geometry'].append(flash)
+                                except KeyError:
+                                    self.apertures[current_aperture]['solid_geometry'] = []
+                                    self.apertures[current_aperture]['solid_geometry'].append(flash)
 
 
                     # maybe those lines are not exactly needed but it is easier to read the program as those coordinates
                     # maybe those lines are not exactly needed but it is easier to read the program as those coordinates
                     # are used in case that circular interpolation is encountered within the Gerber file
                     # are used in case that circular interpolation is encountered within the Gerber file
@@ -2931,11 +3021,18 @@ class Gerber (Geometry):
                             buffered = LineString(path).buffer(width / 1.999, int(self.steps_per_circle))
                             buffered = LineString(path).buffer(width / 1.999, int(self.steps_per_circle))
                             if not buffered.is_empty:
                             if not buffered.is_empty:
                                 poly_buffer.append(buffered)
                                 poly_buffer.append(buffered)
-                                try:
-                                    self.apertures[last_path_aperture]['solid_geometry'].append(buffered)
-                                except KeyError:
-                                    self.apertures[last_path_aperture]['solid_geometry'] = []
-                                    self.apertures[last_path_aperture]['solid_geometry'].append(buffered)
+                                if self.is_lpc is True:
+                                    try:
+                                        self.apertures[last_path_aperture]['clear_geometry'].append(buffered)
+                                    except KeyError:
+                                        self.apertures[last_path_aperture]['clear_geometry'] = []
+                                        self.apertures[last_path_aperture]['clear_geometry'].append(buffered)
+                                else:
+                                    try:
+                                        self.apertures[last_path_aperture]['solid_geometry'].append(buffered)
+                                    except KeyError:
+                                        self.apertures[last_path_aperture]['solid_geometry'] = []
+                                        self.apertures[last_path_aperture]['solid_geometry'].append(buffered)
 
 
                         current_x = circular_x
                         current_x = circular_x
                         current_y = circular_y
                         current_y = circular_y
@@ -3068,11 +3165,18 @@ class Gerber (Geometry):
                     geo = LineString(path).buffer(width / 1.999, int(self.steps_per_circle / 4))
                     geo = LineString(path).buffer(width / 1.999, int(self.steps_per_circle / 4))
                     if not geo.is_empty:
                     if not geo.is_empty:
                         poly_buffer.append(geo)
                         poly_buffer.append(geo)
-                        try:
-                            self.apertures[last_path_aperture]['solid_geometry'].append(geo)
-                        except KeyError:
-                            self.apertures[last_path_aperture]['solid_geometry'] = []
-                            self.apertures[last_path_aperture]['solid_geometry'].append(geo)
+                        if self.is_lpc is True:
+                            try:
+                                self.apertures[last_path_aperture]['clear_geometry'].append(geo)
+                            except KeyError:
+                                self.apertures[last_path_aperture]['clear_geometry'] = []
+                                self.apertures[last_path_aperture]['clear_geometry'].append(geo)
+                        else:
+                            try:
+                                self.apertures[last_path_aperture]['solid_geometry'].append(geo)
+                            except KeyError:
+                                self.apertures[last_path_aperture]['solid_geometry'] = []
+                                self.apertures[last_path_aperture]['solid_geometry'].append(geo)
 
 
             # --- Apply buffer ---
             # --- Apply buffer ---
 
 

+ 14 - 0
flatcamEditors/FlatCAMGrbEditor.py

@@ -1896,6 +1896,20 @@ class FlatCAMGrbEditor(QtCore.QObject):
                 follow_storage_elem = []
                 follow_storage_elem = []
 
 
                 self.storage_dict[apid] = {}
                 self.storage_dict[apid] = {}
+                # first check if we have any clear_geometry (LPC) and if yes then we need to substract it
+                # from the solid_geometry
+                temp_geo = []
+                if 'clear_geometry' in self.gerber_obj.apertures[apid]:
+                    for clear_geo in self.gerber_obj.apertures[apid]['clear_geometry']:
+                        for solid_geo in self.gerber_obj.apertures[apid]['solid_geometry']:
+                            if solid_geo.intersects(clear_geo):
+                                res_geo = clear_geo.symmetric_difference(solid_geo)
+                                temp_geo.append(res_geo)
+                            else:
+                                temp_geo.append(solid_geo)
+                    self.gerber_obj.apertures[apid]['solid_geometry'] = deepcopy(temp_geo)
+
+                # add the Gerber geometry to editor storage
                 for k, v in self.gerber_obj.apertures[apid].items():
                 for k, v in self.gerber_obj.apertures[apid].items():
                     try:
                     try:
                         if k == 'solid_geometry':
                         if k == 'solid_geometry':