- in Preferences, more Plugins preferences UI is upgraded to the new look

- In Paint Plugin fixed the Area select mode to work with Geometry object created by the Geometry Editor
- in Paint Plugin some changes in the way the source object is autoloaded
- in Paint, NCC and Cutout Plugins when using a mode that require to be terminated (by mouse RMB or ESC key) the notebook UI element is disabled until this is done
This commit is contained in:
Marius Stanciu
2021-10-02 18:02:27 +03:00
committed by Marius
parent a1530963f5
commit bc2f31aa90
13 changed files with 380 additions and 283 deletions

View File

@@ -1512,8 +1512,11 @@ class CutOut(AppTool):
int_list = []
for b_geo in buff_man_geo.geoms:
int_list += b_geo.interiors
else:
elif isinstance(buff_man_geo, Polygon):
int_list = buff_man_geo.interiors
else:
self.app.log.debug("Not supported geometry at the moment: %s" % type(buff_man_geo))
return
self.mb_manual_solid_geo = self.flatten(int_list)
self.cutting_gapsize = self.ui.gapsize.get_value()
@@ -1547,7 +1550,10 @@ class CutOut(AppTool):
if self.ui.big_cursor_cb.get_value():
self.old_cursor_type = self.app.defaults["global_cursor_type"]
self.app.on_cursor_type(val="big")
self.app.defaults['global_selection_shape'] = False
# disable the notebook until finished
self.app.ui.notebook.setDisabled(True)
def on_manual_cutout(self, click_pos):
@@ -1833,6 +1839,7 @@ class CutOut(AppTool):
self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
self.app.ui.notebook.setDisabled(False)
self.app.inform.emit('[success] %s' % _("Finished manual adding of gaps."))
def on_mouse_move(self, event):
@@ -1903,32 +1910,24 @@ class CutOut(AppTool):
angle = 0
return angle
r_man_geo = man_geo.geoms if isinstance(man_geo, (MultiPolygon, MultiLineString)) else man_geo
try:
rot_angle = 0
for geo_el in man_geo:
for geo_el in r_man_geo:
if isinstance(geo_el, Polygon):
work_geo = geo_el.exterior
if cut_geo.intersects(work_geo):
rot_angle = get_angle(geo=work_geo)
else:
rot_angle = 0
rot_angle = get_angle(geo=work_geo) if cut_geo.intersects(work_geo) else 0
else:
rot_angle = 0
if cut_geo.intersects(geo_el):
rot_angle = get_angle(geo=geo_el)
rot_angle = get_angle(geo=geo_el) if cut_geo.intersects(geo_el) else 0
if rot_angle != 0:
break
except TypeError:
if isinstance(man_geo, Polygon):
work_geo = man_geo.exterior
if cut_geo.intersects(work_geo):
rot_angle = get_angle(geo=work_geo)
else:
rot_angle = 0
if isinstance(r_man_geo, Polygon):
work_geo = r_man_geo.exterior
rot_angle = get_angle(geo=work_geo) if cut_geo.intersects(work_geo) else 0
else:
rot_angle = 0
if cut_geo.intersects(man_geo):
rot_angle = get_angle(geo=man_geo)
rot_angle = get_angle(geo=r_man_geo) if cut_geo.intersects(r_man_geo) else 0
# rotate only if there is an angle to rotate to
if rot_angle != 0:
@@ -2008,6 +2007,10 @@ class CutOut(AppTool):
self.app.geo_editor.tool_shape.clear(update=True)
self.app.geo_editor.tool_shape.enabled = False
# restore the notebook state
self.app.ui.notebook.setDisabled(False)
self.app.inform.emit("[WARNING_NOTCL] %s" % _("Cancelled."))
# Grid toggle
if key == QtCore.Qt.Key.Key_G or key == 'G':
self.app.ui.grid_snap_btn.trigger()

View File

@@ -366,51 +366,6 @@ class NonCopperClear(AppTool, Gerber):
if option.find('tools_') == 0:
self.default_data[option] = self.app.options[option]
# self.default_data = {
# "name": '_ncc',
# "plot": self.app.defaults["geometry_plot"],
# "cutz": float(self.app.defaults["geometry_cutz"]),
# "vtipdia": float(self.app.defaults["tools_mill_vtipdia"]),
# "vtipangle": float(self.app.defaults["tools_mill_vtipangle"]),
# "travelz": self.app.defaults["geometry_travelz"],
# "feedrate": self.app.defaults["geometry_feedrate"],
# "feedrate_z": self.app.defaults["geometry_feedrate_z"],
# "feedrate_rapid": self.app.defaults["geometry_feedrate_rapid"],
# "dwell": self.app.defaults["geometry_dwell"],
# "dwelltime": self.app.defaults["geometry_dwelltime"],
# "multidepth": self.app.defaults["geometry_multidepth"],
# "ppname_g": self.app.defaults["geometry_ppname_g"],
# "depthperpass": self.app.defaults["geometry_depthperpass"],
# "extracut": self.app.defaults["geometry_extracut"],
# "extracut_length": self.app.defaults["geometry_extracut_length"],
# "toolchange": self.app.defaults["geometry_toolchange"],
# "toolchangez": self.app.defaults["geometry_toolchangez"],
# "endz": self.app.defaults["geometry_endz"],
# "endxy": self.app.defaults["geometry_endxy"],
#
# "spindlespeed": self.app.defaults["geometry_spindlespeed"],
# "toolchangexy": self.app.defaults["geometry_toolchangexy"],
# "startz": self.app.defaults["geometry_startz"],
#
# "area_exclusion": self.app.defaults["geometry_area_exclusion"],
# "area_shape": self.app.defaults["geometry_area_shape"],
# "area_strategy": self.app.defaults["geometry_area_strategy"],
# "area_overz": float(self.app.defaults["geometry_area_overz"]),
# "optimization_type": self.app.defaults["geometry_optimization_type"],
#
# "tools_ncc_operation": self.app.defaults["tools_ncc_operation"],
# "tools_ncc_margin": self.app.defaults["tools_ncc_margin"],
# "tools_ncc_method": self.app.defaults["tools_ncc_method"],
# "tools_ncc_connect": self.app.defaults["tools_ncc_connect"],
# "tools_ncc_contour": self.app.defaults["tools_ncc_contour"],
# "tools_ncc_overlap": self.app.defaults["tools_ncc_overlap"],
# "tools_ncc_rest": self.app.defaults["tools_ncc_rest"],
# "tools_ncc_ref": self.app.defaults["tools_ncc_ref"],
# "tools_ncc_offset_choice": self.app.defaults["tools_ncc_offset_choice"],
# "tools_ncc_offset_value": self.app.defaults["tools_ncc_offset_value"],
# "tools_ncc_milling_type": self.app.defaults["tools_ncc_milling_type"],
# "tools_ncc_check_valid": self.app.defaults["tools_ncc_check_valid"],
# }
try:
dias = [float(self.app.defaults["tools_ncc_tools"])]
@@ -1643,6 +1598,8 @@ class NonCopperClear(AppTool, Gerber):
# disconnect flags
self.area_sel_disconnect_flag = True
# disable the "notebook UI" until finished
self.app.ui.notebook.setDisabled(True)
elif self.select_method == 2: # Reference Object
self.bound_obj_name = self.ui.reference_combo.currentText()
@@ -1776,6 +1733,8 @@ class NonCopperClear(AppTool, Gerber):
self.clear_copper(ncc_obj=self.ncc_obj, sel_obj=self.bound_obj, ncctooldia=self.ncc_dia_list,
isotooldia=self.iso_dia_list, outname=self.o_name)
self.app.ui.notebook.setDisabled(False)
# called on mouse move
def on_mouse_move(self, event):
shape_type = self.ui.area_shape_radio.get_value()
@@ -1908,6 +1867,9 @@ class NonCopperClear(AppTool, Gerber):
self.app.on_mouse_move_over_plot)
self.app.mr = self.app.plotcanvas.graph_event_connect('mouse_release',
self.app.on_mouse_click_release_over_plot)
self.app.ui.notebook.setDisabled(False)
self.points = []
self.poly_drawn = False

View File

@@ -16,7 +16,7 @@ from camlib import Geometry, FlatCAMRTreeStorage, grace
from appGUI.GUIElements import FCTable, FCDoubleSpinner, FCCheckBox, FCInputDoubleSpinner, RadioSet, \
FCButton, FCComboBox, FCLabel, FCComboBox2, VerticalScrollArea, FCGridLayout, FCFrame
from shapely.geometry import base, Polygon, MultiPolygon, LinearRing, Point
from shapely.geometry import base, Polygon, MultiPolygon, LinearRing, Point, MultiLineString, LineString
from shapely.ops import unary_union, linemerge
from matplotlib.backend_bases import KeyEvent as mpl_key_event
@@ -1223,6 +1223,8 @@ class ToolPaint(AppTool, Gerber):
# disconnect flags
self.area_sel_disconnect_flag = True
# disable the "notebook" until the process is finished
self.app.ui.notebook.setDisabled(True)
elif self.select_method == 3: # _("Reference Object")
self.bound_obj_name = self.reference_combo.currentText()
@@ -1437,6 +1439,7 @@ class ToolPaint(AppTool, Gerber):
# disconnect flags
self.area_sel_disconnect_flag = False
self.app.ui.notebook.setDisabled(False)
if len(self.sel_rect) == 0:
return
@@ -1495,7 +1498,7 @@ class ToolPaint(AppTool, Gerber):
# "%.4f    " % (self.app.dx, self.app.dy))
self.app.ui.update_location_labels(self.app.dx, self.app.dy, curr_pos[0], curr_pos[1])
units = self.app.app_units.lower()
# units = self.app.app_units.lower()
# self.app.plotcanvas.text_hud.text = \
# 'Dx:\t{:<.4f} [{:s}]\nDy:\t{:<.4f} [{:s}]\n\nX: \t{:<.4f} [{:s}]\nY: \t{:<.4f} [{:s}]'.format(
# self.app.dx, units, self.app.dy, units, curr_pos[0], units, curr_pos[1], units)
@@ -1591,6 +1594,8 @@ class ToolPaint(AppTool, Gerber):
self.app.on_mouse_click_release_over_plot)
self.app.mp = self.app.plotcanvas.graph_event_connect('mouse_press',
self.app.on_mouse_click_over_plot)
self.app.ui.notebook.setDisabled(False)
self.points = []
self.poly_drawn = False
self.poly_dict.clear()
@@ -1767,30 +1772,6 @@ class ToolPaint(AppTool, Gerber):
cpoly.insert(lin)
except TypeError:
cpoly.insert(lines_union)
# # determine the Gerber follow line
# for apid, apval in obj.tools.items():
# for geo_el in apval['geometry']:
# if 'solid' in geo_el:
# if Point(inside_pt).within(geo_el['solid']):
# if not isinstance(geo_el['follow'], Point):
# line = geo_el['follow']
#
# if apval['type'] == 'C':
# aperture_size = apval['size']
# else:
# if apval['width'] > apval['height']:
# aperture_size = apval['height']
# else:
# aperture_size = apval['width']
#
# if line:
# cpoly = self.fill_with_lines(line, aperture_size,
# tooldia=tooldiameter,
# steps_per_circle=self.circle_steps,
# overlap=over,
# contour=cont,
# connect=conn,
# prog_plot=prog_plot)
except grace:
return "fail"
except Exception as ee:
@@ -1853,7 +1834,8 @@ class ToolPaint(AppTool, Gerber):
:param tools_storage: whether to use the current tools_storage self.paints_tools or a different one.
Usage of the different one is related to when this function is called
from a TcL command.
:param plot:
:param plot: if the geometry is plotted; bool
:param rest: if rest machining apply here; bool
:param run_threaded:
:return: None
"""
@@ -2311,9 +2293,9 @@ class ToolPaint(AppTool, Gerber):
def job_thread(app_obj):
try:
if use_rest_strategy:
ret = app_obj.app_obj.new_object("geometry", name, job_rest_clear, plot=plot)
ret = app_obj.app_obj.new_object("geometry", name, job_rest_clear, plot=plot, autoselected=False)
else:
ret = app_obj.app_obj.new_object("geometry", name, job_normal_clear, plot=plot)
ret = app_obj.app_obj.new_object("geometry", name, job_normal_clear, plot=plot, autoselected=False)
except grace:
proc.done()
return
@@ -2534,10 +2516,10 @@ class ToolPaint(AppTool, Gerber):
# ## If iterable, expand recursively.
try:
for geo in geometry:
multigeo = geometry.geoms if isinstance(geometry, (MultiPolygon, MultiLineString)) else geometry
for geo in multigeo:
if geo and not geo.is_empty and geo.is_valid:
recurse(geometry=geo, reset=False)
# ## Not iterable, do the actual indexing and add.
except TypeError:
if isinstance(geometry, LinearRing):
@@ -2549,7 +2531,8 @@ class ToolPaint(AppTool, Gerber):
return self.flat_geometry
# this is where heavy lifting is done and creating the geometry to be painted
target_geo = MultiPolygon(obj.solid_geometry)
target_geo = unary_union(obj.solid_geometry)
if obj.kind == 'gerber':
# I don't do anything here, like buffering when the Gerber is loaded without buffering????!!!!
if self.app.defaults["gerber_buffering"] == 'no':
@@ -2567,16 +2550,45 @@ class ToolPaint(AppTool, Gerber):
self.app.inform.emit('%s %s' % (_("Paint Tool."), _("Painting area task started.")))
geo_to_paint = target_geo.intersection(sel_obj)
painted_area = recurse(geo_to_paint, reset=True)
try:
painted_area = linemerge(painted_area)
except Exception:
pass
if isinstance(painted_area, (MultiPolygon, MultiLineString)):
painted_area = painted_area.geoms
p_geo_list = []
try:
for paint_g_elem in painted_area:
if isinstance(paint_g_elem, Polygon):
p_geo_list.append(paint_g_elem)
elif isinstance(paint_g_elem, (LinearRing, LineString)):
if paint_g_elem.is_closed:
p_geo_list.append(Polygon(paint_g_elem.coords))
else:
coords = list(paint_g_elem.coords)
coords.append(coords[0])
p_geo_list.append(Polygon(coords))
except TypeError:
if isinstance(painted_area, Polygon):
p_geo_list.append(painted_area)
elif isinstance(painted_area, (LinearRing, LineString)):
if painted_area.is_closed:
p_geo_list.append(Polygon(painted_area.coords))
else:
coords = list(painted_area.coords)
coords.append(coords[0])
p_geo_list.append(Polygon(coords))
# No polygon?
if not geo_to_paint or geo_to_paint.is_empty:
self.app.log.warning('No polygon found.')
if not p_geo_list:
self.app.log.warning('ToolPaint.paint_poly_Area(). No geometry or the found geometry could not be painted.')
self.app.inform.emit('[WARNING] %s' % _('No polygon found.'))
return
painted_area = recurse(geo_to_paint, reset=True)
self.paint_geo(obj, painted_area, tooldia=tooldia, order=order, method=method, outname=outname,
self.paint_geo(obj, p_geo_list, tooldia=tooldia, order=order, method=method, outname=outname,
tools_storage=tools_storage, plot=plot, run_threaded=run_threaded)
def paint_poly_ref(self, obj, sel_obj, tooldia=None, order=None, method=None, outname=None,
@@ -2971,7 +2983,7 @@ class PaintUI:
self.obj_combo = FCComboBox()
self.obj_combo.setModel(self.app.collection)
self.obj_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
self.obj_combo.is_last = True
self.obj_combo.is_last = False
obj_grid.addWidget(self.obj_combo, 2, 0, 1, 2)