- added ability to merge tools when merging Geometry objects if they share the same attributes like: diameter, tool_type or type

- added a control in Edit -> Preferences -> Geometry to control if to merge/fuse tools during Geometry merging
This commit is contained in:
Marius Stanciu 2020-06-10 00:23:08 +03:00 committed by Marius
parent 99e274c82d
commit 0643971b01
6 changed files with 79 additions and 39 deletions

View File

@ -10,6 +10,8 @@ CHANGELOG for FlatCAM beta
9.06.2020 9.06.2020
- fixed a possible problem in generating bounds value for a solid_geometry that have empty geo elements - fixed a possible problem in generating bounds value for a solid_geometry that have empty geo elements
- added ability to merge tools when merging Geometry objects if they share the same attributes like: diameter, tool_type or type
- added a control in Edit -> Preferences -> Geometry to control if to merge/fuse tools during Geometry merging
8.06.2020 8.06.2020

View File

@ -261,11 +261,12 @@ class PreferencesUIManager:
self.ui.excellon_defaults_form.excellon_editor_group.slot_array_circular_angle_entry, self.ui.excellon_defaults_form.excellon_editor_group.slot_array_circular_angle_entry,
# Geometry General # Geometry General
"geometry_plot": self.ui.geometry_defaults_form.geometry_gen_group.plot_cb, "geometry_plot": self.ui.geometry_defaults_form.geometry_gen_group.plot_cb,
"geometry_multicolored": self.ui.geometry_defaults_form.geometry_gen_group.multicolored_cb, "geometry_multicolored": self.ui.geometry_defaults_form.geometry_gen_group.multicolored_cb,
"geometry_circle_steps": self.ui.geometry_defaults_form.geometry_gen_group.circle_steps_entry, "geometry_circle_steps": self.ui.geometry_defaults_form.geometry_gen_group.circle_steps_entry,
"geometry_cnctooldia": self.ui.geometry_defaults_form.geometry_gen_group.cnctooldia_entry, "geometry_cnctooldia": self.ui.geometry_defaults_form.geometry_gen_group.cnctooldia_entry,
"geometry_plot_line": self.ui.geometry_defaults_form.geometry_gen_group.line_color_entry, "geometry_merge_fuse_tools": self.ui.geometry_defaults_form.geometry_gen_group.fuse_tools_cb,
"geometry_plot_line": self.ui.geometry_defaults_form.geometry_gen_group.line_color_entry,
# Geometry Options # Geometry Options
"geometry_cutz": self.ui.geometry_defaults_form.geometry_opt_group.cutz_entry, "geometry_cutz": self.ui.geometry_defaults_form.geometry_opt_group.cutz_entry,

View File

@ -86,9 +86,26 @@ class GeometryGenPrefGroupUI(OptionsGroupUI):
separator_line.setFrameShadow(QtWidgets.QFrame.Sunken) separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
grid0.addWidget(separator_line, 9, 0, 1, 2) grid0.addWidget(separator_line, 9, 0, 1, 2)
# Fuse Tools
self.join_geo_label = QtWidgets.QLabel('<b>%s</b>:' % _('Join Geometry'))
grid0.addWidget(self.join_geo_label, 10, 0, 1, 2)
self.fuse_tools_cb = FCCheckBox(_("Fuse Tools"))
self.fuse_tools_cb.setToolTip(
_("When checked the joined (merged) geometry object tools\n"
"will be merged also but only if they share the same attributes,\n"
"like diameter, tool_type or type.")
)
grid0.addWidget(self.fuse_tools_cb, 11, 0, 1, 2)
separator_line = QtWidgets.QFrame()
separator_line.setFrameShape(QtWidgets.QFrame.HLine)
separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
grid0.addWidget(separator_line, 12, 0, 1, 2)
# Geometry Object Color # Geometry Object Color
self.gerber_color_label = QtWidgets.QLabel('<b>%s</b>' % _('Object Color')) self.gerber_color_label = QtWidgets.QLabel('<b>%s</b>:' % _('Object Color'))
grid0.addWidget(self.gerber_color_label, 10, 0, 1, 2) grid0.addWidget(self.gerber_color_label, 13, 0, 1, 2)
# Plot Line Color # Plot Line Color
self.line_color_label = QtWidgets.QLabel('%s:' % _('Outline')) self.line_color_label = QtWidgets.QLabel('%s:' % _('Outline'))
@ -97,8 +114,8 @@ class GeometryGenPrefGroupUI(OptionsGroupUI):
) )
self.line_color_entry = FCColorEntry() self.line_color_entry = FCColorEntry()
grid0.addWidget(self.line_color_label, 11, 0) grid0.addWidget(self.line_color_label, 14, 0)
grid0.addWidget(self.line_color_entry, 11, 1) grid0.addWidget(self.line_color_entry, 14, 1)
self.layout.addStretch() self.layout.addStretch()

View File

@ -22,6 +22,8 @@ import math
import numpy as np import numpy as np
from copy import deepcopy from copy import deepcopy
import traceback import traceback
from collections import defaultdict
from functools import reduce
import gettext import gettext
import appTranslation as fcTranslate import appTranslation as fcTranslate
@ -2773,13 +2775,14 @@ class GeometryObject(FlatCAMObj, Geometry):
self.plot() self.plot()
@staticmethod @staticmethod
def merge(geo_list, geo_final, multigeo=None): def merge(geo_list, geo_final, multigeo=None, fuse_tools=None):
""" """
Merges the geometry of objects in grb_list into the geometry of geo_final. Merges the geometry of objects in grb_list into the geometry of geo_final.
:param geo_list: List of GerberObject Objects to join. :param geo_list: List of GerberObject Objects to join.
:param geo_final: Destination GerberObject object. :param geo_final: Destination GerberObject object.
:param multigeo: if the merged geometry objects are of type MultiGeo :param multigeo: if the merged geometry objects are of type MultiGeo
:param fuse_tools: If True will try to fuse tools of the same type for the Geometry objects
:return: None :return: None
""" """
@ -2834,38 +2837,52 @@ class GeometryObject(FlatCAMObj, Geometry):
geo_final.options.update(new_options) geo_final.options.update(new_options)
geo_final.solid_geometry = new_solid_geometry geo_final.solid_geometry = new_solid_geometry
# merge the geometries of the tools that share the same tool diameter and the same tool_type and the same type if new_tools and fuse_tools is True:
final_tools = {} # merge the geometries of the tools that share the same tool diameter and the same tool_type
same_dia = {} # and the same type
same_type = {} final_tools = {}
same_tool_type = {} same_dia = defaultdict(list)
same_type = defaultdict(list)
same_tool_type = defaultdict(list)
# find tools that have the same diameter and group them by diameter # find tools that have the same diameter and group them by diameter
for k, v in new_tools.items(): for k, v in new_tools.items():
if v['tooldia'] not in same_dia:
same_dia[v['tooldia']] = [k]
else:
same_dia[v['tooldia']].append(k) same_dia[v['tooldia']].append(k)
# find tools that have the same type and group them by type # find tools that have the same type and group them by type
for k, v in new_tools.items(): for k, v in new_tools.items():
if v['type'] not in same_type:
same_type[v['type']] = [k]
else:
same_type[v['type']].append(k) same_type[v['type']].append(k)
# find tools that have the same tool_type and group them by tool_type # find tools that have the same tool_type and group them by tool_type
for k, v in new_tools.items(): for k, v in new_tools.items():
if v['tool_type'] not in same_tool_type:
same_tool_type[v['tool_type']] = [k]
else:
same_tool_type[v['tool_type']].append(k) same_tool_type[v['tool_type']].append(k)
print(same_dia) # find the intersections in the above groups
print(same_type) intersect_list = []
print(same_tool_type) for dia, dia_list in same_dia.items():
for ty, type_list in same_type.items():
for t_ty, tool_type_list in same_tool_type.items():
intersection = reduce(np.intersect1d, (dia_list, type_list, tool_type_list)).tolist()
if intersection:
intersect_list.append(intersection)
geo_final.tools = new_tools new_tool_nr = 1
for i_lst in intersect_list:
new_solid_geo = []
for old_tool in i_lst:
new_solid_geo += new_tools[old_tool]['solid_geometry']
if new_solid_geo:
final_tools[new_tool_nr] = \
{
k: deepcopy(new_tools[old_tool][k]) for k in new_tools[old_tool] if k != 'solid_geometry'
}
final_tools[new_tool_nr]['solid_geometry'] = deepcopy(new_solid_geo)
new_tool_nr += 1
else:
final_tools = new_tools
geo_final.tools = final_tools
@staticmethod @staticmethod
def get_pts(o): def get_pts(o):

View File

@ -3816,10 +3816,12 @@ class App(QtCore.QObject):
"Check the generated GCODE.")) "Check the generated GCODE."))
return return
fuse_tools = self.defaults["geometry_merge_fuse_tools"]
# if at least one True object is in the list then due of the previous check, all list elements are True objects # if at least one True object is in the list then due of the previous check, all list elements are True objects
if True in geo_type_set: if True in geo_type_set:
def initialize(geo_obj, app): def initialize(geo_obj, app):
GeometryObject.merge(geo_list=objs, geo_final=geo_obj, multigeo=True) GeometryObject.merge(geo_list=objs, geo_final=geo_obj, multigeo=True, fuse_tools=fuse_tools)
app.inform.emit('[success] %s.' % _("Geometry merging finished")) app.inform.emit('[success] %s.' % _("Geometry merging finished"))
# rename all the ['name] key in obj.tools[tooluid]['data'] to the obj_name_multi # rename all the ['name] key in obj.tools[tooluid]['data'] to the obj_name_multi
@ -3829,7 +3831,7 @@ class App(QtCore.QObject):
self.app_obj.new_object("geometry", obj_name_multi, initialize) self.app_obj.new_object("geometry", obj_name_multi, initialize)
else: else:
def initialize(geo_obj, app): def initialize(geo_obj, app):
GeometryObject.merge(geo_list=objs, geo_final=geo_obj, multigeo=False) GeometryObject.merge(geo_list=objs, geo_final=geo_obj, multigeo=False, fuse_tools=fuse_tools)
app.inform.emit('[success] %s.' % _("Geometry merging finished")) app.inform.emit('[success] %s.' % _("Geometry merging finished"))
# rename all the ['name] key in obj.tools[tooluid]['data'] to the obj_name_multi # rename all the ['name] key in obj.tools[tooluid]['data'] to the obj_name_multi

View File

@ -314,6 +314,7 @@ class FlatCAMDefaults:
"geometry_multicolored": False, "geometry_multicolored": False,
"geometry_circle_steps": 64, "geometry_circle_steps": 64,
"geometry_cnctooldia": "2.4", "geometry_cnctooldia": "2.4",
"geometry_merge_fuse_tools": True,
"geometry_plot_line": "#FF0000", "geometry_plot_line": "#FF0000",
# Geometry Options # Geometry Options