- 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:
Marius Stanciu
2020-04-27 10:03:22 +03:00
committed by Marius
parent 61020e3624
commit 3ec666edbb
28 changed files with 3452 additions and 3389 deletions

View File

@@ -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)

View File

@@ -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()")

View File

@@ -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)