- fixed an error due of missing attribute of PlotCanvasLegacy when using Legacy2D graphic engine
- solving deprecation warnings issued by Shapely - made sure that the Gerber Object geometry is always flattened
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
|
||||
from PyQt6 import QtWidgets, QtCore, QtGui
|
||||
|
||||
from camlib import grace
|
||||
from camlib import grace, flatten_shapely_geometry
|
||||
from appTool import AppTool
|
||||
from appGUI.GUIElements import FCDoubleSpinner, RadioSet, FCEntry, FCComboBox, FCLabel, FCCheckBox, \
|
||||
VerticalScrollArea, FCGridLayout, FCFrame, FCComboBox2
|
||||
@@ -694,11 +694,7 @@ class ToolCopperThieving(AppTool):
|
||||
geo_n = working_obj.solid_geometry
|
||||
|
||||
if working_obj.kind == 'geometry':
|
||||
try:
|
||||
__ = iter(geo_n)
|
||||
except Exception as e:
|
||||
log.error("ToolCopperFIll.copper_thieving() 'box' --> %s" % str(e))
|
||||
geo_n = [geo_n]
|
||||
geo_n = flatten_shapely_geometry(geo_n)
|
||||
|
||||
geo_buff_list = []
|
||||
for poly in geo_n:
|
||||
@@ -789,11 +785,7 @@ class ToolCopperThieving(AppTool):
|
||||
dy = bounding_box.centroid.y - thieving_box_geo.centroid.y
|
||||
|
||||
thieving_box_geo = affinity.translate(thieving_box_geo, xoff=dx, yoff=dy)
|
||||
|
||||
try:
|
||||
_it = iter(thieving_box_geo)
|
||||
except TypeError:
|
||||
thieving_box_geo = [thieving_box_geo]
|
||||
thieving_box_geo = flatten_shapely_geometry(thieving_box_geo)
|
||||
|
||||
thieving_geo = []
|
||||
for dot_geo in thieving_box_geo:
|
||||
|
||||
@@ -13,6 +13,7 @@ from appGUI.GUIElements import FCDoubleSpinner, FCCheckBox, RadioSet, FCComboBox
|
||||
from shapely.geometry import box, MultiPolygon, Polygon, LineString, LinearRing, MultiLineString, Point
|
||||
from shapely.ops import unary_union, linemerge
|
||||
import shapely.affinity as affinity
|
||||
from camlib import flatten_shapely_geometry
|
||||
|
||||
from matplotlib.backend_bases import KeyEvent as mpl_key_event
|
||||
|
||||
@@ -937,11 +938,7 @@ class CutOut(AppTool):
|
||||
if gap_type == 'bt' and thin_entry != 0:
|
||||
gaps_solid_geo = rest_geo
|
||||
else:
|
||||
try:
|
||||
__ = iter(object_geo)
|
||||
except TypeError:
|
||||
object_geo = [object_geo]
|
||||
|
||||
object_geo = flatten_shapely_geometry(object_geo)
|
||||
for geom_struct in object_geo:
|
||||
if cutout_obj.kind == 'gerber':
|
||||
if margin >= 0:
|
||||
@@ -991,11 +988,7 @@ class CutOut(AppTool):
|
||||
__, rest_geo = cutout_handler(geom=mb_geo, gapsize=gapsize)
|
||||
mouse_bites_geo = rest_geo
|
||||
else:
|
||||
try:
|
||||
__ = iter(mb_object_geo)
|
||||
except TypeError:
|
||||
mb_object_geo = [mb_object_geo]
|
||||
|
||||
mb_object_geo = flatten_shapely_geometry(mb_object_geo)
|
||||
for mb_geom_struct in mb_object_geo:
|
||||
if cutout_obj.kind == 'gerber':
|
||||
if margin >= 0:
|
||||
@@ -1269,11 +1262,7 @@ class CutOut(AppTool):
|
||||
gaps_solid_geo = self.subtract_geo(geo, deepcopy(solid_geo))
|
||||
else:
|
||||
if cutout_obj.kind == 'geometry':
|
||||
try:
|
||||
__ = iter(object_geo)
|
||||
except TypeError:
|
||||
object_geo = [object_geo]
|
||||
|
||||
object_geo = flatten_shapely_geometry(object_geo)
|
||||
for geom_struct in object_geo:
|
||||
geom_struct = unary_union(geom_struct)
|
||||
xmin, ymin, xmax, ymax = geom_struct.bounds
|
||||
@@ -1287,11 +1276,7 @@ class CutOut(AppTool):
|
||||
except TypeError:
|
||||
gaps_solid_geo.append(self.subtract_geo(geom_struct, c_geo))
|
||||
elif cutout_obj.kind == 'gerber' and margin >= 0:
|
||||
try:
|
||||
__ = iter(object_geo)
|
||||
except TypeError:
|
||||
object_geo = [object_geo]
|
||||
|
||||
object_geo = flatten_shapely_geometry(object_geo)
|
||||
for geom_struct in object_geo:
|
||||
geom_struct = unary_union(geom_struct)
|
||||
xmin, ymin, xmax, ymax = geom_struct.bounds
|
||||
@@ -1347,11 +1332,7 @@ class CutOut(AppTool):
|
||||
mouse_bites_geo = self.subtract_geo(mb_geo, mb_solid_geo)
|
||||
else:
|
||||
if cutout_obj.kind == 'geometry':
|
||||
try:
|
||||
__ = iter(mb_object_geo)
|
||||
except TypeError:
|
||||
mb_object_geo = [mb_object_geo]
|
||||
|
||||
mb_object_geo = flatten_shapely_geometry(mb_object_geo)
|
||||
for mb_geom_struct in mb_object_geo:
|
||||
mb_geom_struct = unary_union(mb_geom_struct)
|
||||
xmin, ymin, xmax, ymax = mb_geom_struct.bounds
|
||||
@@ -1365,11 +1346,7 @@ class CutOut(AppTool):
|
||||
except TypeError:
|
||||
mouse_bites_geo.append(self.subtract_geo(mb_geom_struct, c_geo))
|
||||
elif cutout_obj.kind == 'gerber' and margin >= 0:
|
||||
try:
|
||||
__ = iter(mb_object_geo)
|
||||
except TypeError:
|
||||
mb_object_geo = [mb_object_geo]
|
||||
|
||||
mb_object_geo = flatten_shapely_geometry(mb_object_geo)
|
||||
for mb_geom_struct in mb_object_geo:
|
||||
mb_geom_struct = unary_union(mb_geom_struct)
|
||||
xmin, ymin, xmax, ymax = mb_geom_struct.bounds
|
||||
@@ -2259,11 +2236,7 @@ class CutOut(AppTool):
|
||||
"""
|
||||
|
||||
results = []
|
||||
try:
|
||||
__ = iter(target_geo)
|
||||
except TypeError:
|
||||
target_geo = [target_geo]
|
||||
|
||||
target_geo = flatten_shapely_geometry(target_geo)
|
||||
for geo in target_geo:
|
||||
if second_geo.intersects(geo):
|
||||
results.append(second_geo.intersection(geo))
|
||||
|
||||
@@ -10,6 +10,7 @@ from PyQt6 import QtWidgets, QtCore, QtGui
|
||||
from appTool import AppTool
|
||||
from appGUI.GUIElements import FCButton, FCDoubleSpinner, RadioSet, FCComboBox, NumericalEvalEntry, FCEntry, \
|
||||
VerticalScrollArea, FCGridLayout, FCLabel, FCFrame
|
||||
from camlib import flatten_shapely_geometry
|
||||
|
||||
from shapely.ops import unary_union
|
||||
|
||||
@@ -225,11 +226,7 @@ class ToolEtchCompensation(AppTool):
|
||||
# no need to do anything for zero value offset isn't it? compensating with zero is the same as the original
|
||||
return
|
||||
|
||||
try:
|
||||
__ = iter(grb_obj.solid_geometry)
|
||||
except TypeError:
|
||||
grb_obj.solid_geometry = [grb_obj.solid_geometry]
|
||||
|
||||
grb_obj.solid_geometry = flatten_shapely_geometry(grb_obj.solid_geometry)
|
||||
new_solid_geometry = []
|
||||
|
||||
for poly in grb_obj.solid_geometry:
|
||||
|
||||
@@ -10,6 +10,7 @@ from PyQt6 import QtWidgets, QtCore, QtGui
|
||||
from appTool import AppTool
|
||||
from appGUI.GUIElements import RadioSet, FCButton, FCComboBox, FCLabel, VerticalScrollArea, FCGridLayout, FCFrame
|
||||
from appParsers.ParseGerber import Gerber
|
||||
from camlib import flatten_shapely_geometry
|
||||
|
||||
from copy import deepcopy
|
||||
|
||||
@@ -304,11 +305,7 @@ class ToolFollow(AppTool, Gerber):
|
||||
if opt_key.find('tools_') == 0:
|
||||
new_data[opt_key] = app_obj.options[opt_key]
|
||||
|
||||
try:
|
||||
__ = iter(followed_obj.follow_geometry)
|
||||
except TypeError:
|
||||
followed_obj.follow_geometry = [followed_obj.follow_geometry]
|
||||
|
||||
followed_obj.follow_geometry = flatten_shapely_geometry(followed_obj.follow_geometry)
|
||||
follow_geo = [
|
||||
g for g in followed_obj.follow_geometry if g and not g.is_empty and g.is_valid and
|
||||
g.geom_type != 'Point'
|
||||
@@ -384,11 +381,7 @@ class ToolFollow(AppTool, Gerber):
|
||||
self.sel_rect[:] = []
|
||||
self.points = []
|
||||
|
||||
try:
|
||||
__ = iter(area_follow)
|
||||
except TypeError:
|
||||
area_follow = [area_follow]
|
||||
|
||||
area_follow = flatten_shapely_geometry(area_follow)
|
||||
cleaned_area_follow = [g for g in area_follow if not g.is_empty and g.is_valid and g.geom_type != 'Point']
|
||||
|
||||
new_obj.solid_geometry = deepcopy(cleaned_area_follow)
|
||||
|
||||
@@ -10,6 +10,7 @@ from PyQt6 import QtWidgets, QtCore, QtGui
|
||||
from appTool import AppTool
|
||||
from appGUI.GUIElements import FCButton, FCDoubleSpinner, RadioSet, FCComboBox, FCLabel, \
|
||||
VerticalScrollArea, FCGridLayout, FCFrame
|
||||
from camlib import flatten_shapely_geometry
|
||||
|
||||
from shapely.geometry import box
|
||||
|
||||
@@ -151,21 +152,12 @@ class ToolInvertGerber(AppTool):
|
||||
xmin, ymin, xmax, ymax = grb_obj.bounds()
|
||||
|
||||
grb_box = box(xmin, ymin, xmax, ymax).buffer(margin, resolution=grb_circle_steps, join_style=join_style)
|
||||
|
||||
try:
|
||||
__ = iter(grb_obj.solid_geometry)
|
||||
except TypeError:
|
||||
grb_obj.solid_geometry = list(grb_obj.solid_geometry)
|
||||
|
||||
new_solid_geometry = deepcopy(grb_box)
|
||||
|
||||
grb_obj.solid_geometry = flatten_shapely_geometry(grb_obj.solid_geometry)
|
||||
for poly in grb_obj.solid_geometry:
|
||||
new_solid_geometry = new_solid_geometry.difference(poly)
|
||||
|
||||
try:
|
||||
__ = iter(new_solid_geometry)
|
||||
except TypeError:
|
||||
new_solid_geometry = [new_solid_geometry]
|
||||
new_solid_geometry = flatten_shapely_geometry(new_solid_geometry)
|
||||
|
||||
new_options = {}
|
||||
for opt in grb_obj.options:
|
||||
@@ -175,8 +167,8 @@ class ToolInvertGerber(AppTool):
|
||||
|
||||
if 0 not in new_apertures:
|
||||
new_apertures[0] = {
|
||||
'type': 'REG',
|
||||
'size': 0.0,
|
||||
'type': 'REG',
|
||||
'size': 0.0,
|
||||
'geometry': []
|
||||
}
|
||||
|
||||
|
||||
@@ -1026,10 +1026,7 @@ class ToolIsolation(AppTool, Gerber):
|
||||
total_geo = MultiPolygon(total_geo)
|
||||
total_geo = total_geo.buffer(0)
|
||||
|
||||
try:
|
||||
__ = iter(total_geo)
|
||||
geo_len = len(total_geo)
|
||||
except TypeError:
|
||||
if isinstance(total_geo, Polygon):
|
||||
msg = ('[ERROR_NOTCL] %s' % _("The Gerber object has one Polygon as geometry.\n"
|
||||
"There are no distances between geometry elements to be found."))
|
||||
|
||||
@@ -1165,11 +1162,10 @@ class ToolIsolation(AppTool, Gerber):
|
||||
total_geo = MultiPolygon(total_geo)
|
||||
total_geo = total_geo.buffer(0)
|
||||
|
||||
try:
|
||||
__ = iter(total_geo)
|
||||
geo_len = len(total_geo)
|
||||
if isinstance(total_geo, MultiPolygon):
|
||||
geo_len = len(total_geo.geoms)
|
||||
geo_len = (geo_len * (geo_len - 1)) / 2
|
||||
except TypeError:
|
||||
elif isinstance(total_geo, Polygon):
|
||||
msg = _("The Gerber object has one Polygon as geometry.\n"
|
||||
"There are no distances between geometry elements to be found.")
|
||||
app_obj.inform.emit('[ERROR_NOTCL] %s' % msg)
|
||||
|
||||
@@ -13,7 +13,7 @@ from appGUI.GUIElements import FCCheckBox, FCDoubleSpinner, RadioSet, FCTable, F
|
||||
VerticalScrollArea, FCGridLayout, FCFrame
|
||||
from appParsers.ParseGerber import Gerber
|
||||
|
||||
from camlib import grace
|
||||
from camlib import grace, flatten_shapely_geometry
|
||||
|
||||
from copy import deepcopy
|
||||
|
||||
@@ -1010,10 +1010,7 @@ class NonCopperClear(AppTool, Gerber):
|
||||
total_geo = MultiPolygon(total_geo)
|
||||
total_geo = total_geo.buffer(0)
|
||||
|
||||
try:
|
||||
__ = iter(total_geo)
|
||||
geo_len = len(total_geo)
|
||||
except TypeError:
|
||||
if isinstance(total_geo, Polygon):
|
||||
msg = ('[ERROR_NOTCL] %s' % _("The Gerber object has one Polygon as geometry.\n"
|
||||
"There are no distances between geometry elements to be found."))
|
||||
|
||||
@@ -1153,11 +1150,10 @@ class NonCopperClear(AppTool, Gerber):
|
||||
total_geo = MultiPolygon(total_geo)
|
||||
total_geo = total_geo.buffer(0)
|
||||
|
||||
try:
|
||||
__ = iter(total_geo)
|
||||
geo_len = len(total_geo)
|
||||
if isinstance(total_geo, MultiPolygon):
|
||||
geo_len = len(total_geo.geoms)
|
||||
geo_len = (geo_len * (geo_len - 1)) / 2
|
||||
except TypeError:
|
||||
elif isinstance(total_geo, Polygon):
|
||||
app_obj.inform.emit('[ERROR_NOTCL] %s' %
|
||||
_("The Gerber object has one Polygon as geometry.\n"
|
||||
"There are no distances between geometry elements to be found."))
|
||||
@@ -1949,26 +1945,19 @@ class NonCopperClear(AppTool, Gerber):
|
||||
return None
|
||||
elif ncc_select == 1: # _("Area Selection")
|
||||
env_obj = unary_union(self.sel_rect)
|
||||
try:
|
||||
__ = iter(env_obj)
|
||||
except Exception:
|
||||
env_obj = [env_obj]
|
||||
env_obj = flatten_shapely_geometry(env_obj)
|
||||
elif ncc_select == 2: # _("Reference Object")
|
||||
if box_obj is None:
|
||||
return None, None
|
||||
|
||||
box_geo = box_obj.solid_geometry
|
||||
if box_kind == 'geometry':
|
||||
try:
|
||||
__ = iter(box_geo)
|
||||
env_obj = box_geo
|
||||
except Exception:
|
||||
env_obj = [box_geo]
|
||||
|
||||
box_geo = flatten_shapely_geometry(box_geo)
|
||||
elif box_kind == 'gerber':
|
||||
box_geo = unary_union(box_obj.solid_geometry).convex_hull
|
||||
ncc_geo = unary_union(ncc_obj.solid_geometry).convex_hull
|
||||
env_obj = ncc_geo.intersection(box_geo)
|
||||
env_obj = flatten_shapely_geometry(env_obj)
|
||||
else:
|
||||
self.app.inform.emit('[ERROR_NOTCL] %s' % _("The reference object type is not supported."))
|
||||
return 'fail'
|
||||
@@ -3001,11 +2990,7 @@ class NonCopperClear(AppTool, Gerber):
|
||||
|
||||
elif ncc_select == 1: # area
|
||||
geo_n = unary_union(self.sel_rect)
|
||||
try:
|
||||
__ = iter(geo_n)
|
||||
except Exception as e:
|
||||
self.app.log.error("NonCopperClear.clear_copper() 'area' --> %s" % str(e))
|
||||
geo_n = [geo_n]
|
||||
geo_n = flatten_shapely_geometry(geo_n)
|
||||
|
||||
geo_buff_list = []
|
||||
for poly in geo_n:
|
||||
@@ -3019,13 +3004,8 @@ class NonCopperClear(AppTool, Gerber):
|
||||
elif ncc_select == 2: # Reference Object
|
||||
geo_n = ncc_sel_obj.solid_geometry
|
||||
if ncc_sel_obj.kind == 'geometry':
|
||||
try:
|
||||
__ = iter(geo_n)
|
||||
except Exception as e:
|
||||
self.app.log.error("NonCopperClear.clear_copper() 'Reference Object' --> %s" % str(e))
|
||||
geo_n = [geo_n]
|
||||
|
||||
geo_buff_list = []
|
||||
geo_n = flatten_shapely_geometry(geo_n)
|
||||
for poly in geo_n:
|
||||
if self.app.abort_flag:
|
||||
# graceful abort requested by the user
|
||||
|
||||
@@ -208,11 +208,10 @@ class ToolOptimal(AppTool):
|
||||
total_geo = MultiPolygon(total_geo)
|
||||
total_geo = total_geo.buffer(0)
|
||||
|
||||
try:
|
||||
__ = iter(total_geo)
|
||||
geo_len = len(total_geo)
|
||||
if isinstance(total_geo, MultiPolygon):
|
||||
geo_len = len(total_geo.geoms)
|
||||
geo_len = (geo_len * (geo_len - 1)) / 2
|
||||
except TypeError:
|
||||
else:
|
||||
app_obj.inform.emit('[ERROR_NOTCL] %s' %
|
||||
_("The Gerber object has one Polygon as geometry.\n"
|
||||
"There are no distances between geometry elements to be found."))
|
||||
|
||||
Reference in New Issue
Block a user