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

- fixed importing DXF file as Gerber method such that now the resulting Gerber object is correctly created having the geometry attributes like self.apertures and self.follow_geometry

Marius Stanciu 5 лет назад
Родитель
Сommit
e1dab238a7
5 измененных файлов с 81 добавлено и 26 удалено
  1. 1 0
      CHANGELOG.md
  2. 63 11
      appParsers/ParseGerber.py
  3. 8 3
      app_Main.py
  4. 3 10
      camlib.py
  5. 6 2
      tclCommands/TclCommandOpenDXF.py

+ 1 - 0
CHANGELOG.md

@@ -10,6 +10,7 @@ CHANGELOG for FlatCAM beta
 2.07.2020
 2.07.2020
 
 
 - trying to optimize the resulting geometry in DXF import (and in SVG import) by merging contiguous lines; reduced the lines to about one third of the original
 - trying to optimize the resulting geometry in DXF import (and in SVG import) by merging contiguous lines; reduced the lines to about one third of the original
+- fixed importing DXF file as Gerber method such that now the resulting Gerber object is correctly created having the geometry attributes like self.apertures and self.follow_geometry
 
 
 30.06.2020
 30.06.2020
 
 

+ 63 - 11
appParsers/ParseGerber.py

@@ -2,20 +2,22 @@ from PyQt5 import QtWidgets
 from camlib import Geometry, arc, arc_angle, ApertureMacro, grace
 from camlib import Geometry, arc, arc_angle, ApertureMacro, grace
 
 
 import numpy as np
 import numpy as np
-import re
-import logging
+# import re
+# import logging
 import traceback
 import traceback
 from copy import deepcopy
 from copy import deepcopy
-import sys
+# import sys
 
 
-from shapely.ops import cascaded_union
-from shapely.affinity import scale, translate
+from shapely.ops import unary_union, linemerge
+# from shapely.affinity import scale, translate
 import shapely.affinity as affinity
 import shapely.affinity as affinity
-from shapely.geometry import box as shply_box, Polygon, LineString, Point, MultiPolygon
+from shapely.geometry import box as shply_box
 
 
 from lxml import etree as ET
 from lxml import etree as ET
+import ezdxf
+
+from appParsers.ParseDXF import *
 from appParsers.ParseSVG import svgparselength, getsvggeo
 from appParsers.ParseSVG import svgparselength, getsvggeo
-import appTranslation as fcTranslate
 
 
 import gettext
 import gettext
 import builtins
 import builtins
@@ -502,10 +504,10 @@ class Gerber(Geometry):
 
 
                     if buff_length > 0:
                     if buff_length > 0:
                         if current_polarity == 'D':
                         if current_polarity == 'D':
-                            self.solid_geometry = self.solid_geometry.union(cascaded_union(poly_buffer))
+                            self.solid_geometry = self.solid_geometry.union(unary_union(poly_buffer))
 
 
                         else:
                         else:
-                            self.solid_geometry = self.solid_geometry.difference(cascaded_union(poly_buffer))
+                            self.solid_geometry = self.solid_geometry.difference(unary_union(poly_buffer))
 
 
                         # follow_buffer = []
                         # follow_buffer = []
                         poly_buffer = []
                         poly_buffer = []
@@ -1497,7 +1499,7 @@ class Gerber(Geometry):
 
 
             else:
             else:
                 log.debug("Union by union()...")
                 log.debug("Union by union()...")
-                new_poly = cascaded_union(poly_buffer)
+                new_poly = unary_union(poly_buffer)
                 new_poly = new_poly.buffer(0, int(self.steps_per_circle / 4))
                 new_poly = new_poly.buffer(0, int(self.steps_per_circle / 4))
                 log.warning("Union done.")
                 log.warning("Union done.")
 
 
@@ -1601,7 +1603,7 @@ class Gerber(Geometry):
                 p2 = Point(loc[0], loc[1] - 0.5 * (height - width))
                 p2 = Point(loc[0], loc[1] - 0.5 * (height - width))
                 c1 = p1.buffer(width * 0.5, int(steps_per_circle / 4))
                 c1 = p1.buffer(width * 0.5, int(steps_per_circle / 4))
                 c2 = p2.buffer(width * 0.5, int(steps_per_circle / 4))
                 c2 = p2.buffer(width * 0.5, int(steps_per_circle / 4))
-            return cascaded_union([c1, c2]).convex_hull
+            return unary_union([c1, c2]).convex_hull
 
 
         if aperture['type'] == 'P':  # Regular polygon
         if aperture['type'] == 'P':  # Regular polygon
             loc = location.coords[0]
             loc = location.coords[0]
@@ -1836,6 +1838,56 @@ class Gerber(Geometry):
             new_el['follow'] = pol.exterior
             new_el['follow'] = pol.exterior
             self.apertures['0']['geometry'].append(new_el)
             self.apertures['0']['geometry'].append(new_el)
 
 
+    def import_dxf_as_gerber(self, filename, units='MM'):
+        """
+        Imports shapes from an DXF file into the Gerberobject geometry.
+
+        :param filename:    Path to the DXF file.
+        :type filename:     str
+        :param units:       Application units
+        :return: None
+        """
+
+        log.debug("Parsing DXF file geometry into a Gerber object geometry.")
+        # Parse into list of shapely objects
+        dxf = ezdxf.readfile(filename)
+        geos = getdxfgeo(dxf)
+        # trying to optimize the resulting geometry by merging contiguous lines
+        geos = linemerge(geos)
+
+        # Add to object
+        if self.solid_geometry is None:
+            self.solid_geometry = []
+
+        if type(self.solid_geometry) is list:
+            if type(geos) is list:
+                self.solid_geometry += geos
+            else:
+                self.solid_geometry.append(geos)
+        else:  # It's shapely geometry
+            self.solid_geometry = [self.solid_geometry, geos]
+
+        # flatten the self.solid_geometry list for import_dxf() to import DXF as Gerber
+        flat_geo = list(self.flatten_list(self.solid_geometry))
+        if flat_geo:
+            self.solid_geometry = unary_union(flat_geo)
+            self.follow_geometry = self.solid_geometry
+        else:
+            return "fail"
+
+        # create the self.apertures data structure
+        if '0' not in self.apertures:
+            self.apertures['0'] = {}
+            self.apertures['0']['type'] = 'REG'
+            self.apertures['0']['size'] = 0.0
+            self.apertures['0']['geometry'] = []
+
+        for pol in flat_geo:
+            new_el = {}
+            new_el['solid'] = pol
+            new_el['follow'] = pol
+            self.apertures['0']['geometry'].append(deepcopy(new_el))
+
     def scale(self, xfactor, yfactor=None, point=None):
     def scale(self, xfactor, yfactor=None, point=None):
         """
         """
         Scales the objects' geometry on the XY plane by a given factor.
         Scales the objects' geometry on the XY plane by a given factor.

+ 8 - 3
app_Main.py

@@ -8617,7 +8617,7 @@ class App(QtCore.QObject):
         :param plot:        If True then the resulting object will be plotted on canvas
         :param plot:        If True then the resulting object will be plotted on canvas
         :return:
         :return:
         """
         """
-        self.defaults.report_usage("import_dxf()")
+        log.debug(" ********* Importing SVG as: %s ********* " % geo_type.capitalize())
 
 
         obj_type = ""
         obj_type = ""
         if geo_type is None or geo_type == "geometry":
         if geo_type is None or geo_type == "geometry":
@@ -8632,8 +8632,13 @@ class App(QtCore.QObject):
         units = self.defaults['units'].upper()
         units = self.defaults['units'].upper()
 
 
         def obj_init(geo_obj, app_obj):
         def obj_init(geo_obj, app_obj):
-            geo_obj.import_dxf(filename, obj_type, units=units)
-            geo_obj.multigeo = False
+            if obj_type == "geometry":
+                geo_obj.import_dxf_as_geo(filename, units=units)
+            elif obj_type == "gerber":
+                geo_obj.import_dxf_as_gerber(filename, units=units)
+            else:
+                return "fail"
+            geo_obj.multigeo = True
 
 
         with self.proc_container.new(_("Importing DXF")):
         with self.proc_container.new(_("Importing DXF")):
 
 

+ 3 - 10
camlib.py

@@ -22,7 +22,7 @@ from rtree import index as rtindex
 from lxml import etree as ET
 from lxml import etree as ET
 
 
 # See: http://toblerity.org/shapely/manual.html
 # See: http://toblerity.org/shapely/manual.html
-from shapely.geometry import Polygon, LineString, Point, LinearRing, MultiLineString, MultiPoint, MultiPolygon
+from shapely.geometry import Polygon, Point, LinearRing
 
 
 from shapely.geometry import box as shply_box
 from shapely.geometry import box as shply_box
 from shapely.ops import cascaded_union, unary_union, substring, linemerge
 from shapely.ops import cascaded_union, unary_union, substring, linemerge
@@ -1087,16 +1087,16 @@ class Geometry(object):
             if geos_text_f:
             if geos_text_f:
                 self.solid_geometry = self.solid_geometry + geos_text_f
                 self.solid_geometry = self.solid_geometry + geos_text_f
 
 
-    def import_dxf(self, filename, object_type=None, units='MM'):
+    def import_dxf_as_geo(self, filename, units='MM'):
         """
         """
         Imports shapes from an DXF file into the object's geometry.
         Imports shapes from an DXF file into the object's geometry.
 
 
         :param filename:    Path to the DXF file.
         :param filename:    Path to the DXF file.
         :type filename:     str
         :type filename:     str
-        :param object_type:
         :param units:       Application units
         :param units:       Application units
         :return: None
         :return: None
         """
         """
+        log.debug("Parsing DXF file geometry into a Geometry object solid geometry.")
 
 
         # Parse into list of shapely objects
         # Parse into list of shapely objects
         dxf = ezdxf.readfile(filename)
         dxf = ezdxf.readfile(filename)
@@ -1116,13 +1116,6 @@ class Geometry(object):
         else:  # It's shapely geometry
         else:  # It's shapely geometry
             self.solid_geometry = [self.solid_geometry, geos]
             self.solid_geometry = [self.solid_geometry, geos]
 
 
-        # flatten the self.solid_geometry list for import_dxf() to import DXF as Gerber
-        self.solid_geometry = list(self.flatten_list(self.solid_geometry))
-        if self.solid_geometry is not None:
-            self.solid_geometry = cascaded_union(self.solid_geometry)
-        else:
-            return
-
         # commented until this function is ready
         # commented until this function is ready
         # geos_text = getdxftext(dxf, object_type, units=units)
         # geos_text = getdxftext(dxf, object_type, units=units)
         # if geos_text is not None:
         # if geos_text is not None:

+ 6 - 2
tclCommands/TclCommandOpenDXF.py

@@ -54,8 +54,12 @@ class TclCommandOpenDXF(TclCommandSignaled):
 
 
             # if geo_obj.kind != 'geometry' and geo_obj.kind != 'gerber':
             # if geo_obj.kind != 'geometry' and geo_obj.kind != 'gerber':
             #     self.raise_tcl_error('Expected Geometry or Gerber, got %s %s.' % (outname, type(geo_obj)))
             #     self.raise_tcl_error('Expected Geometry or Gerber, got %s %s.' % (outname, type(geo_obj)))
-
-            geo_obj.import_dxf(filename, obj_type, units=units)
+            if obj_type == "geometry":
+                geo_obj.import_dxf_as_geo(filename, units=units)
+            elif obj_type == "gerber":
+                geo_obj.import_dxf_as_gerber(filename, units=units)
+            else:
+                return "fail"
 
 
         filename = args['filename']
         filename = args['filename']