Explorar el Código

- 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

Marius Stanciu hace 5 años
padre
commit
0643971b01

+ 2 - 0
CHANGELOG.md

@@ -10,6 +10,8 @@ CHANGELOG for FlatCAM beta
 9.06.2020
 
 - 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
 

+ 6 - 5
appGUI/preferences/PreferencesUIManager.py

@@ -261,11 +261,12 @@ class PreferencesUIManager:
                 self.ui.excellon_defaults_form.excellon_editor_group.slot_array_circular_angle_entry,
 
             # Geometry General
-            "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_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_plot_line":       self.ui.geometry_defaults_form.geometry_gen_group.line_color_entry,
+            "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_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_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_cutz":            self.ui.geometry_defaults_form.geometry_opt_group.cutz_entry,

+ 21 - 4
appGUI/preferences/geometry/GeometryGenPrefGroupUI.py

@@ -86,9 +86,26 @@ class GeometryGenPrefGroupUI(OptionsGroupUI):
         separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
         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
-        self.gerber_color_label = QtWidgets.QLabel('<b>%s</b>' % _('Object Color'))
-        grid0.addWidget(self.gerber_color_label, 10, 0, 1, 2)
+        self.gerber_color_label = QtWidgets.QLabel('<b>%s</b>:' % _('Object Color'))
+        grid0.addWidget(self.gerber_color_label, 13, 0, 1, 2)
 
         # Plot Line Color
         self.line_color_label = QtWidgets.QLabel('%s:' % _('Outline'))
@@ -97,8 +114,8 @@ class GeometryGenPrefGroupUI(OptionsGroupUI):
         )
         self.line_color_entry = FCColorEntry()
 
-        grid0.addWidget(self.line_color_label, 11, 0)
-        grid0.addWidget(self.line_color_entry, 11, 1)
+        grid0.addWidget(self.line_color_label, 14, 0)
+        grid0.addWidget(self.line_color_entry, 14, 1)
 
         self.layout.addStretch()
 

+ 45 - 28
appObjects/FlatCAMGeometry.py

@@ -22,6 +22,8 @@ import math
 import numpy as np
 from copy import deepcopy
 import traceback
+from collections import defaultdict
+from functools import reduce
 
 import gettext
 import appTranslation as fcTranslate
@@ -2773,13 +2775,14 @@ class GeometryObject(FlatCAMObj, Geometry):
         self.plot()
 
     @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.
 
-        :param geo_list: List of GerberObject Objects to join.
-        :param geo_final: Destination GerberObject object.
-        :param multigeo: if the merged geometry objects are of type MultiGeo
+        :param geo_list:    List of GerberObject Objects to join.
+        :param geo_final:   Destination GerberObject object.
+        :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
         """
 
@@ -2834,38 +2837,52 @@ class GeometryObject(FlatCAMObj, Geometry):
         geo_final.options.update(new_options)
         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
-        final_tools = {}
-        same_dia = {}
-        same_type = {}
-        same_tool_type = {}
+        if new_tools and fuse_tools is True:
+            # merge the geometries of the tools that share the same tool diameter and the same tool_type
+            # and the same type
+            final_tools = {}
+            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
-        for k, v in new_tools.items():
-            if v['tooldia'] not in same_dia:
-                same_dia[v['tooldia']] = [k]
-            else:
+            # find tools that have the same diameter and group them by diameter
+            for k, v in new_tools.items():
                 same_dia[v['tooldia']].append(k)
 
-        # find tools that have the same type and group them by type
-        for k, v in new_tools.items():
-            if v['type'] not in same_type:
-                same_type[v['type']] = [k]
-            else:
+            # find tools that have the same type and group them by type
+            for k, v in new_tools.items():
                 same_type[v['type']].append(k)
 
-        # find tools that have the same tool_type and group them by tool_type
-        for k, v in new_tools.items():
-            if v['tool_type'] not in same_tool_type:
-                same_tool_type[v['tool_type']] = [k]
-            else:
+            # find tools that have the same tool_type and group them by tool_type
+            for k, v in new_tools.items():
                 same_tool_type[v['tool_type']].append(k)
 
-        print(same_dia)
-        print(same_type)
-        print(same_tool_type)
+            # find the intersections in the above groups
+            intersect_list = []
+            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)
+
+            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 = new_tools
+        geo_final.tools = final_tools
 
     @staticmethod
     def get_pts(o):

+ 4 - 2
app_Main.py

@@ -3816,10 +3816,12 @@ class App(QtCore.QObject):
                                "Check the generated GCODE."))
             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 True in geo_type_set:
             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"))
 
                 # 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)
         else:
             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"))
 
                 # rename all the ['name] key in obj.tools[tooluid]['data'] to the obj_name_multi

+ 1 - 0
defaults.py

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