- made Progressive plotting work in Isolation Tool
- fix an issue with progressive plotted shapes not being deleted on the end of the job
This commit is contained in:
parent
aef1607fd5
commit
54407f6e50
|
@ -805,6 +805,9 @@ class ToolIsolation(AppTool, Gerber):
|
||||||
self.except_cb.set_value(False)
|
self.except_cb.set_value(False)
|
||||||
self.except_cb.hide()
|
self.except_cb.hide()
|
||||||
|
|
||||||
|
self.type_excobj_radio.hide()
|
||||||
|
self.exc_obj_combo.hide()
|
||||||
|
|
||||||
self.select_combo.setCurrentIndex(0)
|
self.select_combo.setCurrentIndex(0)
|
||||||
self.select_combo.hide()
|
self.select_combo.hide()
|
||||||
self.select_label.hide()
|
self.select_label.hide()
|
||||||
|
@ -1747,6 +1750,8 @@ class ToolIsolation(AppTool, Gerber):
|
||||||
lim_area=limited_area, plot=plot)
|
lim_area=limited_area, plot=plot)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
prog_plot = self.app.defaults["tools_iso_plotting"]
|
||||||
|
|
||||||
for tool in tools_storage:
|
for tool in tools_storage:
|
||||||
tool_data = tools_storage[tool]['data']
|
tool_data = tools_storage[tool]['data']
|
||||||
to_follow = tool_data['tools_iso_follow']
|
to_follow = tool_data['tools_iso_follow']
|
||||||
|
@ -1793,7 +1798,7 @@ class ToolIsolation(AppTool, Gerber):
|
||||||
mill_dir = 1 if milling_type == 'cl' else 0
|
mill_dir = 1 if milling_type == 'cl' else 0
|
||||||
|
|
||||||
iso_geo = self.generate_envelope(iso_offset, mill_dir, geometry=work_geo, env_iso_type=iso_t,
|
iso_geo = self.generate_envelope(iso_offset, mill_dir, geometry=work_geo, env_iso_type=iso_t,
|
||||||
follow=to_follow, nr_passes=i)
|
follow=to_follow, nr_passes=i, prog_plot=prog_plot)
|
||||||
if iso_geo == 'fail':
|
if iso_geo == 'fail':
|
||||||
self.app.inform.emit(
|
self.app.inform.emit(
|
||||||
'[ERROR_NOTCL] %s' % _("Isolation geometry could not be generated."))
|
'[ERROR_NOTCL] %s' % _("Isolation geometry could not be generated."))
|
||||||
|
@ -1865,11 +1870,17 @@ class ToolIsolation(AppTool, Gerber):
|
||||||
|
|
||||||
self.app.app_obj.new_object("geometry", iso_name, iso_init, plot=plot)
|
self.app.app_obj.new_object("geometry", iso_name, iso_init, plot=plot)
|
||||||
|
|
||||||
|
# clean the progressive plotted shapes if it was used
|
||||||
|
|
||||||
|
if prog_plot == 'progressive':
|
||||||
|
self.temp_shapes.clear(update=True)
|
||||||
|
|
||||||
# Switch notebook to Selected page
|
# Switch notebook to Selected page
|
||||||
self.app.ui.notebook.setCurrentWidget(self.app.ui.selected_tab)
|
self.app.ui.notebook.setCurrentWidget(self.app.ui.selected_tab)
|
||||||
|
|
||||||
def combined_rest(self, iso_obj, iso2geo, tools_storage, lim_area, plot=True):
|
def combined_rest(self, iso_obj, iso2geo, tools_storage, lim_area, plot=True):
|
||||||
"""
|
"""
|
||||||
|
Isolate the provided Gerber object using "rest machining" strategy
|
||||||
|
|
||||||
:param iso_obj: the isolated Gerber object
|
:param iso_obj: the isolated Gerber object
|
||||||
:type iso_obj: AppObjects.FlatCAMGerber.GerberObject
|
:type iso_obj: AppObjects.FlatCAMGerber.GerberObject
|
||||||
|
@ -1904,6 +1915,9 @@ class ToolIsolation(AppTool, Gerber):
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# decide to use "progressive" or "normal" plotting
|
||||||
|
prog_plot = self.app.defaults["tools_iso_plotting"]
|
||||||
|
|
||||||
for sorted_tool in sorted_tools:
|
for sorted_tool in sorted_tools:
|
||||||
for tool in tools_storage:
|
for tool in tools_storage:
|
||||||
if float('%.*f' % (self.decimals, tools_storage[tool]['tooldia'])) == sorted_tool:
|
if float('%.*f' % (self.decimals, tools_storage[tool]['tooldia'])) == sorted_tool:
|
||||||
|
@ -1942,7 +1956,8 @@ class ToolIsolation(AppTool, Gerber):
|
||||||
|
|
||||||
solid_geo, work_geo = self.generate_rest_geometry(geometry=work_geo, tooldia=tool_dia,
|
solid_geo, work_geo = self.generate_rest_geometry(geometry=work_geo, tooldia=tool_dia,
|
||||||
passes=passes, overlap=overlap, invert=mill_dir,
|
passes=passes, overlap=overlap, invert=mill_dir,
|
||||||
env_iso_type=iso_t)
|
env_iso_type=iso_t, prog_plot=prog_plot,
|
||||||
|
prog_plot_handler=self.plot_temp_shapes)
|
||||||
|
|
||||||
# ############################################################
|
# ############################################################
|
||||||
# ########## AREA SUBTRACTION ################################
|
# ########## AREA SUBTRACTION ################################
|
||||||
|
@ -1973,6 +1988,10 @@ class ToolIsolation(AppTool, Gerber):
|
||||||
if not work_geo:
|
if not work_geo:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
# clean the progressive plotted shapes if it was used
|
||||||
|
if self.app.defaults["tools_iso_plotting"] == 'progressive':
|
||||||
|
self.temp_shapes.clear(update=True)
|
||||||
|
|
||||||
def iso_init(geo_obj, app_obj):
|
def iso_init(geo_obj, app_obj):
|
||||||
geo_obj.options["cnctooldia"] = str(tool_dia)
|
geo_obj.options["cnctooldia"] = str(tool_dia)
|
||||||
|
|
||||||
|
@ -2052,6 +2071,7 @@ class ToolIsolation(AppTool, Gerber):
|
||||||
|
|
||||||
iso_name = iso_obj.options["name"] + '_iso_combined'
|
iso_name = iso_obj.options["name"] + '_iso_combined'
|
||||||
geometry = iso2geo
|
geometry = iso2geo
|
||||||
|
prog_plot = self.app.defaults["tools_iso_plotting"]
|
||||||
|
|
||||||
for tool in tools_storage:
|
for tool in tools_storage:
|
||||||
tool_dia = tools_storage[tool]['tooldia']
|
tool_dia = tools_storage[tool]['tooldia']
|
||||||
|
@ -2100,7 +2120,7 @@ class ToolIsolation(AppTool, Gerber):
|
||||||
mill_dir = 1 if milling_type == 'cl' else 0
|
mill_dir = 1 if milling_type == 'cl' else 0
|
||||||
|
|
||||||
iso_geo = self.generate_envelope(iso_offset, mill_dir, geometry=work_geo, env_iso_type=iso_t,
|
iso_geo = self.generate_envelope(iso_offset, mill_dir, geometry=work_geo, env_iso_type=iso_t,
|
||||||
follow=to_follow, nr_passes=nr_pass)
|
follow=to_follow, nr_passes=nr_pass, prog_plot=prog_plot)
|
||||||
if iso_geo == 'fail':
|
if iso_geo == 'fail':
|
||||||
self.app.inform.emit('[ERROR_NOTCL] %s' % _("Isolation geometry could not be generated."))
|
self.app.inform.emit('[ERROR_NOTCL] %s' % _("Isolation geometry could not be generated."))
|
||||||
continue
|
continue
|
||||||
|
@ -2135,6 +2155,10 @@ class ToolIsolation(AppTool, Gerber):
|
||||||
|
|
||||||
total_solid_geometry += solid_geo
|
total_solid_geometry += solid_geo
|
||||||
|
|
||||||
|
# clean the progressive plotted shapes if it was used
|
||||||
|
if prog_plot == 'progressive':
|
||||||
|
self.temp_shapes.clear(update=True)
|
||||||
|
|
||||||
def iso_init(geo_obj, app_obj):
|
def iso_init(geo_obj, app_obj):
|
||||||
geo_obj.options["cnctooldia"] = str(tool_dia)
|
geo_obj.options["cnctooldia"] = str(tool_dia)
|
||||||
|
|
||||||
|
@ -2709,7 +2733,8 @@ class ToolIsolation(AppTool, Gerber):
|
||||||
def poly2ints(poly):
|
def poly2ints(poly):
|
||||||
return [interior for interior in poly.interiors]
|
return [interior for interior in poly.interiors]
|
||||||
|
|
||||||
def generate_envelope(self, offset, invert, geometry=None, env_iso_type=2, follow=None, nr_passes=0):
|
def generate_envelope(self, offset, invert, geometry=None, env_iso_type=2, follow=None, nr_passes=0,
|
||||||
|
prog_plot=False):
|
||||||
"""
|
"""
|
||||||
Isolation_geometry produces an envelope that is going on the left of the geometry
|
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 copper features). To leave the least amount of burrs on the features
|
||||||
|
@ -2730,17 +2755,19 @@ class ToolIsolation(AppTool, Gerber):
|
||||||
:type follow: bool
|
:type follow: bool
|
||||||
:param nr_passes: Number of passes
|
:param nr_passes: Number of passes
|
||||||
:type nr_passes: int
|
:type nr_passes: int
|
||||||
|
:param prog_plot: Type of plotting: "normal" or "progressive"
|
||||||
|
:type prog_plot: str
|
||||||
:return: The buffered geometry
|
:return: The buffered geometry
|
||||||
:rtype: MultiPolygon or Polygon
|
:rtype: MultiPolygon or Polygon
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if follow:
|
if follow:
|
||||||
geom = self.grb_obj.isolation_geometry(offset, geometry=geometry, follow=follow)
|
geom = self.grb_obj.isolation_geometry(offset, geometry=geometry, follow=follow, prog_plot=prog_plot)
|
||||||
return geom
|
return geom
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
geom = self.grb_obj.isolation_geometry(offset, geometry=geometry, iso_type=env_iso_type,
|
geom = self.grb_obj.isolation_geometry(offset, geometry=geometry, iso_type=env_iso_type,
|
||||||
passes=nr_passes)
|
passes=nr_passes, prog_plot=prog_plot)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.debug('ToolIsolation.generate_envelope() --> %s' % str(e))
|
log.debug('ToolIsolation.generate_envelope() --> %s' % str(e))
|
||||||
return 'fail'
|
return 'fail'
|
||||||
|
@ -2769,7 +2796,8 @@ class ToolIsolation(AppTool, Gerber):
|
||||||
return geom
|
return geom
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def generate_rest_geometry(geometry, tooldia, passes, overlap, invert, env_iso_type=2):
|
def generate_rest_geometry(geometry, tooldia, passes, overlap, invert, env_iso_type=2,
|
||||||
|
prog_plot="normal", prog_plot_handler=None):
|
||||||
"""
|
"""
|
||||||
Will try to isolate the geometry and return a tuple made of list of paths made through isolation
|
Will try to isolate the geometry and return a tuple made of list of paths made through isolation
|
||||||
and a list of Shapely Polygons that could not be isolated
|
and a list of Shapely Polygons that could not be isolated
|
||||||
|
@ -2786,6 +2814,10 @@ class ToolIsolation(AppTool, Gerber):
|
||||||
:type invert: bool
|
:type invert: bool
|
||||||
:param env_iso_type: can be either 0 = keep exteriors or 1 = keep interiors or 2 = keep all paths
|
:param env_iso_type: can be either 0 = keep exteriors or 1 = keep interiors or 2 = keep all paths
|
||||||
:type env_iso_type: int
|
:type env_iso_type: int
|
||||||
|
:param prog_plot: kind of plotting: "progressive" or "normal"
|
||||||
|
:type prog_plot: str
|
||||||
|
:param prog_plot_handler: method used to plot shapes if plot_prog is "proggressive"
|
||||||
|
:type prog_plot_handler:
|
||||||
:return: Tuple made from list of isolating paths and list of not isolated Polygons
|
:return: Tuple made from list of isolating paths and list of not isolated Polygons
|
||||||
:rtype: tuple
|
:rtype: tuple
|
||||||
"""
|
"""
|
||||||
|
@ -2819,7 +2851,10 @@ class ToolIsolation(AppTool, Gerber):
|
||||||
|
|
||||||
# if we had an intersection do nothing, else add the geo to the good pass isolations
|
# if we had an intersection do nothing, else add the geo to the good pass isolations
|
||||||
if intersect_flag is False:
|
if intersect_flag is False:
|
||||||
good_pass_iso.append(geo.buffer(iso_offset))
|
temp_geo = geo.buffer(iso_offset)
|
||||||
|
good_pass_iso.append(temp_geo)
|
||||||
|
if prog_plot == 'progressive':
|
||||||
|
prog_plot_handler(temp_geo)
|
||||||
|
|
||||||
if good_pass_iso:
|
if good_pass_iso:
|
||||||
work_geo += good_pass_iso
|
work_geo += good_pass_iso
|
||||||
|
|
|
@ -23,6 +23,8 @@ CHANGELOG for FlatCAM beta
|
||||||
- after using Isolation Tool it will switch automatically to the Geometry UI
|
- after using Isolation Tool it will switch automatically to the Geometry UI
|
||||||
- in Preferences replaced some widgets with a new one that combine a Slider with a Spinner (from David Robertson)
|
- in Preferences replaced some widgets with a new one that combine a Slider with a Spinner (from David Robertson)
|
||||||
- in Preferences replaced the widgets that sets colors with a compound one (from David Robertson)
|
- in Preferences replaced the widgets that sets colors with a compound one (from David Robertson)
|
||||||
|
- made Progressive plotting work in Isolation Tool
|
||||||
|
- fix an issue with progressive plotted shapes not being deleted on the end of the job
|
||||||
|
|
||||||
31.05.2020
|
31.05.2020
|
||||||
|
|
||||||
|
|
31
camlib.py
31
camlib.py
|
@ -499,7 +499,7 @@ class Geometry(object):
|
||||||
self.el_count = 0
|
self.el_count = 0
|
||||||
|
|
||||||
if self.app.is_legacy is False:
|
if self.app.is_legacy is False:
|
||||||
self.temp_shapes = self.app.plotcanvas.new_shape_group()
|
self.temp_shapes = self.app.plotcanvas.new_shape_collection(layers=1)
|
||||||
else:
|
else:
|
||||||
from AppGUI.PlotCanvasLegacy import ShapeCollectionLegacy
|
from AppGUI.PlotCanvasLegacy import ShapeCollectionLegacy
|
||||||
self.temp_shapes = ShapeCollectionLegacy(obj=self, app=self.app, name='camlib.geometry')
|
self.temp_shapes = ShapeCollectionLegacy(obj=self, app=self.app, name='camlib.geometry')
|
||||||
|
@ -915,7 +915,8 @@ class Geometry(object):
|
||||||
#
|
#
|
||||||
# return self.flat_geometry, self.flat_geometry_rtree
|
# return self.flat_geometry, self.flat_geometry_rtree
|
||||||
|
|
||||||
def isolation_geometry(self, offset, geometry=None, iso_type=2, corner=None, follow=None, passes=0):
|
def isolation_geometry(self, offset, geometry=None, iso_type=2, corner=None, follow=None, passes=0,
|
||||||
|
prog_plot=False):
|
||||||
"""
|
"""
|
||||||
Creates contours around geometry at a given
|
Creates contours around geometry at a given
|
||||||
offset distance.
|
offset distance.
|
||||||
|
@ -928,6 +929,7 @@ class Geometry(object):
|
||||||
0 = round; 1 = square; 2= beveled (line that connects the ends)
|
0 = round; 1 = square; 2= beveled (line that connects the ends)
|
||||||
:param follow: whether the geometry to be isolated is a follow_geometry
|
:param follow: whether the geometry to be isolated is a follow_geometry
|
||||||
:param passes: current pass out of possible multiple passes for which the isolation is done
|
:param passes: current pass out of possible multiple passes for which the isolation is done
|
||||||
|
:param prog_plot: type of plotting: "normal" or "progressive"
|
||||||
:return: The buffered geometry.
|
:return: The buffered geometry.
|
||||||
:rtype: Shapely.MultiPolygon or Shapely.Polygon
|
:rtype: Shapely.MultiPolygon or Shapely.Polygon
|
||||||
"""
|
"""
|
||||||
|
@ -960,10 +962,13 @@ class Geometry(object):
|
||||||
# graceful abort requested by the user
|
# graceful abort requested by the user
|
||||||
raise grace
|
raise grace
|
||||||
if offset == 0:
|
if offset == 0:
|
||||||
geo_iso.append(pol)
|
temp_geo = pol
|
||||||
else:
|
else:
|
||||||
corner_type = 1 if corner is None else corner
|
corner_type = 1 if corner is None else corner
|
||||||
geo_iso.append(pol.buffer(offset, int(self.geo_steps_per_circle), join_style=corner_type))
|
temp_geo = pol.buffer(offset, int(self.geo_steps_per_circle), join_style=corner_type)
|
||||||
|
|
||||||
|
geo_iso.append(temp_geo)
|
||||||
|
|
||||||
pol_nr += 1
|
pol_nr += 1
|
||||||
|
|
||||||
# activity view update
|
# activity view update
|
||||||
|
@ -977,10 +982,12 @@ class Geometry(object):
|
||||||
# taking care of the case when the self.solid_geometry is just a single Polygon, not a list or a
|
# taking care of the case when the self.solid_geometry is just a single Polygon, not a list or a
|
||||||
# MultiPolygon (not an iterable)
|
# MultiPolygon (not an iterable)
|
||||||
if offset == 0:
|
if offset == 0:
|
||||||
geo_iso.append(working_geo)
|
temp_geo = working_geo
|
||||||
else:
|
else:
|
||||||
corner_type = 1 if corner is None else corner
|
corner_type = 1 if corner is None else corner
|
||||||
geo_iso.append(working_geo.buffer(offset, int(self.geo_steps_per_circle), join_style=corner_type))
|
temp_geo = working_geo.buffer(offset, int(self.geo_steps_per_circle), join_style=corner_type)
|
||||||
|
|
||||||
|
geo_iso.append(temp_geo)
|
||||||
|
|
||||||
self.app.proc_container.update_view_text(' %s' % _("Buffering"))
|
self.app.proc_container.update_view_text(' %s' % _("Buffering"))
|
||||||
geo_iso = unary_union(geo_iso)
|
geo_iso = unary_union(geo_iso)
|
||||||
|
@ -989,17 +996,23 @@ class Geometry(object):
|
||||||
# end of replaced block
|
# end of replaced block
|
||||||
|
|
||||||
if iso_type == 2:
|
if iso_type == 2:
|
||||||
return geo_iso
|
ret_geo = geo_iso
|
||||||
elif iso_type == 0:
|
elif iso_type == 0:
|
||||||
self.app.proc_container.update_view_text(' %s' % _("Get Exteriors"))
|
self.app.proc_container.update_view_text(' %s' % _("Get Exteriors"))
|
||||||
return self.get_exteriors(geo_iso)
|
ret_geo = self.get_exteriors(geo_iso)
|
||||||
elif iso_type == 1:
|
elif iso_type == 1:
|
||||||
self.app.proc_container.update_view_text(' %s' % _("Get Interiors"))
|
self.app.proc_container.update_view_text(' %s' % _("Get Interiors"))
|
||||||
return self.get_interiors(geo_iso)
|
ret_geo = self.get_interiors(geo_iso)
|
||||||
else:
|
else:
|
||||||
log.debug("Geometry.isolation_geometry() --> Type of isolation not supported")
|
log.debug("Geometry.isolation_geometry() --> Type of isolation not supported")
|
||||||
return "fail"
|
return "fail"
|
||||||
|
|
||||||
|
if prog_plot == 'progressive':
|
||||||
|
for elem in ret_geo:
|
||||||
|
self.plot_temp_shapes(elem)
|
||||||
|
|
||||||
|
return ret_geo
|
||||||
|
|
||||||
def flatten_list(self, obj_list):
|
def flatten_list(self, obj_list):
|
||||||
for item in obj_list:
|
for item in obj_list:
|
||||||
if isinstance(item, Iterable) and not isinstance(item, (str, bytes)):
|
if isinstance(item, Iterable) and not isinstance(item, (str, bytes)):
|
||||||
|
|
Loading…
Reference in New Issue