- overwritten the Beta_8.995 branch with the Gerber_Editor_Upgrade branch

This commit is contained in:
Marius Stanciu
2023-05-24 18:07:05 +03:00
parent c23d0c4ed6
commit 63071a9bae
214 changed files with 22249 additions and 6251 deletions

176
camlib.py
View File

@@ -6,27 +6,37 @@
# MIT Licence #
# ########################################################## ##
from PyQt6 import QtWidgets
from io import StringIO
from numpy.linalg import solve, norm
from appCommon.Common import GracefulException as grace
# from scipy.spatial import KDTree, Delaunay
# from scipy.spatial import Delaunay
from appParsers.ParseSVG import svgparselength, svgparse_viewbox, getsvggeo, getsvgtext
from appParsers.ParseDXF import getdxfgeo
from numpy.linalg import solve
import platform
from copy import deepcopy
import traceback
from decimal import Decimal
from copy import deepcopy
from collections.abc import Iterable
from copy import copy
from rtree import index as rtindex
from lxml import etree as ET
from io import StringIO
import ezdxf
# See: http://toblerity.org/shapely/manual.html
from shapely.geometry import Polygon, Point, LinearRing, MultiPoint
from shapely import Polygon, Point, LinearRing, MultiPoint, MultiLineString, MultiPolygon, LineString
from shapely.geometry import box as shply_box
from shapely import box as shply_box
from shapely.ops import unary_union, substring, linemerge
import shapely.affinity as affinity
from shapely.affinity import scale, translate
from shapely.wkt import loads as sloads
from shapely.wkt import dumps as sdumps
from shapely.geometry.base import BaseGeometry
@@ -37,26 +47,14 @@ from shapely.geometry.base import BaseGeometry
from descartes.patch import PolygonPatch
# ---------------------------------------
from collections.abc import Iterable
import ezdxf
from appCommon.Common import GracefulException as grace
# from scipy.spatial import KDTree, Delaunay
# from scipy.spatial import Delaunay
from appParsers.ParseSVG import *
from appParsers.ParseDXF import *
import logging
import re
import numpy as np
import gettext
import appTranslation as fcTranslate
import builtins
import copy
HAS_ORTOOLS = True
if platform.architecture()[0] == '64bit':
@@ -335,13 +333,29 @@ class ApertureMacro:
"""
pol = mods[0]
n = mods[1]
points = [(0, 0)] * (n + 1)
for i in range(n + 1):
points[i] = mods[2 * i + 2:2 * i + 4]
# n = mods[1]
# points = [(0, 0)] * (n + 1)
#
# for i in range(n + 1):
# points[i] = mods[2 * i + 2:2 * i + 4]
#
# angle = mods[2 * n + 4]
angle = mods[2 * n + 4]
# ---------------------------
# added to fix the issue on Allegro 17.2 Gerber's which have fewer points than declared
# discard first 2 values (exposure and vertex points number) and last one (rotation)
vertex_list = mods[2:-1]
# rotation is the last value
angle = mods[-1]
n = int(len(vertex_list) / 2)
points = [(0, 0)] * n
for i in range(n):
start = 2 * i
stop = (2 * i) + 2
points[i] = vertex_list[start:stop]
# ---------------------------
poly = Polygon(points)
poly_rotated = affinity.rotate(poly, angle, origin=(0, 0))
@@ -1432,10 +1446,8 @@ class Geometry(object):
"""
# log.debug("camlib.clear_polygon()")
assert type(polygon) == Polygon or type(polygon) == MultiPolygon, \
"Expected a Polygon or MultiPolygon, got %s" % type(polygon)
# ## The toolpaths
# The toolpaths
# Index first and last points in paths
def get_pts(o):
return [o.coords[0], o.coords[-1]]
@@ -1446,58 +1458,71 @@ class Geometry(object):
# Can only result in a Polygon or MultiPolygon
# NOTE: The resulting polygon can be "empty".
current = polygon.buffer((-tooldia / 1.999999), int(steps_per_circle))
if current.area == 0:
# Otherwise, trying to to insert current.exterior == None
# into the FlatCAMStorage will fail.
# print("Area is None")
return None
current = flatten_shapely_geometry(current)
# current can be a MultiPolygon
try:
for p in current:
geoms.insert(p.exterior)
for i in p.interiors:
geoms.insert(i)
# if current.area == 0:
# # Otherwise, trying to insert current.exterior == None
# # into the FlatCAMStorage will fail.
# # print("Area is None")
# return None
# Not a Multipolygon. Must be a Polygon
except TypeError:
geoms.insert(current.exterior)
for i in current.interiors:
for p in current:
geoms.insert(p.exterior)
for i in p.interiors:
geoms.insert(i)
while True:
if self.app.abort_flag:
# graceful abort requested by the user
raise grace
if self.app.abort_flag:
# graceful abort requested by the user
raise grace
# provide the app with a way to process the GUI events when in a blocking loop
QtWidgets.QApplication.processEvents()
# provide the app with a way to process the GUI events when in a blocking loop
QtWidgets.QApplication.processEvents()
# Can only result in a Polygon or MultiPolygon
current = current.buffer(-tooldia * (1 - overlap), int(steps_per_circle))
if current.area > 0:
for cl_pol in current:
while True:
if self.app.abort_flag:
# graceful abort requested by the user
raise grace
# current can be a MultiPolygon
try:
for p in current.geoms:
geoms.insert(p.exterior)
for i in p.interiors:
# provide the app with a way to process the GUI events when in a blocking loop
QtWidgets.QApplication.processEvents()
cl_pol = cl_pol.buffer(-tooldia * (1 - overlap), int(steps_per_circle))
if isinstance(cl_pol, MultiPolygon):
cl_pol = flatten_shapely_geometry(cl_pol)
added_flag = False
for tiny_pol in cl_pol:
if tiny_pol.area > 0:
added_flag = True
geoms.insert(tiny_pol.exterior)
if prog_plot:
self.plot_temp_shapes(tiny_pol.exterior)
for i in tiny_pol.interiors:
geoms.insert(i)
if prog_plot:
self.plot_temp_shapes(i)
if added_flag is False:
break
cl_pol = MultiPolygon(cl_pol)
else:
if cl_pol.area > 0:
geoms.insert(cl_pol.exterior)
if prog_plot:
self.plot_temp_shapes(cl_pol.exterior)
for i in cl_pol.interiors:
geoms.insert(i)
if prog_plot:
self.plot_temp_shapes(p)
self.plot_temp_shapes(i)
else:
break
# Not a Multipolygon. Must be a Polygon
except (TypeError, AttributeError):
geoms.insert(current.exterior)
if prog_plot:
self.plot_temp_shapes(current.exterior)
for i in current.interiors:
geoms.insert(i)
if prog_plot:
self.plot_temp_shapes(i)
else:
self.app.log.debug("camlib.Geometry.clear_polygon() --> Current Area is zero")
break
if not geoms.objects:
self.app.log.debug("camlib.Geometry.clear_polygon() --> Current Area is zero")
return
if prog_plot:
self.temp_shapes.redraw()
@@ -2283,7 +2308,7 @@ class Geometry(object):
# d = {}
# for attr in self.ser_attrs:
# d[attr] = getattr(self, attr)
return {attr: copy.copy(getattr(self, attr)) for attr in self.ser_attrs}
return {attr: copy(getattr(self, attr)) for attr in self.ser_attrs}
def from_dict(self, d):
"""
@@ -2326,12 +2351,13 @@ class Geometry(object):
flat_geo = []
if self.multigeo:
for tool in self.tools:
flat_geo += self.flatten(self.tools[tool]['solid_geometry'])
flat_geo += self.flatten(self.tools[tool]['solid_geometry'],
pathonly=self.app.options["geometry_paths_only"])
geom_svg = unary_union(flat_geo)
else:
geom_svg = unary_union(self.flatten())
geom_svg = unary_union(self.flatten(pathonly=self.app.options["geometry_paths_only"]))
else:
geom_svg = unary_union(self.flatten())
geom_svg = unary_union(self.flatten(pathonly=self.app.options["geometry_paths_only"]))
xmin, ymin, xmax, ymax = geom_svg.bounds