- replaced the testing if instance of FlatCAMObj with testing the obj.kind attribute
- removed the import of the whole FlatCAMApp file only for the usage of GracefulException - remove the import of FlatCAMApp and used alternate ways - optimized the imports in some files - moved the Bookmarksmanager and ToolDB classes into their own files - solved some bugs that were not so visible in the Editors and HPGL parser
This commit is contained in:
@@ -7,7 +7,6 @@
|
||||
# ########################################################## ##
|
||||
|
||||
from camlib import Geometry
|
||||
import FlatCAMApp
|
||||
|
||||
import shapely.affinity as affinity
|
||||
from shapely.geometry import Point, LineString
|
||||
@@ -19,6 +18,7 @@ import traceback
|
||||
from copy import deepcopy
|
||||
|
||||
import FlatCAMTranslation as fcTranslate
|
||||
from FlatCAMCommon import GracefulException as grace
|
||||
|
||||
import gettext
|
||||
import builtins
|
||||
@@ -86,6 +86,7 @@ class Excellon(Geometry):
|
||||
:return: Excellon object.
|
||||
:rtype: Excellon
|
||||
"""
|
||||
|
||||
self.decimals = self.app.decimals
|
||||
|
||||
if geo_steps_per_circle is None:
|
||||
@@ -241,12 +242,12 @@ class Excellon(Geometry):
|
||||
|
||||
def parse_file(self, filename=None, file_obj=None):
|
||||
"""
|
||||
Reads the specified file as array of lines as
|
||||
passes it to ``parse_lines()``.
|
||||
Reads the specified file as array of lines as passes it to ``parse_lines()``.
|
||||
|
||||
:param filename: The file to be read and parsed.
|
||||
:type filename: str
|
||||
:return: None
|
||||
:param filename: The file to be read and parsed.
|
||||
:param file_obj:
|
||||
:type filename: str
|
||||
:return: None
|
||||
"""
|
||||
if file_obj:
|
||||
estr = file_obj
|
||||
@@ -298,7 +299,7 @@ class Excellon(Geometry):
|
||||
for eline in elines:
|
||||
if self.app.abort_flag:
|
||||
# graceful abort requested by the user
|
||||
raise FlatCAMApp.GracefulException
|
||||
raise grace
|
||||
|
||||
line_num += 1
|
||||
# log.debug("%3d %s" % (line_num, str(eline)))
|
||||
@@ -526,7 +527,7 @@ class Excellon(Geometry):
|
||||
slot_dia = 0.05
|
||||
try:
|
||||
slot_dia = float(self.tools[current_tool]['C'])
|
||||
except Exception as e:
|
||||
except Exception:
|
||||
pass
|
||||
log.debug(
|
||||
'Milling/Drilling slot with tool %s, diam=%f' % (
|
||||
@@ -596,7 +597,7 @@ class Excellon(Geometry):
|
||||
slot_dia = 0.05
|
||||
try:
|
||||
slot_dia = float(self.tools[current_tool]['C'])
|
||||
except Exception as e:
|
||||
except Exception:
|
||||
pass
|
||||
log.debug(
|
||||
'Milling/Drilling slot with tool %s, diam=%f' % (
|
||||
@@ -893,9 +894,8 @@ class Excellon(Geometry):
|
||||
log.info("Zeros: %s, Units %s." % (self.zeros, self.units))
|
||||
except Exception:
|
||||
log.error("Excellon PARSING FAILED. Line %d: %s" % (line_num, eline))
|
||||
msg = '[ERROR_NOTCL] %s' % \
|
||||
_("An internal error has ocurred. See shell.\n")
|
||||
msg += ('{e_code} {tx} {l_nr}: {line}\n').format(
|
||||
msg = '[ERROR_NOTCL] %s' % _("An internal error has occurred. See shell.\n")
|
||||
msg += '{e_code} {tx} {l_nr}: {line}\n'.format(
|
||||
e_code='[ERROR]',
|
||||
tx=_("Excellon Parser error.\nParsing Failed. Line"),
|
||||
l_nr=line_num,
|
||||
@@ -1010,13 +1010,13 @@ class Excellon(Geometry):
|
||||
"Excellon geometry creation failed due of ERROR: %s" % str(e))
|
||||
return "fail"
|
||||
|
||||
def bounds(self):
|
||||
def bounds(self, flatten=None):
|
||||
"""
|
||||
Returns coordinates of rectangular bounds
|
||||
of Excellon geometry: (xmin, ymin, xmax, ymax).
|
||||
|
||||
:param flatten: No used
|
||||
"""
|
||||
# fixed issue of getting bounds only for one level lists of objects
|
||||
# now it can get bounds for nested lists of objects
|
||||
|
||||
log.debug("flatcamParsers.ParseExcellon.Excellon.bounds()")
|
||||
|
||||
@@ -1056,11 +1056,11 @@ class Excellon(Geometry):
|
||||
maxy_list = []
|
||||
|
||||
for tool in self.tools:
|
||||
minx, miny, maxx, maxy = bounds_rec(self.tools[tool]['solid_geometry'])
|
||||
minx_list.append(minx)
|
||||
miny_list.append(miny)
|
||||
maxx_list.append(maxx)
|
||||
maxy_list.append(maxy)
|
||||
eminx, eminy, emaxx, emaxy = bounds_rec(self.tools[tool]['solid_geometry'])
|
||||
minx_list.append(eminx)
|
||||
miny_list.append(eminy)
|
||||
maxx_list.append(emaxx)
|
||||
maxy_list.append(emaxy)
|
||||
|
||||
return min(minx_list), min(miny_list), max(maxx_list), max(maxy_list)
|
||||
|
||||
@@ -1075,8 +1075,9 @@ class Excellon(Geometry):
|
||||
|
||||
Kind of convolute way to make the conversion and it is based on the assumption that the Excellon file
|
||||
will have detected the units before the tools are parsed and stored in self.tools
|
||||
:param units:
|
||||
:type str: IN or MM
|
||||
|
||||
:param units: 'IN' or 'MM'. String
|
||||
|
||||
:return:
|
||||
"""
|
||||
|
||||
@@ -1109,12 +1110,13 @@ class Excellon(Geometry):
|
||||
Scales geometry on the XY plane in the object by a given factor.
|
||||
Tool sizes, feedrates an Z-plane dimensions are untouched.
|
||||
|
||||
:param xfactor: Number by which to scale the object.
|
||||
:type xfactor: float
|
||||
:param yfactor: Number by which to scale the object.
|
||||
:type yfactor: float
|
||||
:return: None
|
||||
:rtype: NOne
|
||||
:param xfactor: Number by which to scale the object.
|
||||
:type xfactor: float
|
||||
:param yfactor: Number by which to scale the object.
|
||||
:type yfactor: float
|
||||
:param point: Origin point for scale
|
||||
:return: None
|
||||
:rtype: None
|
||||
"""
|
||||
log.debug("flatcamParsers.ParseExcellon.Excellon.scale()")
|
||||
|
||||
@@ -1145,8 +1147,7 @@ class Excellon(Geometry):
|
||||
# variables to display the percentage of work done
|
||||
self.geo_len = 0
|
||||
try:
|
||||
for g in self.drills:
|
||||
self.geo_len += 1
|
||||
self.geo_len = len(self.drills)
|
||||
except TypeError:
|
||||
self.geo_len = 1
|
||||
self.old_disp_number = 0
|
||||
@@ -1190,12 +1191,12 @@ class Excellon(Geometry):
|
||||
return
|
||||
|
||||
def offset_geom(obj):
|
||||
if type(obj) is list:
|
||||
try:
|
||||
new_obj = []
|
||||
for g in obj:
|
||||
new_obj.append(offset_geom(g))
|
||||
for geo in obj:
|
||||
new_obj.append(offset_geom(geo))
|
||||
return new_obj
|
||||
else:
|
||||
except TypeError:
|
||||
try:
|
||||
return affinity.translate(obj, xoff=dx, yoff=dy)
|
||||
except AttributeError:
|
||||
@@ -1204,8 +1205,7 @@ class Excellon(Geometry):
|
||||
# variables to display the percentage of work done
|
||||
self.geo_len = 0
|
||||
try:
|
||||
for g in self.drills:
|
||||
self.geo_len += 1
|
||||
self.geo_len = len(self.drills)
|
||||
except TypeError:
|
||||
self.geo_len = 1
|
||||
self.old_disp_number = 0
|
||||
@@ -1237,11 +1237,11 @@ class Excellon(Geometry):
|
||||
def mirror(self, axis, point):
|
||||
"""
|
||||
|
||||
:param axis: "X" or "Y" indicates around which axis to mirror.
|
||||
:type axis: str
|
||||
:param point: [x, y] point belonging to the mirror axis.
|
||||
:type point: list
|
||||
:return: None
|
||||
:param axis: "X" or "Y" indicates around which axis to mirror.
|
||||
:type axis: str
|
||||
:param point: [x, y] point belonging to the mirror axis.
|
||||
:type point: list
|
||||
:return: None
|
||||
"""
|
||||
log.debug("flatcamParsers.ParseExcellon.Excellon.mirror()")
|
||||
|
||||
@@ -1249,12 +1249,12 @@ class Excellon(Geometry):
|
||||
xscale, yscale = {"X": (1.0, -1.0), "Y": (-1.0, 1.0)}[axis]
|
||||
|
||||
def mirror_geom(obj):
|
||||
if type(obj) is list:
|
||||
try:
|
||||
new_obj = []
|
||||
for g in obj:
|
||||
new_obj.append(mirror_geom(g))
|
||||
for geo in obj:
|
||||
new_obj.append(mirror_geom(geo))
|
||||
return new_obj
|
||||
else:
|
||||
except TypeError:
|
||||
try:
|
||||
return affinity.scale(obj, xscale, yscale, origin=(px, py))
|
||||
except AttributeError:
|
||||
@@ -1265,8 +1265,7 @@ class Excellon(Geometry):
|
||||
# variables to display the percentage of work done
|
||||
self.geo_len = 0
|
||||
try:
|
||||
for g in self.drills:
|
||||
self.geo_len += 1
|
||||
self.geo_len = len(self.drills)
|
||||
except TypeError:
|
||||
self.geo_len = 1
|
||||
self.old_disp_number = 0
|
||||
@@ -1300,12 +1299,12 @@ class Excellon(Geometry):
|
||||
Shear/Skew the geometries of an object by angles along x and y dimensions.
|
||||
Tool sizes, feedrates an Z-plane dimensions are untouched.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
xs, ys : float, float
|
||||
:param angle_x:
|
||||
:param angle_y:
|
||||
The shear angle(s) for the x and y axes respectively. These can be
|
||||
specified in either degrees (default) or radians by setting
|
||||
use_radians=True.
|
||||
:param point: Origin point for Skew
|
||||
|
||||
See shapely manual for more information:
|
||||
http://toblerity.org/shapely/manual.html#affine-transformations
|
||||
@@ -1322,12 +1321,12 @@ class Excellon(Geometry):
|
||||
return
|
||||
|
||||
def skew_geom(obj):
|
||||
if type(obj) is list:
|
||||
try:
|
||||
new_obj = []
|
||||
for g in obj:
|
||||
new_obj.append(skew_geom(g))
|
||||
return new_obj
|
||||
else:
|
||||
except TypeError:
|
||||
try:
|
||||
return affinity.skew(obj, angle_x, angle_y, origin=(px, py))
|
||||
except AttributeError:
|
||||
@@ -1336,8 +1335,7 @@ class Excellon(Geometry):
|
||||
# variables to display the percentage of work done
|
||||
self.geo_len = 0
|
||||
try:
|
||||
for g in self.drills:
|
||||
self.geo_len += 1
|
||||
self.geo_len = len(self.drills)
|
||||
except TypeError:
|
||||
self.geo_len = 1
|
||||
self.old_disp_number = 0
|
||||
@@ -1393,9 +1391,10 @@ class Excellon(Geometry):
|
||||
def rotate(self, angle, point=None):
|
||||
"""
|
||||
Rotate the geometry of an object by an angle around the 'point' coordinates
|
||||
|
||||
:param angle:
|
||||
:param point: tuple of coordinates (x, y)
|
||||
:return:
|
||||
:param point: tuple of coordinates (x, y)
|
||||
:return: None
|
||||
"""
|
||||
log.debug("flatcamParsers.ParseExcellon.Excellon.rotate()")
|
||||
|
||||
@@ -1423,8 +1422,7 @@ class Excellon(Geometry):
|
||||
# variables to display the percentage of work done
|
||||
self.geo_len = 0
|
||||
try:
|
||||
for g in self.drills:
|
||||
self.geo_len += 1
|
||||
self.geo_len = len(self.drills)
|
||||
except TypeError:
|
||||
self.geo_len = 1
|
||||
self.old_disp_number = 0
|
||||
@@ -1476,9 +1474,10 @@ class Excellon(Geometry):
|
||||
def buffer(self, distance, join, factor):
|
||||
"""
|
||||
|
||||
:param distance: if 'factor' is True then distance is the factor
|
||||
:param factor: True or False (None)
|
||||
:return:
|
||||
:param distance: if 'factor' is True then distance is the factor
|
||||
:param factor: True or False (None)
|
||||
:param join: The type of line joint used by the shapely buffer method: round, square, bevel
|
||||
:return: None
|
||||
"""
|
||||
log.debug("flatcamParsers.ParseExcellon.Excellon.buffer()")
|
||||
|
||||
@@ -1486,12 +1485,12 @@ class Excellon(Geometry):
|
||||
return
|
||||
|
||||
def buffer_geom(obj):
|
||||
if type(obj) is list:
|
||||
try:
|
||||
new_obj = []
|
||||
for g in obj:
|
||||
new_obj.append(buffer_geom(g))
|
||||
return new_obj
|
||||
else:
|
||||
except TypeError:
|
||||
try:
|
||||
if factor is None:
|
||||
return obj.buffer(distance, resolution=self.geo_steps_per_circle)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
from PyQt5 import QtWidgets
|
||||
from camlib import Geometry, arc, arc_angle, ApertureMacro
|
||||
import FlatCAMApp
|
||||
|
||||
import numpy as np
|
||||
import re
|
||||
@@ -9,15 +8,16 @@ import traceback
|
||||
from copy import deepcopy
|
||||
import sys
|
||||
|
||||
from shapely.ops import cascaded_union, unary_union
|
||||
from shapely.geometry import Polygon, MultiPolygon, LineString, Point
|
||||
from shapely.ops import cascaded_union
|
||||
from shapely.affinity import scale, translate
|
||||
import shapely.affinity as affinity
|
||||
from shapely.geometry import box as shply_box
|
||||
from shapely.geometry import box as shply_box, Polygon, LineString, Point, MultiPolygon
|
||||
|
||||
from lxml import etree as ET
|
||||
from flatcamParsers.ParseSVG import *
|
||||
|
||||
from flatcamParsers.ParseSVG import svgparselength, getsvggeo
|
||||
from FlatCAMCommon import GracefulException as grace
|
||||
import FlatCAMTranslation as fcTranslate
|
||||
|
||||
import gettext
|
||||
import builtins
|
||||
|
||||
@@ -255,7 +255,7 @@ class Gerber(Geometry):
|
||||
"""
|
||||
if self.app.abort_flag:
|
||||
# graceful abort requested by the user
|
||||
raise FlatCAMApp.GracefulException
|
||||
raise grace
|
||||
|
||||
# Found some Gerber with a leading zero in the aperture id and the
|
||||
# referenced it without the zero, so this is a hack to handle that.
|
||||
@@ -403,7 +403,7 @@ class Gerber(Geometry):
|
||||
|
||||
# Absolute or Relative/Incremental coordinates
|
||||
# Not implemented
|
||||
absolute = True
|
||||
# absolute = True
|
||||
|
||||
# How to interpret circular interpolation: SINGLE or MULTI
|
||||
quadrant_mode = None
|
||||
@@ -428,7 +428,7 @@ class Gerber(Geometry):
|
||||
for gline in glines:
|
||||
if self.app.abort_flag:
|
||||
# graceful abort requested by the user
|
||||
raise FlatCAMApp.GracefulException
|
||||
raise grace
|
||||
|
||||
line_num += 1
|
||||
self.source_file += gline + '\n'
|
||||
@@ -986,7 +986,7 @@ class Gerber(Geometry):
|
||||
if 'geometry' not in self.apertures[current_aperture]:
|
||||
self.apertures[current_aperture]['geometry'] = []
|
||||
self.apertures[current_aperture]['geometry'].append(deepcopy(geo_dict))
|
||||
except Exception as e:
|
||||
except Exception:
|
||||
pass
|
||||
last_path_aperture = current_aperture
|
||||
# we do this for the case that a region is done without having defined any aperture
|
||||
@@ -1229,25 +1229,25 @@ class Gerber(Geometry):
|
||||
try:
|
||||
circular_x = parse_gerber_number(circular_x,
|
||||
self.int_digits, self.frac_digits, self.gerber_zeros)
|
||||
except Exception as e:
|
||||
except Exception:
|
||||
circular_x = current_x
|
||||
|
||||
try:
|
||||
circular_y = parse_gerber_number(circular_y,
|
||||
self.int_digits, self.frac_digits, self.gerber_zeros)
|
||||
except Exception as e:
|
||||
except Exception:
|
||||
circular_y = current_y
|
||||
|
||||
# According to Gerber specification i and j are not modal, which means that when i or j are missing,
|
||||
# they are to be interpreted as being zero
|
||||
try:
|
||||
i = parse_gerber_number(i, self.int_digits, self.frac_digits, self.gerber_zeros)
|
||||
except Exception as e:
|
||||
except Exception:
|
||||
i = 0
|
||||
|
||||
try:
|
||||
j = parse_gerber_number(j, self.int_digits, self.frac_digits, self.gerber_zeros)
|
||||
except Exception as e:
|
||||
except Exception:
|
||||
j = 0
|
||||
|
||||
if quadrant_mode is None:
|
||||
@@ -1668,13 +1668,14 @@ class Gerber(Geometry):
|
||||
bbox = bbox.envelope
|
||||
return bbox
|
||||
|
||||
def bounds(self):
|
||||
def bounds(self, flatten=None):
|
||||
"""
|
||||
Returns coordinates of rectangular bounds
|
||||
of Gerber geometry: (xmin, ymin, xmax, ymax).
|
||||
|
||||
:param flatten: Not used, it is here for compatibility with base class method
|
||||
:return: None
|
||||
"""
|
||||
# fixed issue of getting bounds only for one level lists of objects
|
||||
# now it can get bounds for nested lists of objects
|
||||
|
||||
log.debug("parseGerber.Gerber.bounds()")
|
||||
|
||||
@@ -1999,8 +2000,7 @@ class Gerber(Geometry):
|
||||
# variables to display the percentage of work done
|
||||
self.geo_len = 0
|
||||
try:
|
||||
for __ in self.solid_geometry:
|
||||
self.geo_len += 1
|
||||
self.geo_len = len(self.solid_geometry)
|
||||
except TypeError:
|
||||
self.geo_len = 1
|
||||
|
||||
@@ -2078,8 +2078,7 @@ class Gerber(Geometry):
|
||||
# variables to display the percentage of work done
|
||||
self.geo_len = 0
|
||||
try:
|
||||
for __ in self.solid_geometry:
|
||||
self.geo_len += 1
|
||||
self.geo_len = len(self.solid_geometry)
|
||||
except TypeError:
|
||||
self.geo_len = 1
|
||||
|
||||
@@ -2217,8 +2216,7 @@ class Gerber(Geometry):
|
||||
# variables to display the percentage of work done
|
||||
self.geo_len = 0
|
||||
try:
|
||||
for __ in self.solid_geometry:
|
||||
self.geo_len += 1
|
||||
self.geo_len = len(self.solid_geometry)
|
||||
except TypeError:
|
||||
self.geo_len = 1
|
||||
|
||||
@@ -2266,8 +2264,9 @@ class Gerber(Geometry):
|
||||
def buffer(self, distance, join, factor=None):
|
||||
"""
|
||||
|
||||
:param distance: if 'factor' is True then distance is the factor
|
||||
:param factor: True or False (None)
|
||||
:param distance: If 'factor' is True then distance is the factor
|
||||
:param join: The type of joining used by the Shapely buffer method. Can be: round, square and bevel
|
||||
:param factor: True or False (None)
|
||||
:return:
|
||||
"""
|
||||
log.debug("parseGerber.Gerber.buffer()")
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
# ############################################################
|
||||
|
||||
from camlib import arc, three_point_circle
|
||||
import FlatCAMApp
|
||||
|
||||
import numpy as np
|
||||
import re
|
||||
@@ -19,6 +18,7 @@ import sys
|
||||
from shapely.ops import unary_union
|
||||
from shapely.geometry import LineString, Point
|
||||
|
||||
from FlatCAMCommon import GracefulException as grace
|
||||
import FlatCAMTranslation as fcTranslate
|
||||
import gettext
|
||||
import builtins
|
||||
@@ -180,7 +180,7 @@ class HPGL2:
|
||||
for gline in glines:
|
||||
if self.app.abort_flag:
|
||||
# graceful abort requested by the user
|
||||
raise FlatCAMApp.GracefulException
|
||||
raise grace
|
||||
|
||||
line_num += 1
|
||||
self.source_file += gline + '\n'
|
||||
@@ -304,7 +304,7 @@ class HPGL2:
|
||||
(_("Coordinates missing, line ignored"), str(gline)))
|
||||
|
||||
if current_x is not None and current_y is not None:
|
||||
radius = match.group(1)
|
||||
radius = float(match.group(1))
|
||||
geo = Point((current_x, current_y)).buffer(radius, int(self.steps_per_circle))
|
||||
geo_line = geo.exterior
|
||||
self.tools[current_tool]['solid_geometry'].append(geo_line)
|
||||
|
||||
Reference in New Issue
Block a user