- added new option in ToolSub: the ability to close (or not) the resulting paths when using tool on Geometry objects. Added also a new category in the Edit -> Preferences -> Tools, the Substractor Tool Options
This commit is contained in:
@@ -590,7 +590,8 @@ class App(QtCore.QObject):
|
|||||||
"tools_solderpaste_dwellfwd": self.ui.tools_defaults_form.tools_solderpaste_group.dwellfwd_entry,
|
"tools_solderpaste_dwellfwd": self.ui.tools_defaults_form.tools_solderpaste_group.dwellfwd_entry,
|
||||||
"tools_solderpaste_speedrev": self.ui.tools_defaults_form.tools_solderpaste_group.speedrev_entry,
|
"tools_solderpaste_speedrev": self.ui.tools_defaults_form.tools_solderpaste_group.speedrev_entry,
|
||||||
"tools_solderpaste_dwellrev": self.ui.tools_defaults_form.tools_solderpaste_group.dwellrev_entry,
|
"tools_solderpaste_dwellrev": self.ui.tools_defaults_form.tools_solderpaste_group.dwellrev_entry,
|
||||||
"tools_solderpaste_pp": self.ui.tools_defaults_form.tools_solderpaste_group.pp_combo
|
"tools_solderpaste_pp": self.ui.tools_defaults_form.tools_solderpaste_group.pp_combo,
|
||||||
|
"tools_sub_close_paths": self.ui.tools_defaults_form.tools_sub_group.close_paths_cb
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -922,7 +923,9 @@ class App(QtCore.QObject):
|
|||||||
"tools_solderpaste_dwellfwd": 1,
|
"tools_solderpaste_dwellfwd": 1,
|
||||||
"tools_solderpaste_speedrev": 10,
|
"tools_solderpaste_speedrev": 10,
|
||||||
"tools_solderpaste_dwellrev": 1,
|
"tools_solderpaste_dwellrev": 1,
|
||||||
"tools_solderpaste_pp": 'Paste_1'
|
"tools_solderpaste_pp": 'Paste_1',
|
||||||
|
|
||||||
|
"tools_sub_close_paths": True
|
||||||
})
|
})
|
||||||
|
|
||||||
# ##############################
|
# ##############################
|
||||||
|
|||||||
@@ -9,6 +9,10 @@ CAD program, and create G-Code for Isolation routing.
|
|||||||
|
|
||||||
=================================================
|
=================================================
|
||||||
|
|
||||||
|
13.08.2019
|
||||||
|
|
||||||
|
- added new option in ToolSub: the ability to close (or not) the resulting paths when using tool on Geometry objects. Added also a new category in the Edit -> Preferences -> Tools, the Substractor Tool Options
|
||||||
|
|
||||||
12.08.2019
|
12.08.2019
|
||||||
|
|
||||||
- done regression to solve the bug with multiple passes cutting from the copper features (I should remember not to make mods here)
|
- done regression to solve the bug with multiple passes cutting from the copper features (I should remember not to make mods here)
|
||||||
|
|||||||
@@ -3280,6 +3280,9 @@ class ToolsPreferencesUI(QtWidgets.QWidget):
|
|||||||
self.tools_solderpaste_group = ToolsSolderpastePrefGroupUI()
|
self.tools_solderpaste_group = ToolsSolderpastePrefGroupUI()
|
||||||
self.tools_solderpaste_group.setMinimumWidth(200)
|
self.tools_solderpaste_group.setMinimumWidth(200)
|
||||||
|
|
||||||
|
self.tools_sub_group = ToolsSubPrefGroupUI()
|
||||||
|
self.tools_sub_group.setMinimumWidth(200)
|
||||||
|
|
||||||
self.vlay = QtWidgets.QVBoxLayout()
|
self.vlay = QtWidgets.QVBoxLayout()
|
||||||
self.vlay.addWidget(self.tools_ncc_group)
|
self.vlay.addWidget(self.tools_ncc_group)
|
||||||
self.vlay.addWidget(self.tools_paint_group)
|
self.vlay.addWidget(self.tools_paint_group)
|
||||||
@@ -3296,6 +3299,7 @@ class ToolsPreferencesUI(QtWidgets.QWidget):
|
|||||||
|
|
||||||
self.vlay3 = QtWidgets.QVBoxLayout()
|
self.vlay3 = QtWidgets.QVBoxLayout()
|
||||||
self.vlay3.addWidget(self.tools_solderpaste_group)
|
self.vlay3.addWidget(self.tools_solderpaste_group)
|
||||||
|
self.vlay3.addWidget(self.tools_sub_group)
|
||||||
|
|
||||||
self.layout.addLayout(self.vlay)
|
self.layout.addLayout(self.vlay)
|
||||||
self.layout.addLayout(self.vlay1)
|
self.layout.addLayout(self.vlay1)
|
||||||
@@ -6708,6 +6712,28 @@ class ToolsSolderpastePrefGroupUI(OptionsGroupUI):
|
|||||||
self.layout.addStretch()
|
self.layout.addStretch()
|
||||||
|
|
||||||
|
|
||||||
|
class ToolsSubPrefGroupUI(OptionsGroupUI):
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
|
||||||
|
super(ToolsSubPrefGroupUI, self).__init__(self)
|
||||||
|
|
||||||
|
self.setTitle(str(_("Substractor Tool Options")))
|
||||||
|
|
||||||
|
# ## Solder Paste Dispensing
|
||||||
|
self.sublabel = QtWidgets.QLabel(_("<b>Parameters:</b>"))
|
||||||
|
self.sublabel.setToolTip(
|
||||||
|
_("A tool to substract one Gerber or Geometry object\n"
|
||||||
|
"from another of the same type.")
|
||||||
|
)
|
||||||
|
self.layout.addWidget(self.sublabel)
|
||||||
|
|
||||||
|
self.close_paths_cb = FCCheckBox(_("Close paths"))
|
||||||
|
self.close_paths_cb.setToolTip(_("Checking this will close the paths cut by the Geometry substractor object."))
|
||||||
|
self.layout.addWidget(self.close_paths_cb)
|
||||||
|
|
||||||
|
self.layout.addStretch()
|
||||||
|
|
||||||
|
|
||||||
class FlatCAMActivityView(QtWidgets.QWidget):
|
class FlatCAMActivityView(QtWidgets.QWidget):
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
|
|||||||
@@ -130,6 +130,10 @@ class ToolSub(FlatCAMTool):
|
|||||||
|
|
||||||
form_geo_layout.addRow(self.sub_geo_label, self.sub_geo_combo)
|
form_geo_layout.addRow(self.sub_geo_label, self.sub_geo_combo)
|
||||||
|
|
||||||
|
self.close_paths_cb = FCCheckBox(_("Close paths"))
|
||||||
|
self.close_paths_cb.setToolTip(_("Checking this will close the paths cut by the Geometry substractor object."))
|
||||||
|
self.tools_box.addWidget(self.close_paths_cb)
|
||||||
|
|
||||||
self.intersect_geo_btn = FCButton(_('Substract Geometry'))
|
self.intersect_geo_btn = FCButton(_('Substract Geometry'))
|
||||||
self.intersect_geo_btn.setToolTip(
|
self.intersect_geo_btn.setToolTip(
|
||||||
_("Will remove the area occupied by the substractor\n"
|
_("Will remove the area occupied by the substractor\n"
|
||||||
@@ -217,6 +221,7 @@ class ToolSub(FlatCAMTool):
|
|||||||
|
|
||||||
def set_tool_ui(self):
|
def set_tool_ui(self):
|
||||||
self.tools_frame.show()
|
self.tools_frame.show()
|
||||||
|
self.close_paths_cb.setChecked(self.app.defaults["tools_sub_close_paths"])
|
||||||
|
|
||||||
def on_grb_intersection_click(self):
|
def on_grb_intersection_click(self):
|
||||||
# reset previous values
|
# reset previous values
|
||||||
@@ -231,7 +236,7 @@ class ToolSub(FlatCAMTool):
|
|||||||
self.app.inform.emit(_("[ERROR_NOTCL] No Target object loaded."))
|
self.app.inform.emit(_("[ERROR_NOTCL] No Target object loaded."))
|
||||||
return
|
return
|
||||||
|
|
||||||
# Get source object.
|
# Get target object.
|
||||||
try:
|
try:
|
||||||
self.target_grb_obj = self.app.collection.get_by_name(self.target_grb_obj_name)
|
self.target_grb_obj = self.app.collection.get_by_name(self.target_grb_obj_name)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -244,7 +249,7 @@ class ToolSub(FlatCAMTool):
|
|||||||
self.app.inform.emit(_("[ERROR_NOTCL] No Substractor object loaded."))
|
self.app.inform.emit(_("[ERROR_NOTCL] No Substractor object loaded."))
|
||||||
return
|
return
|
||||||
|
|
||||||
# Get source object.
|
# Get substractor object.
|
||||||
try:
|
try:
|
||||||
self.sub_grb_obj = self.app.collection.get_by_name(self.sub_grb_obj_name)
|
self.sub_grb_obj = self.app.collection.get_by_name(self.sub_grb_obj_name)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -424,7 +429,7 @@ class ToolSub(FlatCAMTool):
|
|||||||
self.app.inform.emit(_("[ERROR_NOTCL] No Target object loaded."))
|
self.app.inform.emit(_("[ERROR_NOTCL] No Target object loaded."))
|
||||||
return
|
return
|
||||||
|
|
||||||
# Get source object.
|
# Get target object.
|
||||||
try:
|
try:
|
||||||
self.target_geo_obj = self.app.collection.get_by_name(self.target_geo_obj_name)
|
self.target_geo_obj = self.app.collection.get_by_name(self.target_geo_obj_name)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -437,7 +442,7 @@ class ToolSub(FlatCAMTool):
|
|||||||
self.app.inform.emit(_("[ERROR_NOTCL] No Substractor object loaded."))
|
self.app.inform.emit(_("[ERROR_NOTCL] No Substractor object loaded."))
|
||||||
return
|
return
|
||||||
|
|
||||||
# Get source object.
|
# Get substractor object.
|
||||||
try:
|
try:
|
||||||
self.sub_geo_obj = self.app.collection.get_by_name(self.sub_geo_obj_name)
|
self.sub_geo_obj = self.app.collection.get_by_name(self.sub_geo_obj_name)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -496,10 +501,58 @@ class ToolSub(FlatCAMTool):
|
|||||||
text = _("Parsing tool %s geometry ...") % str(tool)
|
text = _("Parsing tool %s geometry ...") % str(tool)
|
||||||
|
|
||||||
with self.app.proc_container.new(text):
|
with self.app.proc_container.new(text):
|
||||||
new_geo = (cascaded_union(geo)).difference(self.sub_union)
|
# resulting paths are closed resulting into Polygons
|
||||||
if new_geo:
|
if self.close_paths_cb.isChecked():
|
||||||
if not new_geo.is_empty:
|
new_geo = (cascaded_union(geo)).difference(self.sub_union)
|
||||||
new_geometry.append(new_geo)
|
if new_geo:
|
||||||
|
if not new_geo.is_empty:
|
||||||
|
new_geometry.append(new_geo)
|
||||||
|
# resulting paths are unclosed resulting in a multitude of rings
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
for geo_elem in geo:
|
||||||
|
if isinstance(geo_elem, Polygon):
|
||||||
|
for ring in self.poly2rings(geo_elem):
|
||||||
|
new_geo = ring.difference(self.sub_union)
|
||||||
|
if new_geo:
|
||||||
|
if 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(self.sub_union)
|
||||||
|
if new_geo:
|
||||||
|
if not new_geo.is_empty:
|
||||||
|
new_geometry.append(new_geo)
|
||||||
|
elif isinstance(geo_elem, LineString):
|
||||||
|
new_geo = geo_elem.difference(self.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(self.sub_union)
|
||||||
|
if new_geo:
|
||||||
|
if 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(self.sub_union)
|
||||||
|
if new_geo:
|
||||||
|
if not new_geo.is_empty:
|
||||||
|
new_geometry.append(new_geo)
|
||||||
|
elif isinstance(geo, LineString):
|
||||||
|
new_geo = geo.difference(self.sub_union)
|
||||||
|
if new_geo:
|
||||||
|
if not new_geo.is_empty:
|
||||||
|
new_geometry.append(new_geo)
|
||||||
|
elif isinstance(geo, MultiLineString):
|
||||||
|
for line_elem in geo:
|
||||||
|
new_geo = line_elem.difference(self.sub_union)
|
||||||
|
if new_geo:
|
||||||
|
if not new_geo.is_empty:
|
||||||
|
new_geometry.append(new_geo)
|
||||||
|
|
||||||
if new_geometry:
|
if new_geometry:
|
||||||
if tool == "single":
|
if tool == "single":
|
||||||
@@ -620,4 +673,7 @@ class ToolSub(FlatCAMTool):
|
|||||||
self.target_geo_combo.setRootModelIndex(self.app.collection.index(2, 0, QtCore.QModelIndex()))
|
self.target_geo_combo.setRootModelIndex(self.app.collection.index(2, 0, QtCore.QModelIndex()))
|
||||||
self.sub_geo_combo.setRootModelIndex(self.app.collection.index(2, 0, QtCore.QModelIndex()))
|
self.sub_geo_combo.setRootModelIndex(self.app.collection.index(2, 0, QtCore.QModelIndex()))
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def poly2rings(poly):
|
||||||
|
return [poly.exterior] + [interior for interior in poly.interiors]
|
||||||
# end of file
|
# end of file
|
||||||
|
|||||||
Reference in New Issue
Block a user