Sfoglia il codice sorgente

- fixed Excellon parser to detect correctly the units and zeros for Excellon's generated by Eagle 9.3.0
- modified the initial size of the canvas on startup
- modified the build file (make_win.py) to solve the issue with suddenly not accepting the version as Beta

Marius Stanciu 7 anni fa
parent
commit
71d8b2df36
4 ha cambiato i file con 217 aggiunte e 215 eliminazioni
  1. 3 0
      README.md
  2. 1 1
      VisPyCanvas.py
  3. 208 209
      camlib.py
  4. 5 5
      make_win.py

+ 3 - 0
README.md

@@ -20,6 +20,9 @@ CAD program, and create G-Code for Isolation routing.
 - fixed DblSided Tool crash when trying to create Alignment Drills object without a Tool diameter specified
 - fixed DblSided Tool issue when entering Tool diameter values with comma decimal separator instead of decimal dot separator
 - fixed Cutout Tool Freeform to generate cutouts with options: LR, TB. 2LR, 2TB which didn't worked previously
+- fixed Excellon parser to detect correctly the units and zeros for Excellon's generated by Eagle 9.3.0
+- modified the initial size of the canvas on startup
+- modified the build file (make_win.py) to solve the issue with suddenly not accepting the version as Beta
 
 15.02.2019
 

+ 1 - 1
VisPyCanvas.py

@@ -40,7 +40,7 @@ class VisPyCanvas(scene.SceneCanvas):
         right_padding.width_max = 0
 
         view = self.grid_widget.add_view(row=1, col=1, border_color='black', bgcolor='white')
-        view.camera = Camera(aspect=1, rect=(-100,-100,500,500))
+        view.camera = Camera(aspect=1, rect=(-25,-25,150,150))
 
         # Following function was removed from 'prepare_draw()' of 'Grid' class by patch,
         # it is necessary to call manually

+ 208 - 209
camlib.py

@@ -43,7 +43,7 @@ from rasterio.features import shapes
 
 from xml.dom.minidom import parseString as parse_xml_string
 
-from scipy.spatial import KDTree, Delaunay
+# from scipy.spatial import KDTree, Delaunay
 
 from ParseSVG import *
 from ParseDXF import *
@@ -3348,7 +3348,7 @@ class Excellon(Geometry):
         # Number format and units
         # INCH uses 6 digits
         # METRIC uses 5/6
-        self.units_re = re.compile(r'^(INCH|METRIC)(?:,([TL])Z)?$')
+        self.units_re = re.compile(r'^(INCH|METRIC)(?:,([TL])Z)?.*$')
 
         # Tool definition/parameters (?= is look-ahead
         # NOTE: This might be an overkill!
@@ -3968,7 +3968,6 @@ class Excellon(Geometry):
                         #FlatCAMApp.App.inform.emit("Detected INLINE: %s" % str(eline))
                         continue
 
-
                     # Search for zeros type again because it might be alone on the line
                     match = re.search(r'[LT]Z',eline)
                     if match:
@@ -6551,212 +6550,212 @@ def parse_gerber_number(strnumber, int_digits, frac_digits, zeros):
     return ret_val
 
 
-def voronoi(P):
-    """
-    Returns a list of all edges of the voronoi diagram for the given input points.
-    """
-    delauny = Delaunay(P)
-    triangles = delauny.points[delauny.vertices]
-
-    circum_centers = np.array([triangle_csc(tri) for tri in triangles])
-    long_lines_endpoints = []
-
-    lineIndices = []
-    for i, triangle in enumerate(triangles):
-        circum_center = circum_centers[i]
-        for j, neighbor in enumerate(delauny.neighbors[i]):
-            if neighbor != -1:
-                lineIndices.append((i, neighbor))
-            else:
-                ps = triangle[(j+1)%3] - triangle[(j-1)%3]
-                ps = np.array((ps[1], -ps[0]))
-
-                middle = (triangle[(j+1)%3] + triangle[(j-1)%3]) * 0.5
-                di = middle - triangle[j]
-
-                ps /= np.linalg.norm(ps)
-                di /= np.linalg.norm(di)
-
-                if np.dot(di, ps) < 0.0:
-                    ps *= -1000.0
-                else:
-                    ps *= 1000.0
-
-                long_lines_endpoints.append(circum_center + ps)
-                lineIndices.append((i, len(circum_centers) + len(long_lines_endpoints)-1))
-
-    vertices = np.vstack((circum_centers, long_lines_endpoints))
-
-    # filter out any duplicate lines
-    lineIndicesSorted = np.sort(lineIndices) # make (1,2) and (2,1) both (1,2)
-    lineIndicesTupled = [tuple(row) for row in lineIndicesSorted]
-    lineIndicesUnique = np.unique(lineIndicesTupled)
-
-    return vertices, lineIndicesUnique
-
-
-def triangle_csc(pts):
-    rows, cols = pts.shape
-
-    A = np.bmat([[2 * np.dot(pts, pts.T), np.ones((rows, 1))],
-                 [np.ones((1, rows)), np.zeros((1, 1))]])
-
-    b = np.hstack((np.sum(pts * pts, axis=1), np.ones((1))))
-    x = np.linalg.solve(A,b)
-    bary_coords = x[:-1]
-    return np.sum(pts * np.tile(bary_coords.reshape((pts.shape[0], 1)), (1, pts.shape[1])), axis=0)
-
-
-def voronoi_cell_lines(points, vertices, lineIndices):
-    """
-    Returns a mapping from a voronoi cell to its edges.
-
-    :param points: shape (m,2)
-    :param vertices: shape (n,2)
-    :param lineIndices: shape (o,2)
-    :rtype: dict point index -> list of shape (n,2) with vertex indices
-    """
-    kd = KDTree(points)
-
-    cells = collections.defaultdict(list)
-    for i1, i2 in lineIndices:
-        v1, v2 = vertices[i1], vertices[i2]
-        mid = (v1+v2)/2
-        _, (p1Idx, p2Idx) = kd.query(mid, 2)
-        cells[p1Idx].append((i1, i2))
-        cells[p2Idx].append((i1, i2))
-
-    return cells
-
-
-def voronoi_edges2polygons(cells):
-    """
-    Transforms cell edges into polygons.
-
-    :param cells: as returned from voronoi_cell_lines
-    :rtype: dict point index -> list of vertex indices which form a polygon
-    """
-
-    # first, close the outer cells
-    for pIdx, lineIndices_ in cells.items():
-        dangling_lines = []
-        for i1, i2 in lineIndices_:
-            p = (i1, i2)
-            connections = filter(lambda k: p != k and (p[0] == k[0] or p[0] == k[1] or p[1] == k[0] or p[1] == k[1]), lineIndices_)
-            # connections = filter(lambda (i1_, i2_): (i1, i2) != (i1_, i2_) and (i1 == i1_ or i1 == i2_ or i2 == i1_ or i2 == i2_), lineIndices_)
-            assert 1 <= len(connections) <= 2
-            if len(connections) == 1:
-                dangling_lines.append((i1, i2))
-        assert len(dangling_lines) in [0, 2]
-        if len(dangling_lines) == 2:
-            (i11, i12), (i21, i22) = dangling_lines
-            s = (i11, i12)
-            t = (i21, i22)
-
-            # determine which line ends are unconnected
-            connected = filter(lambda k: k != s and (k[0] == s[0] or k[1] == s[0]), lineIndices_)
-            # connected = filter(lambda (i1,i2): (i1,i2) != (i11,i12) and (i1 == i11 or i2 == i11), lineIndices_)
-            i11Unconnected = len(connected) == 0
-
-            connected = filter(lambda k: k != t and (k[0] == t[0] or k[1] == t[0]), lineIndices_)
-            # connected = filter(lambda (i1,i2): (i1,i2) != (i21,i22) and (i1 == i21 or i2 == i21), lineIndices_)
-            i21Unconnected = len(connected) == 0
-
-            startIdx = i11 if i11Unconnected else i12
-            endIdx = i21 if i21Unconnected else i22
-
-            cells[pIdx].append((startIdx, endIdx))
-
-    # then, form polygons by storing vertex indices in (counter-)clockwise order
-    polys = dict()
-    for pIdx, lineIndices_ in cells.items():
-        # get a directed graph which contains both directions and arbitrarily follow one of both
-        directedGraph = lineIndices_ + [(i2, i1) for (i1, i2) in lineIndices_]
-        directedGraphMap = collections.defaultdict(list)
-        for (i1, i2) in directedGraph:
-            directedGraphMap[i1].append(i2)
-        orderedEdges = []
-        currentEdge = directedGraph[0]
-        while len(orderedEdges) < len(lineIndices_):
-            i1 = currentEdge[1]
-            i2 = directedGraphMap[i1][0] if directedGraphMap[i1][0] != currentEdge[0] else directedGraphMap[i1][1]
-            nextEdge = (i1, i2)
-            orderedEdges.append(nextEdge)
-            currentEdge = nextEdge
-
-        polys[pIdx] = [i1 for (i1, i2) in orderedEdges]
-
-    return polys
-
-
-def voronoi_polygons(points):
-    """
-    Returns the voronoi polygon for each input point.
-
-    :param points: shape (n,2)
-    :rtype: list of n polygons where each polygon is an array of vertices
-    """
-    vertices, lineIndices = voronoi(points)
-    cells = voronoi_cell_lines(points, vertices, lineIndices)
-    polys = voronoi_edges2polygons(cells)
-    polylist = []
-    for i in range(len(points)):
-        poly = vertices[np.asarray(polys[i])]
-        polylist.append(poly)
-    return polylist
-
-
-class Zprofile:
-    def __init__(self):
-
-        # data contains lists of [x, y, z]
-        self.data = []
-
-        # Computed voronoi polygons (shapely)
-        self.polygons = []
-        pass
-
-    # def plot_polygons(self):
-    #     axes = plt.subplot(1, 1, 1)
-    #
-    #     plt.axis([-0.05, 1.05, -0.05, 1.05])
-    #
-    #     for poly in self.polygons:
-    #         p = PolygonPatch(poly, facecolor=np.random.rand(3, 1), alpha=0.3)
-    #         axes.add_patch(p)
-
-    def init_from_csv(self, filename):
-        pass
-
-    def init_from_string(self, zpstring):
-        pass
-
-    def init_from_list(self, zplist):
-        self.data = zplist
-
-    def generate_polygons(self):
-        self.polygons = [Polygon(p) for p in voronoi_polygons(array([[x[0], x[1]] for x in self.data]))]
-
-    def normalize(self, origin):
-        pass
-
-    def paste(self, path):
-        """
-        Return a list of dictionaries containing the parts of the original
-        path and their z-axis offset.
-        """
-
-        # At most one region/polygon will contain the path
-        containing = [i for i in range(len(self.polygons)) if self.polygons[i].contains(path)]
-
-        if len(containing) > 0:
-            return [{"path": path, "z": self.data[containing[0]][2]}]
-
-        # All region indexes that intersect with the path
-        crossing = [i for i in range(len(self.polygons)) if self.polygons[i].intersects(path)]
-
-        return [{"path": path.intersection(self.polygons[i]),
-                 "z": self.data[i][2]} for i in crossing]
+# def voronoi(P):
+#     """
+#     Returns a list of all edges of the voronoi diagram for the given input points.
+#     """
+#     delauny = Delaunay(P)
+#     triangles = delauny.points[delauny.vertices]
+#
+#     circum_centers = np.array([triangle_csc(tri) for tri in triangles])
+#     long_lines_endpoints = []
+#
+#     lineIndices = []
+#     for i, triangle in enumerate(triangles):
+#         circum_center = circum_centers[i]
+#         for j, neighbor in enumerate(delauny.neighbors[i]):
+#             if neighbor != -1:
+#                 lineIndices.append((i, neighbor))
+#             else:
+#                 ps = triangle[(j+1)%3] - triangle[(j-1)%3]
+#                 ps = np.array((ps[1], -ps[0]))
+#
+#                 middle = (triangle[(j+1)%3] + triangle[(j-1)%3]) * 0.5
+#                 di = middle - triangle[j]
+#
+#                 ps /= np.linalg.norm(ps)
+#                 di /= np.linalg.norm(di)
+#
+#                 if np.dot(di, ps) < 0.0:
+#                     ps *= -1000.0
+#                 else:
+#                     ps *= 1000.0
+#
+#                 long_lines_endpoints.append(circum_center + ps)
+#                 lineIndices.append((i, len(circum_centers) + len(long_lines_endpoints)-1))
+#
+#     vertices = np.vstack((circum_centers, long_lines_endpoints))
+#
+#     # filter out any duplicate lines
+#     lineIndicesSorted = np.sort(lineIndices) # make (1,2) and (2,1) both (1,2)
+#     lineIndicesTupled = [tuple(row) for row in lineIndicesSorted]
+#     lineIndicesUnique = np.unique(lineIndicesTupled)
+#
+#     return vertices, lineIndicesUnique
+#
+#
+# def triangle_csc(pts):
+#     rows, cols = pts.shape
+#
+#     A = np.bmat([[2 * np.dot(pts, pts.T), np.ones((rows, 1))],
+#                  [np.ones((1, rows)), np.zeros((1, 1))]])
+#
+#     b = np.hstack((np.sum(pts * pts, axis=1), np.ones((1))))
+#     x = np.linalg.solve(A,b)
+#     bary_coords = x[:-1]
+#     return np.sum(pts * np.tile(bary_coords.reshape((pts.shape[0], 1)), (1, pts.shape[1])), axis=0)
+#
+#
+# def voronoi_cell_lines(points, vertices, lineIndices):
+#     """
+#     Returns a mapping from a voronoi cell to its edges.
+#
+#     :param points: shape (m,2)
+#     :param vertices: shape (n,2)
+#     :param lineIndices: shape (o,2)
+#     :rtype: dict point index -> list of shape (n,2) with vertex indices
+#     """
+#     kd = KDTree(points)
+#
+#     cells = collections.defaultdict(list)
+#     for i1, i2 in lineIndices:
+#         v1, v2 = vertices[i1], vertices[i2]
+#         mid = (v1+v2)/2
+#         _, (p1Idx, p2Idx) = kd.query(mid, 2)
+#         cells[p1Idx].append((i1, i2))
+#         cells[p2Idx].append((i1, i2))
+#
+#     return cells
+#
+#
+# def voronoi_edges2polygons(cells):
+#     """
+#     Transforms cell edges into polygons.
+#
+#     :param cells: as returned from voronoi_cell_lines
+#     :rtype: dict point index -> list of vertex indices which form a polygon
+#     """
+#
+#     # first, close the outer cells
+#     for pIdx, lineIndices_ in cells.items():
+#         dangling_lines = []
+#         for i1, i2 in lineIndices_:
+#             p = (i1, i2)
+#             connections = filter(lambda k: p != k and (p[0] == k[0] or p[0] == k[1] or p[1] == k[0] or p[1] == k[1]), lineIndices_)
+#             # connections = filter(lambda (i1_, i2_): (i1, i2) != (i1_, i2_) and (i1 == i1_ or i1 == i2_ or i2 == i1_ or i2 == i2_), lineIndices_)
+#             assert 1 <= len(connections) <= 2
+#             if len(connections) == 1:
+#                 dangling_lines.append((i1, i2))
+#         assert len(dangling_lines) in [0, 2]
+#         if len(dangling_lines) == 2:
+#             (i11, i12), (i21, i22) = dangling_lines
+#             s = (i11, i12)
+#             t = (i21, i22)
+#
+#             # determine which line ends are unconnected
+#             connected = filter(lambda k: k != s and (k[0] == s[0] or k[1] == s[0]), lineIndices_)
+#             # connected = filter(lambda (i1,i2): (i1,i2) != (i11,i12) and (i1 == i11 or i2 == i11), lineIndices_)
+#             i11Unconnected = len(connected) == 0
+#
+#             connected = filter(lambda k: k != t and (k[0] == t[0] or k[1] == t[0]), lineIndices_)
+#             # connected = filter(lambda (i1,i2): (i1,i2) != (i21,i22) and (i1 == i21 or i2 == i21), lineIndices_)
+#             i21Unconnected = len(connected) == 0
+#
+#             startIdx = i11 if i11Unconnected else i12
+#             endIdx = i21 if i21Unconnected else i22
+#
+#             cells[pIdx].append((startIdx, endIdx))
+#
+#     # then, form polygons by storing vertex indices in (counter-)clockwise order
+#     polys = dict()
+#     for pIdx, lineIndices_ in cells.items():
+#         # get a directed graph which contains both directions and arbitrarily follow one of both
+#         directedGraph = lineIndices_ + [(i2, i1) for (i1, i2) in lineIndices_]
+#         directedGraphMap = collections.defaultdict(list)
+#         for (i1, i2) in directedGraph:
+#             directedGraphMap[i1].append(i2)
+#         orderedEdges = []
+#         currentEdge = directedGraph[0]
+#         while len(orderedEdges) < len(lineIndices_):
+#             i1 = currentEdge[1]
+#             i2 = directedGraphMap[i1][0] if directedGraphMap[i1][0] != currentEdge[0] else directedGraphMap[i1][1]
+#             nextEdge = (i1, i2)
+#             orderedEdges.append(nextEdge)
+#             currentEdge = nextEdge
+#
+#         polys[pIdx] = [i1 for (i1, i2) in orderedEdges]
+#
+#     return polys
+#
+#
+# def voronoi_polygons(points):
+#     """
+#     Returns the voronoi polygon for each input point.
+#
+#     :param points: shape (n,2)
+#     :rtype: list of n polygons where each polygon is an array of vertices
+#     """
+#     vertices, lineIndices = voronoi(points)
+#     cells = voronoi_cell_lines(points, vertices, lineIndices)
+#     polys = voronoi_edges2polygons(cells)
+#     polylist = []
+#     for i in range(len(points)):
+#         poly = vertices[np.asarray(polys[i])]
+#         polylist.append(poly)
+#     return polylist
+#
+#
+# class Zprofile:
+#     def __init__(self):
+#
+#         # data contains lists of [x, y, z]
+#         self.data = []
+#
+#         # Computed voronoi polygons (shapely)
+#         self.polygons = []
+#         pass
+#
+#     # def plot_polygons(self):
+#     #     axes = plt.subplot(1, 1, 1)
+#     #
+#     #     plt.axis([-0.05, 1.05, -0.05, 1.05])
+#     #
+#     #     for poly in self.polygons:
+#     #         p = PolygonPatch(poly, facecolor=np.random.rand(3, 1), alpha=0.3)
+#     #         axes.add_patch(p)
+#
+#     def init_from_csv(self, filename):
+#         pass
+#
+#     def init_from_string(self, zpstring):
+#         pass
+#
+#     def init_from_list(self, zplist):
+#         self.data = zplist
+#
+#     def generate_polygons(self):
+#         self.polygons = [Polygon(p) for p in voronoi_polygons(array([[x[0], x[1]] for x in self.data]))]
+#
+#     def normalize(self, origin):
+#         pass
+#
+#     def paste(self, path):
+#         """
+#         Return a list of dictionaries containing the parts of the original
+#         path and their z-axis offset.
+#         """
+#
+#         # At most one region/polygon will contain the path
+#         containing = [i for i in range(len(self.polygons)) if self.polygons[i].contains(path)]
+#
+#         if len(containing) > 0:
+#             return [{"path": path, "z": self.data[containing[0]][2]}]
+#
+#         # All region indexes that intersect with the path
+#         crossing = [i for i in range(len(self.polygons)) if self.polygons[i].intersects(path)]
+#
+#         return [{"path": path.intersection(self.polygons[i]),
+#                  "z": self.data[i][2]} for i in crossing]
 
 
 def autolist(obj):

+ 5 - 5
make_win.py

@@ -63,8 +63,8 @@ if platform.architecture()[0] == '64bit':
         include_files=include_files,
         excludes=['scipy','pytz'],
         # packages=['OpenGL','numpy','vispy','ortools','google']
-        packages=['numpy','google', 'rasterio'] # works for Python 3.7
-        # packages = ['opengl', 'numpy', 'google', 'rasterio'] # works for Python 3.6.5
+        # packages=['numpy','google', 'rasterio'] # works for Python 3.7
+        packages = ['opengl', 'numpy', 'google', 'rasterio'] # works for Python 3.6.5 and Python 3.7.1
 
     )
 else:
@@ -72,8 +72,8 @@ else:
         include_files=include_files,
         excludes=['scipy', 'pytz'],
         # packages=['OpenGL','numpy','vispy','ortools','google']
-        packages=['numpy', 'rasterio']  # works for Python 3.7
-        # packages = ['opengl', 'numpy', 'google', 'rasterio'] # works for Python 3.6.5
+        # packages=['numpy', 'rasterio']  # works for Python 3.7
+        packages = ['opengl', 'numpy', 'google', 'rasterio'] # works for Python 3.6.5 and Python 3.7.1
 
     )
 
@@ -84,7 +84,7 @@ print("INCLUDE_FILES", include_files)
 setup(
     name="FlatCAM",
     author="Juan Pablo Caram",
-    version="Beta",
+    version="8.9",
     description="FlatCAM: 2D Computer Aided PCB Manufacturing",
     options=dict(build_exe=buildOptions),
     executables=[Executable("FlatCAM.py", icon='share/flatcam_icon48.ico', base=base)]