- NCC Plugin: modified the previous change and now the simplification action is much bigger reducing the number of coordinates by a factor of 20 (20 times less)

- Paint Plugin: same as above
- Ncc Plugin: added some more tooltips
- Isolation Plugin: fixed some issues when using the Rest Machining option
This commit is contained in:
Marius Stanciu
2023-06-17 22:30:17 +03:00
parent 5fe50dbcd1
commit 968fb1f943
6 changed files with 159 additions and 113 deletions

View File

@@ -2187,7 +2187,6 @@ class NonCopperClear(AppTool, Gerber):
steps_per_circle=self.circle_steps,
overlap=ncc_overlap, contour=ncc_contour,
connect=ncc_connect,
simplify_tol=simplify_tol,
prog_plot=prog_plot)
except grace:
return "fail"
@@ -2248,8 +2247,10 @@ class NonCopperClear(AppTool, Gerber):
self.app.log.error("NonCopperClear.clear_polygon_worker() Combo --> %s" % str(ee))
if cp and cp.objects:
ret_val = list(cp.get_objects())
return ret_val
if simplify_tol > 0.0:
return [x.simplify(simplify_tol) for x in cp.get_objects()]
else:
return [x for x in cp.get_objects()]
else:
pt = pol.representative_point()
coords = (pt.x, pt.y)
@@ -2285,9 +2286,9 @@ class NonCopperClear(AppTool, Gerber):
self.app.log.debug("Executing the clear_copper handler ...")
if run_threaded:
proc = self.app.proc_container.new('%s...' % _("Non-Copper Clearing"))
proc = self.app.proc_container.new('%s...' % _("Working"))
else:
self.app.proc_container.view.set_busy('%s...' % _("Non-Copper Clearing"))
self.app.proc_container.view.set_busy('%s...' % _("Working"))
QtWidgets.QApplication.processEvents()
# ######################################################################################################
@@ -2300,7 +2301,7 @@ class NonCopperClear(AppTool, Gerber):
rest_machining_choice = self.ui.ncc_rest_cb.get_value()
# TODO this should be in preferences and in the UI
simplification_value = 0.02
simplification_value = 0.01
# determine if to use the progressive plotting
prog_plot = True if self.app.options["tools_ncc_plotting"] == 'progressive' else False
@@ -2360,7 +2361,9 @@ class NonCopperClear(AppTool, Gerber):
bbox = self.apply_margin_to_bounding_box(bbox=bbox_geo, box_kind=bbox_kind,
ncc_select=ncc_select, ncc_margin=ncc_margin)
# ----------------------------------------------------
# COPPER CLEARING with tools marked for CLEAR#
# ----------------------------------------------------
for tool in sorted_clear_tools:
self.app.log.debug("Starting geometry processing for tool: %s" % str(tool))
if self.app.abort_flag:
@@ -2376,16 +2379,23 @@ class NonCopperClear(AppTool, Gerber):
)
app_obj.proc_container.update_view_text(' %d%%' % 0)
# ----------------------------------------------------
# store here the geometry generated by clear operation
# ----------------------------------------------------
cleared_geo = []
tool_uid = 0 # find the current tool_uid
# ----------------------------------------------------
# find the current tool_uid
# ----------------------------------------------------
tool_uid = 0
for k, v in self.ncc_tools.items():
if float('%.*f' % (self.decimals, v['tooldia'])) == float('%.*f' % (self.decimals, tool)):
tool_uid = int(k)
break
# ----------------------------------------------------
# parameters that are particular to the current tool
# ----------------------------------------------------
ncc_overlap = float(self.ncc_tools[tool_uid]["data"]["tools_ncc_overlap"]) / 100.0
ncc_method = self.ncc_tools[tool_uid]["data"]["tools_ncc_method"]
ncc_connect = self.ncc_tools[tool_uid]["data"]["tools_ncc_connect"]
@@ -2393,107 +2403,119 @@ class NonCopperClear(AppTool, Gerber):
has_offset = self.ncc_tools[tool_uid]["data"]["tools_ncc_offset_choice"]
ncc_offset = float(self.ncc_tools[tool_uid]["data"]["tools_ncc_offset_value"])
# ----------------------------------------------------
# Area to clear
# ----------------------------------------------------
result = self.get_tool_empty_area(name=name, ncc_obj=ncc_obj, geo_obj=geo_obj, isotooldia=isotd_list,
ncc_margin=ncc_margin, has_offset=has_offset, ncc_offset=ncc_offset,
tools_storage=tools_storage, bounding_box=bbox)
area, warning_flag = result
if area == "fail":
self.app.log.debug("Failed to create empty area for this tool.")
continue
# Transform area to MultiPolygon
if isinstance(area, Polygon):
area = MultiPolygon([area])
tool_empty_area = flatten_shapely_geometry(area)
if not tool_empty_area:
continue
# variables to display the percentage of work done
geo_len = len(area.geoms)
old_disp_number = 0
geo_len = len(tool_empty_area)
self.app.log.warning("Total number of polygons to be cleared. %s" % str(geo_len))
tool_empty_area = flatten_shapely_geometry(area.geoms)
# ----------------------------------------------------
# Copper-clear the Polygons in the non-copper-area
# Iterate over them
# ----------------------------------------------------
pol_nr = 0
for p in tool_empty_area:
# provide the app with a way to process the GUI events when in a blocking loop
if not run_threaded:
QtWidgets.QApplication.processEvents()
if tool_empty_area:
pol_nr = 0
for p in tool_empty_area:
if self.app.abort_flag:
# graceful abort requested by the user
raise grace
# ----------------------------------------------------
# attempt to fix possible problems with the polygon
# ----------------------------------------------------
p = p.buffer(0.0000001)
p = flatten_shapely_geometry(p, simplify_tolerance=simplification_value)
poly_failed = 0
for pol in p:
# provide the app with a way to process the GUI events when in a blocking loop
if not run_threaded:
QtWidgets.QApplication.processEvents()
QtWidgets.QApplication.processEvents()
if self.app.abort_flag:
# graceful abort requested by the user
raise grace
# clean the polygon
p = p.buffer(0.0000001)
p = flatten_shapely_geometry(p, simplify_tolerance=simplification_value)
poly_failed = 0
for pol in p:
# provide the app with a way to process the GUI events when in a blocking loop
QtWidgets.QApplication.processEvents()
if pol is not None and pol.is_valid and isinstance(pol, Polygon):
res = self.clear_polygon_worker(pol=pol, tooldia=tool,
ncc_method=ncc_method,
ncc_overlap=ncc_overlap,
ncc_connect=ncc_connect,
ncc_contour=ncc_contour,
simplify_tol=simplification_value,
prog_plot=prog_plot)
if res is not None:
cleared_geo += res
else:
poly_failed += 1
if pol is not None and pol.is_valid and isinstance(pol, Polygon):
# ----------------------------------------------------
# This is where copper clearing is happening
# ----------------------------------------------------
res = self.clear_polygon_worker(pol=pol, tooldia=tool,
ncc_method=ncc_method,
ncc_overlap=ncc_overlap,
ncc_connect=ncc_connect,
ncc_contour=ncc_contour,
simplify_tol=simplification_value,
prog_plot=prog_plot)
if res is not None:
cleared_geo += res
else:
self.app.log.warning(
"Expected geo is a Polygon. Instead got a %s" % str(type(pol)))
poly_failed += 1
else:
self.app.log.warning(
"Expected geo is a Polygon. Instead got a %s" % str(type(pol)))
pol_nr += 1
disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100]))
# log.debug("Polygons cleared: %d" % pol_nr)
pol_nr += 1
disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100]))
if old_disp_number < disp_number <= 100:
self.app.proc_container.update_view_text(' %d%%' % disp_number)
old_disp_number = disp_number
if old_disp_number < disp_number <= 100:
self.app.proc_container.update_view_text(' %d%%' % disp_number)
old_disp_number = disp_number
# log.debug("Polygons cleared: %d. Percentage done: %d%%" % (pol_nr, disp_number))
if poly_failed > 0:
app_obj.poly_not_cleared = True
if poly_failed > 0:
app_obj.poly_not_cleared = True
# ---------------------------------------------------------
# Debug message regarding how many points are in the result
# ---------------------------------------------------------
l_coords = 0
for i in range(len(cleared_geo)):
l_coords += len(cleared_geo[i].coords)
self.app.log.debug(
"NCC Tool.clear_copper.gen_clear_area() -> Number of cleared geo coords: %s" % str(l_coords))
l_coords = 0
for i in range(len(cleared_geo)):
l_coords += len(cleared_geo[i].coords)
self.app.log.debug(
"NCC Tool.clear_copper.gen_clear_area() -> Number of cleared geo coords: %s" % str(l_coords))
# -----------------------------------------------------------
# check if there is a geometry at all in the cleared geometry
# -----------------------------------------------------------
if cleared_geo:
formatted_tool = self.app.dec_format(tool, self.decimals)
# find the tooluid associated with the current tool_dia so we know where to add the tool
# solid_geometry
for k, v in tools_storage.items():
if self.app.dec_format(v['tooldia'], self.decimals) == formatted_tool:
current_uid = int(k)
# check if there is a geometry at all in the cleared geometry
if cleared_geo:
formatted_tool = self.app.dec_format(tool, self.decimals)
# find the tooluid associated with the current tool_dia so we know where to add the tool
# solid_geometry
for k, v in tools_storage.items():
if self.app.dec_format(v['tooldia'], self.decimals) == formatted_tool:
current_uid = int(k)
# add the solid_geometry to the current too in self.paint_tools dictionary
# and then reset the temporary list that stored that solid_geometry
v['solid_geometry'] = deepcopy(cleared_geo)
v['data']['name'] = name
geo_obj.tools[current_uid] = dict(tools_storage[current_uid])
break
else:
self.app.log.debug("There are no geometries in the cleared polygon.")
# add the solid_geometry to the current too in self.paint_tools dictionary
# and then reset the temporary list that stored that solid_geometry
v['solid_geometry'] = deepcopy(cleared_geo)
v['data']['name'] = name
geo_obj.tools[current_uid] = dict(tools_storage[current_uid])
break
else:
self.app.log.debug("There are no geometries in the cleared polygon.")
# ----------------------------------------------------
# clean the progressive plotted shapes if it was used
# ----------------------------------------------------
if self.app.options["tools_ncc_plotting"] == 'progressive':
self.temp_shapes.clear(update=True)
# ----------------------------------------------------
# delete tools with empty geometry
# look for keys in the tools_storage dict that have 'solid_geometry' values empty
# ----------------------------------------------------
for uid, uid_val in list(tools_storage.items()):
try:
# if the solid_geometry (type=list) is empty
@@ -2516,7 +2538,9 @@ class NonCopperClear(AppTool, Gerber):
geo_obj.multigeo = True
geo_obj.tools = dict(tools_storage)
# -------------------------------------------------------------------------------------------------
# test if at least one tool has solid_geometry. If no tool has solid_geometry we raise an Exception
# -------------------------------------------------------------------------------------------------
has_solid_geo = 0
for tid in geo_obj.tools:
if geo_obj.tools[tid]['solid_geometry']:
@@ -2528,8 +2552,10 @@ class NonCopperClear(AppTool, Gerber):
app_obj.inform.emit(msg)
return 'fail'
# ----------------------------------------------------------------
# check to see if geo_obj.tools is empty
# it will be updated only if there is a solid_geometry for tools
# ----------------------------------------------------------------
if geo_obj.tools:
if warning_flag == 0:
self.app.inform.emit('[success] %s' % _("NCC Tool clear all done."))
@@ -2889,9 +2915,9 @@ class NonCopperClear(AppTool, Gerber):
:return:
"""
if run_threaded:
proc = self.app.proc_container.new('%s...' % _("Non-Copper Clearing"))
proc = self.app.proc_container.new('%s...' % _("Working"))
else:
self.app.proc_container.view.set_busy('%s...' % _("Non-Copper Clearing"))
self.app.proc_container.view.set_busy('%s...' % _("Working"))
QtWidgets.QApplication.processEvents()
# #####################################################################