Просмотр исходного кода

- camlib Gerber parser - made sure that we don't loose goemetry in regions
- Gerber Editor - made sure that for some tools the added geometry is clean (the coordinates are non repeating)
- covered some possible issues in Gerber Export

Marius Stanciu 6 лет назад
Родитель
Сommit
e6a0997fd6
4 измененных файлов с 158 добавлено и 137 удалено
  1. 121 115
      FlatCAMObj.py
  2. 3 0
      README.md
  3. 21 20
      camlib.py
  4. 13 2
      flatcamEditors/FlatCAMGrbEditor.py

+ 121 - 115
FlatCAMObj.py

@@ -1308,84 +1308,87 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
                     for geo_elem in self.apertures['0']['geometry']:
                         if 'solid' in geo_elem:
                             geo = geo_elem['solid']
-                            gerber_code += 'G36*\n'
-                            geo_coords = list(geo.exterior.coords)
-                            # first command is a move with pen-up D02 at the beginning of the geo
-                            if g_zeros == 'T':
-                                x_formatted, y_formatted = tz_format(geo_coords[0][0], geo_coords[0][1], factor)
-                                gerber_code += "X{xform}Y{yform}D02*\n".format(xform=x_formatted,
-                                                                               yform=y_formatted)
-                            else:
-                                x_formatted, y_formatted = lz_format(geo_coords[0][0], geo_coords[0][1], factor)
-                                gerber_code += "X{xform}Y{yform}D02*\n".format(xform=x_formatted,
-                                                                               yform=y_formatted)
-                            for coord in geo_coords[1:]:
+                            if not geo.is_empty:
+                                gerber_code += 'G36*\n'
+                                geo_coords = list(geo.exterior.coords)
+                                # first command is a move with pen-up D02 at the beginning of the geo
                                 if g_zeros == 'T':
-                                    x_formatted, y_formatted = tz_format(coord[0], coord[1], factor)
-                                    gerber_code += "X{xform}Y{yform}D01*\n".format(xform=x_formatted,
+                                    x_formatted, y_formatted = tz_format(geo_coords[0][0], geo_coords[0][1], factor)
+                                    gerber_code += "X{xform}Y{yform}D02*\n".format(xform=x_formatted,
                                                                                    yform=y_formatted)
                                 else:
-                                    x_formatted, y_formatted = lz_format(coord[0], coord[1], factor)
-                                    gerber_code += "X{xform}Y{yform}D01*\n".format(xform=x_formatted,
+                                    x_formatted, y_formatted = lz_format(geo_coords[0][0], geo_coords[0][1], factor)
+                                    gerber_code += "X{xform}Y{yform}D02*\n".format(xform=x_formatted,
                                                                                    yform=y_formatted)
-                            gerber_code += 'D02*\n'
-                            gerber_code += 'G37*\n'
-
-                            clear_list = list(geo.interiors)
-                            if clear_list:
-                                gerber_code += '%LPC*%\n'
-                                for clear_geo in clear_list:
-                                    gerber_code += 'G36*\n'
-                                    geo_coords = list(clear_geo.coords)
-
-                                    # first command is a move with pen-up D02 at the beginning of the geo
+                                for coord in geo_coords[1:]:
                                     if g_zeros == 'T':
-                                        x_formatted, y_formatted = tz_format(geo_coords[0][0], geo_coords[0][1], factor)
-                                        gerber_code += "X{xform}Y{yform}D02*\n".format(xform=x_formatted,
+                                        x_formatted, y_formatted = tz_format(coord[0], coord[1], factor)
+                                        gerber_code += "X{xform}Y{yform}D01*\n".format(xform=x_formatted,
                                                                                        yform=y_formatted)
                                     else:
-                                        x_formatted, y_formatted = lz_format(geo_coords[0][0], geo_coords[0][1], factor)
-                                        gerber_code += "X{xform}Y{yform}D02*\n".format(xform=x_formatted,
+                                        x_formatted, y_formatted = lz_format(coord[0], coord[1], factor)
+                                        gerber_code += "X{xform}Y{yform}D01*\n".format(xform=x_formatted,
                                                                                        yform=y_formatted)
-                                    for coord in geo_coords[1:]:
+                                gerber_code += 'D02*\n'
+                                gerber_code += 'G37*\n'
+
+                                clear_list = list(geo.interiors)
+                                if clear_list:
+                                    gerber_code += '%LPC*%\n'
+                                    for clear_geo in clear_list:
+                                        gerber_code += 'G36*\n'
+                                        geo_coords = list(clear_geo.coords)
+
+                                        # first command is a move with pen-up D02 at the beginning of the geo
                                         if g_zeros == 'T':
-                                            x_formatted, y_formatted = tz_format(coord[0], coord[1], factor)
-                                            gerber_code += "X{xform}Y{yform}D01*\n".format(xform=x_formatted,
+                                            x_formatted, y_formatted = tz_format(
+                                                geo_coords[0][0], geo_coords[0][1], factor)
+                                            gerber_code += "X{xform}Y{yform}D02*\n".format(xform=x_formatted,
                                                                                            yform=y_formatted)
                                         else:
-                                            x_formatted, y_formatted = lz_format(coord[0], coord[1], factor)
-                                            gerber_code += "X{xform}Y{yform}D01*\n".format(xform=x_formatted,
+                                            x_formatted, y_formatted = lz_format(
+                                                geo_coords[0][0], geo_coords[0][1], factor)
+                                            gerber_code += "X{xform}Y{yform}D02*\n".format(xform=x_formatted,
                                                                                            yform=y_formatted)
-                                    gerber_code += 'D02*\n'
-                                    gerber_code += 'G37*\n'
-                                gerber_code += '%LPD*%\n'
+                                        for coord in geo_coords[1:]:
+                                            if g_zeros == 'T':
+                                                x_formatted, y_formatted = tz_format(coord[0], coord[1], factor)
+                                                gerber_code += "X{xform}Y{yform}D01*\n".format(xform=x_formatted,
+                                                                                               yform=y_formatted)
+                                            else:
+                                                x_formatted, y_formatted = lz_format(coord[0], coord[1], factor)
+                                                gerber_code += "X{xform}Y{yform}D01*\n".format(xform=x_formatted,
+                                                                                               yform=y_formatted)
+                                        gerber_code += 'D02*\n'
+                                        gerber_code += 'G37*\n'
+                                    gerber_code += '%LPD*%\n'
                         if 'clear' in geo_elem:
                             geo = geo_elem['clear']
-
-                            gerber_code += '%LPC*%\n'
-                            gerber_code += 'G36*\n'
-                            geo_coords = list(geo.exterior.coords)
-                            # first command is a move with pen-up D02 at the beginning of the geo
-                            if g_zeros == 'T':
-                                x_formatted, y_formatted = tz_format(geo_coords[0][0], geo_coords[0][1], factor)
-                                gerber_code += "X{xform}Y{yform}D02*\n".format(xform=x_formatted,
-                                                                               yform=y_formatted)
-                            else:
-                                x_formatted, y_formatted = lz_format(geo_coords[0][0], geo_coords[0][1], factor)
-                                gerber_code += "X{xform}Y{yform}D02*\n".format(xform=x_formatted,
-                                                                               yform=y_formatted)
-                            for coord in geo_coords[1:]:
+                            if not geo.is_empty:
+                                gerber_code += '%LPC*%\n'
+                                gerber_code += 'G36*\n'
+                                geo_coords = list(geo.exterior.coords)
+                                # first command is a move with pen-up D02 at the beginning of the geo
                                 if g_zeros == 'T':
-                                    x_formatted, y_formatted = tz_format(coord[0], coord[1], factor)
-                                    gerber_code += "X{xform}Y{yform}D01*\n".format(xform=x_formatted,
+                                    x_formatted, y_formatted = tz_format(geo_coords[0][0], geo_coords[0][1], factor)
+                                    gerber_code += "X{xform}Y{yform}D02*\n".format(xform=x_formatted,
                                                                                    yform=y_formatted)
                                 else:
-                                    x_formatted, y_formatted = lz_format(coord[0], coord[1], factor)
-                                    gerber_code += "X{xform}Y{yform}D01*\n".format(xform=x_formatted,
+                                    x_formatted, y_formatted = lz_format(geo_coords[0][0], geo_coords[0][1], factor)
+                                    gerber_code += "X{xform}Y{yform}D02*\n".format(xform=x_formatted,
                                                                                    yform=y_formatted)
-                            gerber_code += 'D02*\n'
-                            gerber_code += 'G37*\n'
-                            gerber_code += '%LPD*%\n'
+                                for coord in geo_coords[1:]:
+                                    if g_zeros == 'T':
+                                        x_formatted, y_formatted = tz_format(coord[0], coord[1], factor)
+                                        gerber_code += "X{xform}Y{yform}D01*\n".format(xform=x_formatted,
+                                                                                       yform=y_formatted)
+                                    else:
+                                        x_formatted, y_formatted = lz_format(coord[0], coord[1], factor)
+                                        gerber_code += "X{xform}Y{yform}D01*\n".format(xform=x_formatted,
+                                                                                       yform=y_formatted)
+                                gerber_code += 'D02*\n'
+                                gerber_code += 'G37*\n'
+                                gerber_code += '%LPD*%\n'
 
             for apid in self.apertures:
                 if apid == '0':
@@ -1396,75 +1399,78 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
                         for geo_elem in self.apertures[apid]['geometry']:
                             if 'follow' in geo_elem:
                                 geo = geo_elem['follow']
-                                if geo.is_empty:
-                                    continue
-
-                                if isinstance(geo, Point):
-                                    if g_zeros == 'T':
-                                        x_formatted, y_formatted = tz_format(geo.x, geo.y, factor)
-                                        gerber_code += "X{xform}Y{yform}D03*\n".format(xform=x_formatted,
-                                                                                       yform=y_formatted)
-                                    else:
-                                        x_formatted, y_formatted = lz_format(geo.x, geo.y, factor)
-                                        gerber_code += "X{xform}Y{yform}D03*\n".format(xform=x_formatted,
-                                                                                       yform=y_formatted)
-                                else:
-                                    geo_coords = list(geo.coords)
-                                    # first command is a move with pen-up D02 at the beginning of the geo
-                                    if g_zeros == 'T':
-                                        x_formatted, y_formatted = tz_format(geo_coords[0][0], geo_coords[0][1], factor)
-                                        gerber_code += "X{xform}Y{yform}D02*\n".format(xform=x_formatted,
-                                                                                       yform=y_formatted)
+                                if not geo.is_empty:
+                                    if isinstance(geo, Point):
+                                        if g_zeros == 'T':
+                                            x_formatted, y_formatted = tz_format(geo.x, geo.y, factor)
+                                            gerber_code += "X{xform}Y{yform}D03*\n".format(xform=x_formatted,
+                                                                                           yform=y_formatted)
+                                        else:
+                                            x_formatted, y_formatted = lz_format(geo.x, geo.y, factor)
+                                            gerber_code += "X{xform}Y{yform}D03*\n".format(xform=x_formatted,
+                                                                                           yform=y_formatted)
                                     else:
-                                        x_formatted, y_formatted = lz_format(geo_coords[0][0], geo_coords[0][1], factor)
-                                        gerber_code += "X{xform}Y{yform}D02*\n".format(xform=x_formatted,
-                                                                                       yform=y_formatted)
-                                    for coord in geo_coords[1:]:
+                                        geo_coords = list(geo.coords)
+                                        # first command is a move with pen-up D02 at the beginning of the geo
                                         if g_zeros == 'T':
-                                            x_formatted, y_formatted = tz_format(coord[0], coord[1], factor)
-                                            gerber_code += "X{xform}Y{yform}D01*\n".format(xform=x_formatted,
+                                            x_formatted, y_formatted = tz_format(
+                                                geo_coords[0][0], geo_coords[0][1], factor)
+                                            gerber_code += "X{xform}Y{yform}D02*\n".format(xform=x_formatted,
                                                                                            yform=y_formatted)
                                         else:
-                                            x_formatted, y_formatted = lz_format(coord[0], coord[1], factor)
-                                            gerber_code += "X{xform}Y{yform}D01*\n".format(xform=x_formatted,
+                                            x_formatted, y_formatted = lz_format(
+                                                geo_coords[0][0], geo_coords[0][1], factor)
+                                            gerber_code += "X{xform}Y{yform}D02*\n".format(xform=x_formatted,
                                                                                            yform=y_formatted)
-                                    # gerber_code += "D02*\n"
+                                        for coord in geo_coords[1:]:
+                                            if g_zeros == 'T':
+                                                x_formatted, y_formatted = tz_format(coord[0], coord[1], factor)
+                                                gerber_code += "X{xform}Y{yform}D01*\n".format(xform=x_formatted,
+                                                                                               yform=y_formatted)
+                                            else:
+                                                x_formatted, y_formatted = lz_format(coord[0], coord[1], factor)
+                                                gerber_code += "X{xform}Y{yform}D01*\n".format(xform=x_formatted,
+                                                                                               yform=y_formatted)
+                                        # gerber_code += "D02*\n"
 
                             if 'clear' in geo_elem:
                                 gerber_code += '%LPC*%\n'
 
                                 geo = geo_elem['clear']
-                                if isinstance(geo, Point):
-                                    if g_zeros == 'T':
-                                        x_formatted, y_formatted = tz_format(geo.x, geo.y, factor)
-                                        gerber_code += "X{xform}Y{yform}D03*\n".format(xform=x_formatted,
-                                                                                       yform=y_formatted)
-                                    else:
-                                        x_formatted, y_formatted = lz_format(geo.x, geo.y, factor)
-                                        gerber_code += "X{xform}Y{yform}D03*\n".format(xform=x_formatted,
-                                                                                       yform=y_formatted)
-                                else:
-                                    geo_coords = list(geo.coords)
-                                    # first command is a move with pen-up D02 at the beginning of the geo
-                                    if g_zeros == 'T':
-                                        x_formatted, y_formatted = tz_format(geo_coords[0][0], geo_coords[0][1], factor)
-                                        gerber_code += "X{xform}Y{yform}D02*\n".format(xform=x_formatted,
-                                                                                       yform=y_formatted)
+                                if not geo.is_empty:
+                                    if isinstance(geo, Point):
+                                        if g_zeros == 'T':
+                                            x_formatted, y_formatted = tz_format(geo.x, geo.y, factor)
+                                            gerber_code += "X{xform}Y{yform}D03*\n".format(xform=x_formatted,
+                                                                                           yform=y_formatted)
+                                        else:
+                                            x_formatted, y_formatted = lz_format(geo.x, geo.y, factor)
+                                            gerber_code += "X{xform}Y{yform}D03*\n".format(xform=x_formatted,
+                                                                                           yform=y_formatted)
                                     else:
-                                        x_formatted, y_formatted = lz_format(geo_coords[0][0], geo_coords[0][1], factor)
-                                        gerber_code += "X{xform}Y{yform}D02*\n".format(xform=x_formatted,
-                                                                                       yform=y_formatted)
-                                    for coord in geo_coords[1:]:
+                                        geo_coords = list(geo.coords)
+                                        # first command is a move with pen-up D02 at the beginning of the geo
                                         if g_zeros == 'T':
-                                            x_formatted, y_formatted = tz_format(coord[0], coord[1], factor)
-                                            gerber_code += "X{xform}Y{yform}D01*\n".format(xform=x_formatted,
+                                            x_formatted, y_formatted = tz_format(
+                                                geo_coords[0][0], geo_coords[0][1], factor)
+                                            gerber_code += "X{xform}Y{yform}D02*\n".format(xform=x_formatted,
                                                                                            yform=y_formatted)
                                         else:
-                                            x_formatted, y_formatted = lz_format(coord[0], coord[1], factor)
-                                            gerber_code += "X{xform}Y{yform}D01*\n".format(xform=x_formatted,
-                                                                                          yform=y_formatted)
-                                    # gerber_code += "D02*\n"
-                                gerber_code += '%LPD*%\n'
+                                            x_formatted, y_formatted = lz_format(
+                                                geo_coords[0][0], geo_coords[0][1], factor)
+                                            gerber_code += "X{xform}Y{yform}D02*\n".format(xform=x_formatted,
+                                                                                           yform=y_formatted)
+                                        for coord in geo_coords[1:]:
+                                            if g_zeros == 'T':
+                                                x_formatted, y_formatted = tz_format(coord[0], coord[1], factor)
+                                                gerber_code += "X{xform}Y{yform}D01*\n".format(xform=x_formatted,
+                                                                                               yform=y_formatted)
+                                            else:
+                                                x_formatted, y_formatted = lz_format(coord[0], coord[1], factor)
+                                                gerber_code += "X{xform}Y{yform}D01*\n".format(xform=x_formatted,
+                                                                                              yform=y_formatted)
+                                        # gerber_code += "D02*\n"
+                                    gerber_code += '%LPD*%\n'
 
         except Exception as e:
             log.debug("FlatCAMObj.FlatCAMGerber.export_gerber() --> %s" % str(e))

+ 3 - 0
README.md

@@ -16,6 +16,9 @@ CAD program, and create G-Code for Isolation routing.
 - Gerber Editor: fixed the Poligonize Tool to work with new geometric structure and took care of a special case
 - Gerber Export is fixed to work with the new Gerber object data structure and it now works also for Gerber objects edited in Gerber Editor
 - Gerber Editor: fixed units conversion for obj.apertures keys that require it
+- camlib Gerber parser - made sure that we don't loose goemetry in regions
+- Gerber Editor - made sure that for some tools the added geometry is clean (the coordinates are non repeating)
+- covered some possible issues in Gerber Export
 
 12.05.2019
 

+ 21 - 20
camlib.py

@@ -2575,27 +2575,28 @@ class Gerber (Geometry):
                         self.apertures['0']['size'] = 0.0
                         self.apertures['0']['geometry'] = []
 
-                    # if D02 happened before G37 we now have a path with 1 element only so we have to add the current
+                    # if D02 happened before G37 we now have a path with 1 element only; we have to add the current
                     # geo to the poly_buffer otherwise we loose it
-                    # if current_operation_code == 2:
-                    #     print(path)
-                    #     geo_dict = dict()
-                    #     if geo_f:
-                    #         if not geo_f.is_empty:
-                    #             follow_buffer.append(geo_f)
-                    #             geo_dict['follow'] = geo_f
-                    #     if geo_s:
-                    #         if not geo_s.is_empty:
-                    #             poly_buffer.append(geo_s)
-                    #             if self.is_lpc is True:
-                    #                 geo_dict['clear'] = geo_s
-                    #             else:
-                    #                 geo_dict['solid'] = geo_s
-                    #
-                    #     if geo_s or geo_f:
-                    #         self.apertures['0']['geometry'].append(deepcopy(geo_dict))
-                    #
-                    #     continue
+                    if current_operation_code == 2:
+                        if len(path) == 1:
+                            # this means that the geometry was prepared previously and we just need to add it
+                            geo_dict = dict()
+                            if geo_f:
+                                if not geo_f.is_empty:
+                                    follow_buffer.append(geo_f)
+                                    geo_dict['follow'] = geo_f
+                            if geo_s:
+                                if not geo_s.is_empty:
+                                    poly_buffer.append(geo_s)
+                                    if self.is_lpc is True:
+                                        geo_dict['clear'] = geo_s
+                                    else:
+                                        geo_dict['solid'] = geo_s
+
+                            if geo_s or geo_f:
+                                self.apertures['0']['geometry'].append(deepcopy(geo_dict))
+
+                            path = [[current_x, current_y]]  # Start new path
 
                     # Only one path defines region?
                     # This can happen if D02 happened before G37 and

+ 13 - 2
flatcamEditors/FlatCAMGrbEditor.py

@@ -767,6 +767,9 @@ class FCPoligonize(FCShapeTool):
         current_storage = self.draw_app.storage_dict[self.draw_app.last_aperture_selected]['geometry']
         if isinstance(fused_geo, MultiPolygon):
             for geo in fused_geo:
+                # clean-up the geo
+                geo = geo.buffer(0)
+
                 if len(geo.interiors) == 0:
                     try:
                         current_storage = self.draw_app.storage_dict['0']['geometry']
@@ -778,6 +781,9 @@ class FCPoligonize(FCShapeTool):
                 new_el['follow'] = geo.exterior
                 self.draw_app.on_grb_shape_complete(current_storage, specific_shape=DrawToolShape(deepcopy(new_el)))
         else:
+            # clean-up the geo
+            fused_geo = fused_geo.buffer(0)
+
             if len(fused_geo.interiors) == 0 and len(exterior_geo) == 1:
                 try:
                     current_storage = self.draw_app.storage_dict['0']['geometry']
@@ -1118,7 +1124,7 @@ class FCTrack(FCRegion):
             new_geo_el['solid'] = Point(self.temp_points).buffer(self.buf_val)
             new_geo_el['follow'] = Point(self.temp_points)
         else:
-            new_geo_el['solid'] = LineString(self.temp_points).buffer(self.buf_val)
+            new_geo_el['solid'] = (LineString(self.temp_points).buffer(self.buf_val)).buffer(0)
             new_geo_el['follow'] = LineString(self.temp_points)
 
         self.geometry = DrawToolShape(new_geo_el)
@@ -1134,7 +1140,12 @@ class FCTrack(FCRegion):
 
     def click(self, point):
         self.draw_app.in_action = True
-        self.points.append(point)
+        try:
+            if point != self.points[-1]:
+                self.points.append(point)
+        except IndexError:
+            self.points.append(point)
+
         new_geo_el = dict()
 
         if len(self.temp_points) == 1: