- made some optimizations in FlatCAMGerber.isolate() method
This commit is contained in:
parent
2fe08cf990
commit
b31d016b13
203
FlatCAMObj.py
203
FlatCAMObj.py
|
@ -1148,97 +1148,6 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
|||
|
||||
base_name = self.options["name"]
|
||||
|
||||
def generate_envelope(offset, invert, geometry=None, env_iso_type=2, follow=None, nr_passes=0):
|
||||
# isolation_geometry produces an envelope that is going on the left of the geometry
|
||||
# (the copper features). To leave the least amount of burrs on the features
|
||||
# the tool needs to travel on the right side of the features (this is called conventional milling)
|
||||
# the first pass is the one cutting all of the features, so it needs to be reversed
|
||||
# the other passes overlap preceding ones and cut the left over copper. It is better for them
|
||||
# to cut on the right side of the left over copper i.e on the left side of the features.
|
||||
|
||||
if follow:
|
||||
geom = self.isolation_geometry(offset, geometry=geometry, follow=follow)
|
||||
else:
|
||||
try:
|
||||
geom = self.isolation_geometry(offset, geometry=geometry, iso_type=env_iso_type, passes=nr_passes)
|
||||
except Exception as e:
|
||||
log.debug('FlatCAMGerber.isolate().generate_envelope() --> %s' % str(e))
|
||||
return 'fail'
|
||||
|
||||
if invert:
|
||||
try:
|
||||
pl = []
|
||||
for p in geom:
|
||||
if p is not None:
|
||||
if isinstance(p, Polygon):
|
||||
pl.append(Polygon(p.exterior.coords[::-1], p.interiors))
|
||||
elif isinstance(p, LinearRing):
|
||||
pl.append(Polygon(p.coords[::-1]))
|
||||
geom = MultiPolygon(pl)
|
||||
except TypeError:
|
||||
if isinstance(geom, Polygon) and geom is not None:
|
||||
geom = Polygon(geom.exterior.coords[::-1], geom.interiors)
|
||||
elif isinstance(geom, LinearRing) and geom is not None:
|
||||
geom = Polygon(geom.coords[::-1])
|
||||
else:
|
||||
log.debug("FlatCAMGerber.isolate().generate_envelope() Error --> Unexpected Geometry %s" %
|
||||
type(geom))
|
||||
except Exception as e:
|
||||
log.debug("FlatCAMGerber.isolate().generate_envelope() Error --> %s" % str(e))
|
||||
return 'fail'
|
||||
return geom
|
||||
|
||||
# if float(self.options["isotooldia"]) < 0:
|
||||
# self.options["isotooldia"] = -self.options["isotooldia"]
|
||||
|
||||
def area_subtraction(geo):
|
||||
new_geometry = []
|
||||
|
||||
name = self.ui.obj_combo.currentText()
|
||||
subtractor_obj = self.app.collection.get_by_name(name)
|
||||
sub_union = cascaded_union(subtractor_obj.solid_geometry)
|
||||
|
||||
try:
|
||||
for geo_elem in geo:
|
||||
if isinstance(geo_elem, Polygon):
|
||||
for ring in self.poly2rings(geo_elem):
|
||||
new_geo = ring.difference(sub_union)
|
||||
if new_geo and not new_geo.is_empty:
|
||||
new_geometry.append(new_geo)
|
||||
elif isinstance(geo_elem, MultiPolygon):
|
||||
for poly in geo_elem:
|
||||
for ring in self.poly2rings(poly):
|
||||
new_geo = ring.difference(sub_union)
|
||||
if new_geo and not new_geo.is_empty:
|
||||
new_geometry.append(new_geo)
|
||||
elif isinstance(geo_elem, LineString):
|
||||
new_geo = geo_elem.difference(sub_union)
|
||||
if new_geo:
|
||||
if not new_geo.is_empty:
|
||||
new_geometry.append(new_geo)
|
||||
elif isinstance(geo_elem, MultiLineString):
|
||||
for line_elem in geo_elem:
|
||||
new_geo = line_elem.difference(sub_union)
|
||||
if new_geo and not new_geo.is_empty:
|
||||
new_geometry.append(new_geo)
|
||||
except TypeError:
|
||||
if isinstance(geo, Polygon):
|
||||
for ring in self.poly2rings(geo):
|
||||
new_geo = ring.difference(sub_union)
|
||||
if new_geo:
|
||||
if not new_geo.is_empty:
|
||||
new_geometry.append(new_geo)
|
||||
elif isinstance(geo, LineString):
|
||||
new_geo = geo.difference(sub_union)
|
||||
if new_geo and not new_geo.is_empty:
|
||||
new_geometry.append(new_geo)
|
||||
elif isinstance(geo, MultiLineString):
|
||||
for line_elem in geo:
|
||||
new_geo = line_elem.difference(sub_union)
|
||||
if new_geo and not new_geo.is_empty:
|
||||
new_geometry.append(new_geo)
|
||||
return new_geometry
|
||||
|
||||
if combine:
|
||||
if outname is None:
|
||||
if self.iso_type == 0:
|
||||
|
@ -1260,8 +1169,8 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
|||
|
||||
# if milling type is climb then the move is counter-clockwise around features
|
||||
mill_t = 1 if milling_type == 'cl' else 0
|
||||
geom = generate_envelope(iso_offset, mill_t, geometry=work_geo, env_iso_type=iso_t, follow=follow,
|
||||
nr_passes=i)
|
||||
geom = self.generate_envelope(iso_offset, mill_t, geometry=work_geo, env_iso_type=iso_t,
|
||||
follow=follow, nr_passes=i)
|
||||
|
||||
if geom == 'fail':
|
||||
app_obj.inform.emit('[ERROR_NOTCL] %s' % _("Isolation geometry could not be generated."))
|
||||
|
@ -1349,7 +1258,7 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
|||
# ############################################################
|
||||
if self.ui.except_cb.get_value():
|
||||
self.app.proc_container.update_view_text(' %s' % _("Subtracting Geo"))
|
||||
geo_obj.solid_geometry = area_subtraction(geo_obj.solid_geometry)
|
||||
geo_obj.solid_geometry = self.area_subtraction(geo_obj.solid_geometry)
|
||||
|
||||
# TODO: Do something if this is None. Offer changing name?
|
||||
self.app.new_object("geometry", iso_name, iso_init, plot=plot)
|
||||
|
@ -1386,8 +1295,9 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
|||
# if milling type is climb then the move is counter-clockwise around features
|
||||
mill_t = 1 if milling_type == 'cl' else 0
|
||||
mill_t = 1 if milling_type == 'cl' else 0
|
||||
geom = generate_envelope(offset, mill_t, geometry=work_geo, env_iso_type=iso_t, follow=follow,
|
||||
nr_passes=i)
|
||||
geom = self.generate_envelope(offset, mill_t, geometry=work_geo, env_iso_type=iso_t,
|
||||
follow=follow,
|
||||
nr_passes=i)
|
||||
|
||||
if geom == 'fail':
|
||||
app_obj.inform.emit('[ERROR_NOTCL] %s' %
|
||||
|
@ -1422,11 +1332,110 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
|||
# ############################################################
|
||||
if self.ui.except_cb.get_value():
|
||||
self.app.proc_container.update_view_text(' %s' % _("Subtracting Geo"))
|
||||
geo_obj.solid_geometry = area_subtraction(geo_obj.solid_geometry)
|
||||
geo_obj.solid_geometry = self.area_subtraction(geo_obj.solid_geometry)
|
||||
|
||||
# TODO: Do something if this is None. Offer changing name?
|
||||
self.app.new_object("geometry", iso_name, iso_init, plot=plot)
|
||||
|
||||
def generate_envelope(self, offset, invert, geometry=None, env_iso_type=2, follow=None, nr_passes=0):
|
||||
# isolation_geometry produces an envelope that is going on the left of the geometry
|
||||
# (the copper features). To leave the least amount of burrs on the features
|
||||
# the tool needs to travel on the right side of the features (this is called conventional milling)
|
||||
# the first pass is the one cutting all of the features, so it needs to be reversed
|
||||
# the other passes overlap preceding ones and cut the left over copper. It is better for them
|
||||
# to cut on the right side of the left over copper i.e on the left side of the features.
|
||||
|
||||
if follow:
|
||||
geom = self.isolation_geometry(offset, geometry=geometry, follow=follow)
|
||||
else:
|
||||
try:
|
||||
geom = self.isolation_geometry(offset, geometry=geometry, iso_type=env_iso_type, passes=nr_passes)
|
||||
except Exception as e:
|
||||
log.debug('FlatCAMGerber.isolate().generate_envelope() --> %s' % str(e))
|
||||
return 'fail'
|
||||
|
||||
if invert:
|
||||
try:
|
||||
pl = []
|
||||
for p in geom:
|
||||
if p is not None:
|
||||
if isinstance(p, Polygon):
|
||||
pl.append(Polygon(p.exterior.coords[::-1], p.interiors))
|
||||
elif isinstance(p, LinearRing):
|
||||
pl.append(Polygon(p.coords[::-1]))
|
||||
geom = MultiPolygon(pl)
|
||||
except TypeError:
|
||||
if isinstance(geom, Polygon) and geom is not None:
|
||||
geom = Polygon(geom.exterior.coords[::-1], geom.interiors)
|
||||
elif isinstance(geom, LinearRing) and geom is not None:
|
||||
geom = Polygon(geom.coords[::-1])
|
||||
else:
|
||||
log.debug("FlatCAMGerber.isolate().generate_envelope() Error --> Unexpected Geometry %s" %
|
||||
type(geom))
|
||||
except Exception as e:
|
||||
log.debug("FlatCAMGerber.isolate().generate_envelope() Error --> %s" % str(e))
|
||||
return 'fail'
|
||||
return geom
|
||||
|
||||
def area_subtraction(self, geo, subtractor_geo=None):
|
||||
"""
|
||||
Subtracts the subtractor_geo (if present else self.solid_geometry) from the geo
|
||||
|
||||
:param geo: target geometry from which to subtract
|
||||
:param subtractor_geo: geometry that acts as subtractor
|
||||
:return:
|
||||
"""
|
||||
new_geometry = []
|
||||
target_geo = geo
|
||||
|
||||
if subtractor_geo:
|
||||
sub_union = cascaded_union(subtractor_geo)
|
||||
else:
|
||||
name = self.ui.obj_combo.currentText()
|
||||
subtractor_obj = self.app.collection.get_by_name(name)
|
||||
sub_union = cascaded_union(subtractor_obj.solid_geometry)
|
||||
|
||||
try:
|
||||
for geo_elem in target_geo:
|
||||
if isinstance(geo_elem, Polygon):
|
||||
for ring in self.poly2rings(geo_elem):
|
||||
new_geo = ring.difference(sub_union)
|
||||
if new_geo and not new_geo.is_empty:
|
||||
new_geometry.append(new_geo)
|
||||
elif isinstance(geo_elem, MultiPolygon):
|
||||
for poly in geo_elem:
|
||||
for ring in self.poly2rings(poly):
|
||||
new_geo = ring.difference(sub_union)
|
||||
if new_geo and not new_geo.is_empty:
|
||||
new_geometry.append(new_geo)
|
||||
elif isinstance(geo_elem, LineString):
|
||||
new_geo = geo_elem.difference(sub_union)
|
||||
if new_geo:
|
||||
if not new_geo.is_empty:
|
||||
new_geometry.append(new_geo)
|
||||
elif isinstance(geo_elem, MultiLineString):
|
||||
for line_elem in geo_elem:
|
||||
new_geo = line_elem.difference(sub_union)
|
||||
if new_geo and not new_geo.is_empty:
|
||||
new_geometry.append(new_geo)
|
||||
except TypeError:
|
||||
if isinstance(target_geo, Polygon):
|
||||
for ring in self.poly2rings(target_geo):
|
||||
new_geo = ring.difference(sub_union)
|
||||
if new_geo:
|
||||
if not new_geo.is_empty:
|
||||
new_geometry.append(new_geo)
|
||||
elif isinstance(target_geo, LineString):
|
||||
new_geo = target_geo.difference(sub_union)
|
||||
if new_geo and not new_geo.is_empty:
|
||||
new_geometry.append(new_geo)
|
||||
elif isinstance(target_geo, MultiLineString):
|
||||
for line_elem in target_geo:
|
||||
new_geo = line_elem.difference(sub_union)
|
||||
if new_geo and not new_geo.is_empty:
|
||||
new_geometry.append(new_geo)
|
||||
return new_geometry
|
||||
|
||||
def on_plot_cb_click(self, *args):
|
||||
if self.muted_ui:
|
||||
return
|
||||
|
|
Loading…
Reference in New Issue