Przeglądaj źródła

- modified the Cutout Tool to generate multi-geo objects therefore the set geometry parameters will populate the Geometry Object UI
- modified the Panelize Tool to optimize the output from Cutout Tool such that there are no longer overlapping cuts
- some string corrections

Marius Stanciu 5 lat temu
rodzic
commit
ada271cbd6

+ 3 - 0
CHANGELOG.md

@@ -14,6 +14,9 @@ CHANGELOG for FlatCAM beta
 - fixed bug in Gerber Editor in which the units conversion wasn't calculated correct
 - fixed bug in Gerber Editor in which the units conversion wasn't calculated correct
 - fixed bug in Gerber Editor in which the QThread that is started on object edit was not stopped at clean up stage
 - fixed bug in Gerber Editor in which the QThread that is started on object edit was not stopped at clean up stage
 - fixed bug in Gerber Editor that kept all the apertures (including the geometry) of a previously edited object that was not saved after edit
 - fixed bug in Gerber Editor that kept all the apertures (including the geometry) of a previously edited object that was not saved after edit
+- modified the Cutout Tool to generate multi-geo objects therefore the set geometry parameters will populate the Geometry Object UI
+- modified the Panelize Tool to optimize the output from Cutout Tool such that there are no longer overlapping cuts
+- some string corrections
 
 
 01.05.2020
 01.05.2020
 
 

+ 4 - 2
FlatCAMApp.py

@@ -4111,9 +4111,11 @@ class App(QtCore.QObject):
         obj.multigeo = True
         obj.multigeo = True
         for tooluid, dict_value in obj.tools.items():
         for tooluid, dict_value in obj.tools.items():
             dict_value['solid_geometry'] = deepcopy(obj.solid_geometry)
             dict_value['solid_geometry'] = deepcopy(obj.solid_geometry)
+
         if not isinstance(obj.solid_geometry, list):
         if not isinstance(obj.solid_geometry, list):
             obj.solid_geometry = [obj.solid_geometry]
             obj.solid_geometry = [obj.solid_geometry]
-        obj.solid_geometry[:] = []
+
+        # obj.solid_geometry[:] = []
         obj.plot()
         obj.plot()
 
 
         self.should_we_save = True
         self.should_we_save = True
@@ -5024,7 +5026,7 @@ class App(QtCore.QObject):
                 self.paste_tool.on_add_tool_by_key()
                 self.paste_tool.on_add_tool_by_key()
 
 
     # It's meant to delete tools in tool tables via a 'Delete' shortcut key but only if certain conditions are met
     # It's meant to delete tools in tool tables via a 'Delete' shortcut key but only if certain conditions are met
-    # See description bellow.
+    # See description below.
     def on_delete_keypress(self):
     def on_delete_keypress(self):
         notebook_widget_name = self.ui.notebook.currentWidget().objectName()
         notebook_widget_name = self.ui.notebook.currentWidget().objectName()
 
 

+ 2 - 2
flatcamEditors/FlatCAMExcEditor.py

@@ -3226,7 +3226,7 @@ class FlatCAMExcEditor(QtCore.QObject):
             spec = {"C": float(tool_dia[0])}
             spec = {"C": float(tool_dia[0])}
             self.new_tools[name] = spec
             self.new_tools[name] = spec
 
 
-            # add in self.tools the 'solid_geometry' key, the value (a list) is populated bellow
+            # add in self.tools the 'solid_geometry' key, the value (a list) is populated below
             self.new_tools[name]['solid_geometry'] = []
             self.new_tools[name]['solid_geometry'] = []
 
 
             # create the self.drills for the new Excellon object (the one with edited content)
             # create the self.drills for the new Excellon object (the one with edited content)
@@ -3258,7 +3258,7 @@ class FlatCAMExcEditor(QtCore.QObject):
                 spec = {"C": float(tool_dia[0])}
                 spec = {"C": float(tool_dia[0])}
                 self.new_tools[name] = spec
                 self.new_tools[name] = spec
 
 
-                # add in self.tools the 'solid_geometry' key, the value (a list) is populated bellow
+                # add in self.tools the 'solid_geometry' key, the value (a list) is populated below
                 self.new_tools[name]['solid_geometry'] = []
                 self.new_tools[name]['solid_geometry'] = []
 
 
             # create the self.slots for the new Excellon object (the one with edited content)
             # create the self.slots for the new Excellon object (the one with edited content)

+ 1 - 1
flatcamGUI/FlatCAMGUI.py

@@ -3232,7 +3232,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
                         else:
                         else:
                             self.app.collection.set_active(names_list[active_index-1])
                             self.app.collection.set_active(names_list[active_index-1])
 
 
-                # Select the object in the Tree bellow the current one
+                # Select the object in the Tree below the current one
                 if key == QtCore.Qt.Key_Down:
                 if key == QtCore.Qt.Key_Down:
                     # make sure it works only for the Project Tab who is an instance of KeySensitiveListView
                     # make sure it works only for the Project Tab who is an instance of KeySensitiveListView
                     focused_wdg = QtWidgets.QApplication.focusWidget()
                     focused_wdg = QtWidgets.QApplication.focusWidget()

+ 1 - 1
flatcamGUI/preferences/PreferencesUIManager.py

@@ -42,7 +42,7 @@ class PreferencesUIManager:
         # if Preferences are changed in the Edit -> Preferences tab the value will be set to True
         # if Preferences are changed in the Edit -> Preferences tab the value will be set to True
         self.preferences_changed_flag = False
         self.preferences_changed_flag = False
 
 
-        # when adding entries here read the comments in the  method found bellow named:
+        # when adding entries here read the comments in the  method found below named:
         # def new_object(self, kind, name, initialize, active=True, fit=True, plot=True)
         # def new_object(self, kind, name, initialize, active=True, fit=True, plot=True)
         self.defaults_form_fields = {
         self.defaults_form_fields = {
             # General App
             # General App

+ 1 - 1
flatcamObjects/FlatCAMCNCJob.py

@@ -364,7 +364,7 @@ class CNCJobObject(FlatCAMObj, CNCjob):
         self.units_found = self.app.defaults['units']
         self.units_found = self.app.defaults['units']
 
 
         # this signal has to be connected to it's slot before the defaults are populated
         # this signal has to be connected to it's slot before the defaults are populated
-        # the decision done in the slot has to override the default value set bellow
+        # the decision done in the slot has to override the default value set below
         self.ui.toolchange_cb.toggled.connect(self.on_toolchange_custom_clicked)
         self.ui.toolchange_cb.toggled.connect(self.on_toolchange_custom_clicked)
 
 
         self.form_fields.update({
         self.form_fields.update({

+ 1 - 1
flatcamParsers/ParseExcellon.py

@@ -426,7 +426,7 @@ class Excellon(Geometry):
                                     # it's possible that tool definition has only tool number and no diameter info
                                     # it's possible that tool definition has only tool number and no diameter info
                                     # (those could be in another file like PCB Wizard do)
                                     # (those could be in another file like PCB Wizard do)
                                     # then match.group(2) = None and float(None) will create the exception
                                     # then match.group(2) = None and float(None) will create the exception
-                                    # the bellow construction is so each tool will have a slightly different diameter
+                                    # the below construction is so each tool will have a slightly different diameter
                                     # starting with a default value, to allow Excellon editing after that
                                     # starting with a default value, to allow Excellon editing after that
                                     self.diameterless = True
                                     self.diameterless = True
                                     self.app.inform.emit('[WARNING] %s%s %s' %
                                     self.app.inform.emit('[WARNING] %s%s %s' %

+ 106 - 9
flatcamTools/ToolCutOut.py

@@ -293,12 +293,12 @@ class CutOut(FlatCAMTool):
                             font-weight: bold;
                             font-weight: bold;
                         }
                         }
                         """)
                         """)
-        self.layout.addWidget(self.rect_cutout_object_btn)
+        grid0.addWidget(self.rect_cutout_object_btn, 21, 0, 1, 2)
 
 
         separator_line = QtWidgets.QFrame()
         separator_line = QtWidgets.QFrame()
         separator_line.setFrameShape(QtWidgets.QFrame.HLine)
         separator_line.setFrameShape(QtWidgets.QFrame.HLine)
         separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
         separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
-        grid0.addWidget(separator_line, 21, 0, 1, 2)
+        grid0.addWidget(separator_line, 22, 0, 1, 2)
 
 
         # Title5
         # Title5
         title_manual_label = QtWidgets.QLabel("<font size=4><b>%s</b></font>" % _('B. Manual Bridge Gaps'))
         title_manual_label = QtWidgets.QLabel("<font size=4><b>%s</b></font>" % _('B. Manual Bridge Gaps'))
@@ -307,7 +307,7 @@ class CutOut(FlatCAMTool):
               "This is done by mouse clicking on the perimeter of the\n"
               "This is done by mouse clicking on the perimeter of the\n"
               "Geometry object that is used as a cutout object. ")
               "Geometry object that is used as a cutout object. ")
         )
         )
-        grid0.addWidget(title_manual_label, 22, 0, 1, 2)
+        grid0.addWidget(title_manual_label, 23, 0, 1, 2)
 
 
         # Manual Geo Object
         # Manual Geo Object
         self.man_object_combo = FCComboBox()
         self.man_object_combo = FCComboBox()
@@ -322,8 +322,8 @@ class CutOut(FlatCAMTool):
         )
         )
         # self.man_object_label.setMinimumWidth(60)
         # self.man_object_label.setMinimumWidth(60)
 
 
-        grid0.addWidget(self.man_object_label, 23, 0, 1, 2)
-        grid0.addWidget(self.man_object_combo, 24, 0, 1, 2)
+        grid0.addWidget(self.man_object_label, 25, 0, 1, 2)
+        grid0.addWidget(self.man_object_combo, 26, 0, 1, 2)
 
 
         self.man_geo_creation_btn = FCButton(_("Generate Manual Geometry"))
         self.man_geo_creation_btn = FCButton(_("Generate Manual Geometry"))
         self.man_geo_creation_btn.setToolTip(
         self.man_geo_creation_btn.setToolTip(
@@ -338,7 +338,7 @@ class CutOut(FlatCAMTool):
                             font-weight: bold;
                             font-weight: bold;
                         }
                         }
                         """)
                         """)
-        grid0.addWidget(self.man_geo_creation_btn, 25, 0, 1, 2)
+        grid0.addWidget(self.man_geo_creation_btn, 28, 0, 1, 2)
 
 
         self.man_gaps_creation_btn = FCButton(_("Manual Add Bridge Gaps"))
         self.man_gaps_creation_btn = FCButton(_("Manual Add Bridge Gaps"))
         self.man_gaps_creation_btn.setToolTip(
         self.man_gaps_creation_btn.setToolTip(
@@ -354,7 +354,7 @@ class CutOut(FlatCAMTool):
                             font-weight: bold;
                             font-weight: bold;
                         }
                         }
                         """)
                         """)
-        grid0.addWidget(self.man_gaps_creation_btn, 27, 0, 1, 2)
+        grid0.addWidget(self.man_gaps_creation_btn, 30, 0, 1, 2)
 
 
         self.layout.addStretch()
         self.layout.addStretch()
 
 
@@ -394,6 +394,9 @@ class CutOut(FlatCAMTool):
         self.x_pos = None
         self.x_pos = None
         self.y_pos = None
         self.y_pos = None
 
 
+        # store the default data for the resulting Geometry Object
+        self.default_data = {}
+
         # Signals
         # Signals
         self.ff_cutout_object_btn.clicked.connect(self.on_freeform_cutout)
         self.ff_cutout_object_btn.clicked.connect(self.on_freeform_cutout)
         self.rect_cutout_object_btn.clicked.connect(self.on_rectangular_cutout)
         self.rect_cutout_object_btn.clicked.connect(self.on_rectangular_cutout)
@@ -454,6 +457,48 @@ class CutOut(FlatCAMTool):
         self.convex_box.set_value(self.app.defaults['tools_cutout_convexshape'])
         self.convex_box.set_value(self.app.defaults['tools_cutout_convexshape'])
         self.type_obj_radio.set_value('grb')
         self.type_obj_radio.set_value('grb')
 
 
+        self.default_data.update({
+            "plot":             True,
+            "cutz":             float(self.app.defaults["geometry_cutz"]),
+            "multidepth":       self.app.defaults["geometry_multidepth"],
+            "depthperpass":     float(self.app.defaults["geometry_depthperpass"]),
+            "vtipdia":          float(self.app.defaults["geometry_vtipdia"]),
+            "vtipangle":        float(self.app.defaults["geometry_vtipangle"]),
+            "travelz":          float(self.app.defaults["geometry_travelz"]),
+            "feedrate":         float(self.app.defaults["geometry_feedrate"]),
+            "feedrate_z":       float(self.app.defaults["geometry_feedrate_z"]),
+            "feedrate_rapid":   float(self.app.defaults["geometry_feedrate_rapid"]),
+            "spindlespeed":     self.app.defaults["geometry_spindlespeed"],
+            "dwell":            self.app.defaults["geometry_dwell"],
+            "dwelltime":        float(self.app.defaults["geometry_dwelltime"]),
+            "ppname_g":         self.app.defaults["geometry_ppname_g"],
+            "extracut":         self.app.defaults["geometry_extracut"],
+            "extracut_length":  float(self.app.defaults["geometry_extracut_length"]),
+            "toolchange":       self.app.defaults["geometry_toolchange"],
+            "toolchangexy":     self.app.defaults["geometry_toolchangexy"],
+            "toolchangez":      float(self.app.defaults["geometry_toolchangez"]),
+            "startz":           self.app.defaults["geometry_startz"],
+            "endz":             float(self.app.defaults["geometry_endz"]),
+
+            # NCC
+            "tools_nccoperation":       self.app.defaults["tools_nccoperation"],
+            "tools_nccmilling_type":    self.app.defaults["tools_nccmilling_type"],
+            "tools_nccoverlap":         float(self.app.defaults["tools_nccoverlap"]),
+            "tools_nccmargin":          float(self.app.defaults["tools_nccmargin"]),
+            "tools_nccmethod":          self.app.defaults["tools_nccmethod"],
+            "tools_nccconnect":         self.app.defaults["tools_nccconnect"],
+            "tools_ncccontour":         self.app.defaults["tools_ncccontour"],
+            "tools_ncc_offset_choice":  self.app.defaults["tools_ncc_offset_choice"],
+            "tools_ncc_offset_value":   float(self.app.defaults["tools_ncc_offset_value"]),
+
+            # Paint
+            "tools_paintoverlap":       float(self.app.defaults["tools_paintoverlap"]),
+            "tools_paintmargin":        float(self.app.defaults["tools_paintmargin"]),
+            "tools_paintmethod":        self.app.defaults["tools_paintmethod"],
+            "tools_pathconnect":        self.app.defaults["tools_pathconnect"],
+            "tools_paintcontour":       self.app.defaults["tools_paintcontour"],
+        })
+
     def on_freeform_cutout(self):
     def on_freeform_cutout(self):
         log.debug("Cutout.on_freeform_cutout() was launched ...")
         log.debug("Cutout.on_freeform_cutout() was launched ...")
 
 
@@ -622,8 +667,8 @@ class CutOut(FlatCAMTool):
 
 
                     solid_geo += cutout_handler(geom=geom_struct)
                     solid_geo += cutout_handler(geom=geom_struct)
 
 
-            geo_obj.solid_geometry = deepcopy(solid_geo)
             xmin, ymin, xmax, ymax = recursive_bounds(geo_obj.solid_geometry)
             xmin, ymin, xmax, ymax = recursive_bounds(geo_obj.solid_geometry)
+            geo_obj.solid_geometry = deepcopy(solid_geo)
             geo_obj.options['xmin'] = xmin
             geo_obj.options['xmin'] = xmin
             geo_obj.options['ymin'] = ymin
             geo_obj.options['ymin'] = ymin
             geo_obj.options['xmax'] = xmax
             geo_obj.options['xmax'] = xmax
@@ -633,6 +678,23 @@ class CutOut(FlatCAMTool):
             geo_obj.options['multidepth'] = self.mpass_cb.get_value()
             geo_obj.options['multidepth'] = self.mpass_cb.get_value()
             geo_obj.options['depthperpass'] = self.maxdepth_entry.get_value()
             geo_obj.options['depthperpass'] = self.maxdepth_entry.get_value()
 
 
+            geo_obj.tools.update({
+                1: {
+                    'tooldia': str(dia),
+                    'offset': 'Path',
+                    'offset_value': 0.0,
+                    'type': _('Rough'),
+                    'tool_type': 'C1',
+                    'data': self.default_data,
+                    'solid_geometry': geo_obj.solid_geometry
+                }
+            })
+            geo_obj.multigeo = True
+            geo_obj.tools[1]['data']['name'] = outname
+            geo_obj.tools[1]['data']['cutz'] = self.cutz_entry.get_value()
+            geo_obj.tools[1]['data']['multidepth'] = self.mpass_cb.get_value()
+            geo_obj.tools[1]['data']['depthperpass'] = self.maxdepth_entry.get_value()
+
         outname = cutout_obj.options["name"] + "_cutout"
         outname = cutout_obj.options["name"] + "_cutout"
         self.app.new_object('geometry', outname, geo_init)
         self.app.new_object('geometry', outname, geo_init)
 
 
@@ -759,6 +821,7 @@ class CutOut(FlatCAMTool):
                 return proc_geometry
                 return proc_geometry
 
 
             if kind == 'single':
             if kind == 'single':
+                # fuse the lines
                 object_geo = unary_union(object_geo)
                 object_geo = unary_union(object_geo)
 
 
                 xmin, ymin, xmax, ymax = object_geo.bounds
                 xmin, ymin, xmax, ymax = object_geo.bounds
@@ -805,11 +868,28 @@ class CutOut(FlatCAMTool):
                                          _("Rectangular cutout with negative margin is not possible."))
                                          _("Rectangular cutout with negative margin is not possible."))
                     return "fail"
                     return "fail"
 
 
-            geo_obj.solid_geometry = deepcopy(solid_geo)
             geo_obj.options['cnctooldia'] = str(dia)
             geo_obj.options['cnctooldia'] = str(dia)
             geo_obj.options['cutz'] = self.cutz_entry.get_value()
             geo_obj.options['cutz'] = self.cutz_entry.get_value()
             geo_obj.options['multidepth'] = self.mpass_cb.get_value()
             geo_obj.options['multidepth'] = self.mpass_cb.get_value()
             geo_obj.options['depthperpass'] = self.maxdepth_entry.get_value()
             geo_obj.options['depthperpass'] = self.maxdepth_entry.get_value()
+            geo_obj.solid_geometry = deepcopy(solid_geo)
+
+            geo_obj.tools.update({
+                1: {
+                    'tooldia': str(dia),
+                    'offset': 'Path',
+                    'offset_value': 0.0,
+                    'type': _('Rough'),
+                    'tool_type': 'C1',
+                    'data': self.default_data,
+                    'solid_geometry': geo_obj.solid_geometry
+                }
+            })
+            geo_obj.multigeo = True
+            geo_obj.tools[1]['data']['name'] = outname
+            geo_obj.tools[1]['data']['cutz'] = self.cutz_entry.get_value()
+            geo_obj.tools[1]['data']['multidepth'] = self.mpass_cb.get_value()
+            geo_obj.tools[1]['data']['depthperpass'] = self.maxdepth_entry.get_value()
 
 
         outname = cutout_obj.options["name"] + "_cutout"
         outname = cutout_obj.options["name"] + "_cutout"
         ret = self.app.new_object('geometry', outname, geo_init)
         ret = self.app.new_object('geometry', outname, geo_init)
@@ -954,6 +1034,23 @@ class CutOut(FlatCAMTool):
             geo_obj.options['multidepth'] = self.mpass_cb.get_value()
             geo_obj.options['multidepth'] = self.mpass_cb.get_value()
             geo_obj.options['depthperpass'] = self.maxdepth_entry.get_value()
             geo_obj.options['depthperpass'] = self.maxdepth_entry.get_value()
 
 
+            geo_obj.tools.update({
+                1: {
+                    'tooldia': str(dia),
+                    'offset': 'Path',
+                    'offset_value': 0.0,
+                    'type': _('Rough'),
+                    'tool_type': 'C1',
+                    'data': self.default_data,
+                    'solid_geometry': geo_obj.solid_geometry
+                }
+            })
+            geo_obj.multigeo = True
+            geo_obj.tools[1]['data']['name'] = outname
+            geo_obj.tools[1]['data']['cutz'] = self.cutz_entry.get_value()
+            geo_obj.tools[1]['data']['multidepth'] = self.mpass_cb.get_value()
+            geo_obj.tools[1]['data']['depthperpass'] = self.maxdepth_entry.get_value()
+
         outname = cutout_obj.options["name"] + "_cutout"
         outname = cutout_obj.options["name"] + "_cutout"
         self.app.new_object('geometry', outname, geo_init)
         self.app.new_object('geometry', outname, geo_init)
 
 

+ 77 - 78
flatcamTools/ToolPanelize.py

@@ -14,6 +14,8 @@ from copy import deepcopy
 import numpy as np
 import numpy as np
 
 
 import shapely.affinity as affinity
 import shapely.affinity as affinity
+from shapely.ops import unary_union
+from shapely.geometry import LineString
 
 
 import gettext
 import gettext
 import FlatCAMTranslation as fcTranslate
 import FlatCAMTranslation as fcTranslate
@@ -402,19 +404,18 @@ class Panelize(FlatCAMTool):
     def on_panelize(self):
     def on_panelize(self):
         name = self.object_combo.currentText()
         name = self.object_combo.currentText()
 
 
-        # Get source object.
+        # Get source object to be panelized.
         try:
         try:
-            panel_obj = self.app.collection.get_by_name(str(name))
+            panel_source_obj = self.app.collection.get_by_name(str(name))
         except Exception as e:
         except Exception as e:
             log.debug("Panelize.on_panelize() --> %s" % str(e))
             log.debug("Panelize.on_panelize() --> %s" % str(e))
-            self.app.inform.emit('[ERROR_NOTCL] %s: %s' %
-                                 (_("Could not retrieve object"), name))
+            self.app.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Could not retrieve object"), name))
             return "Could not retrieve object: %s" % name
             return "Could not retrieve object: %s" % name
 
 
-        if panel_obj is None:
+        if panel_source_obj is None:
             self.app.inform.emit('[ERROR_NOTCL] %s: %s' %
             self.app.inform.emit('[ERROR_NOTCL] %s: %s' %
-                                 (_("Object not found"), panel_obj))
-            return "Object not found: %s" % panel_obj
+                                 (_("Object not found"), panel_source_obj))
+            return "Object not found: %s" % panel_source_obj
 
 
         boxname = self.box_combo.currentText()
         boxname = self.box_combo.currentText()
 
 
@@ -422,17 +423,15 @@ class Panelize(FlatCAMTool):
             box = self.app.collection.get_by_name(boxname)
             box = self.app.collection.get_by_name(boxname)
         except Exception as e:
         except Exception as e:
             log.debug("Panelize.on_panelize() --> %s" % str(e))
             log.debug("Panelize.on_panelize() --> %s" % str(e))
-            self.app.inform.emit('[ERROR_NOTCL] %s: %s' %
-                                 (_("Could not retrieve object"), boxname))
+            self.app.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Could not retrieve object"), boxname))
             return "Could not retrieve object: %s" % boxname
             return "Could not retrieve object: %s" % boxname
 
 
         if box is None:
         if box is None:
-            self.app.inform.emit('[WARNING_NOTCL]%s: %s' %
-                                 (_("No object Box. Using instead"), panel_obj))
+            self.app.inform.emit('[WARNING_NOTCL]%s: %s' % (_("No object Box. Using instead"), panel_source_obj))
             self.reference_radio.set_value('bbox')
             self.reference_radio.set_value('bbox')
 
 
         if self.reference_radio.get_value() == 'bbox':
         if self.reference_radio.get_value() == 'bbox':
-            box = panel_obj
+            box = panel_source_obj
 
 
         self.outname = name + '_panelized'
         self.outname = name + '_panelized'
 
 
@@ -478,20 +477,20 @@ class Panelize(FlatCAMTool):
                     rows -= 1
                     rows -= 1
                     panel_lengthy = ((ymax - ymin) * rows) + (spacing_rows * (rows - 1))
                     panel_lengthy = ((ymax - ymin) * rows) + (spacing_rows * (rows - 1))
 
 
-        if panel_obj.kind == 'excellon' or panel_obj.kind == 'geometry':
+        if panel_source_obj.kind == 'excellon' or panel_source_obj.kind == 'geometry':
             # make a copy of the panelized Excellon or Geometry tools
             # make a copy of the panelized Excellon or Geometry tools
             copied_tools = {}
             copied_tools = {}
-            for tt, tt_val in list(panel_obj.tools.items()):
+            for tt, tt_val in list(panel_source_obj.tools.items()):
                 copied_tools[tt] = deepcopy(tt_val)
                 copied_tools[tt] = deepcopy(tt_val)
 
 
-        if panel_obj.kind == 'gerber':
+        if panel_source_obj.kind == 'gerber':
             # make a copy of the panelized Gerber apertures
             # make a copy of the panelized Gerber apertures
             copied_apertures = {}
             copied_apertures = {}
-            for tt, tt_val in list(panel_obj.apertures.items()):
+            for tt, tt_val in list(panel_source_obj.apertures.items()):
                 copied_apertures[tt] = deepcopy(tt_val)
                 copied_apertures[tt] = deepcopy(tt_val)
 
 
-        def panelize_2():
-            if panel_obj is not None:
+        def panelize_worker():
+            if panel_source_obj is not None:
                 self.app.inform.emit(_("Generating panel ... "))
                 self.app.inform.emit(_("Generating panel ... "))
 
 
                 def job_init_excellon(obj_fin, app_obj):
                 def job_init_excellon(obj_fin, app_obj):
@@ -501,15 +500,15 @@ class Panelize(FlatCAMTool):
                     obj_fin.slots = []
                     obj_fin.slots = []
                     obj_fin.solid_geometry = []
                     obj_fin.solid_geometry = []
 
 
-                    for option in panel_obj.options:
+                    for option in panel_source_obj.options:
                         if option != 'name':
                         if option != 'name':
                             try:
                             try:
-                                obj_fin.options[option] = panel_obj.options[option]
+                                obj_fin.options[option] = panel_source_obj.options[option]
                             except KeyError:
                             except KeyError:
                                 log.warning("Failed to copy option. %s" % str(option))
                                 log.warning("Failed to copy option. %s" % str(option))
 
 
-                    geo_len_drills = len(panel_obj.drills) if panel_obj.drills else 0
-                    geo_len_slots = len(panel_obj.slots) if panel_obj.slots else 0
+                    geo_len_drills = len(panel_source_obj.drills) if panel_source_obj.drills else 0
+                    geo_len_slots = len(panel_source_obj.slots) if panel_source_obj.slots else 0
 
 
                     element = 0
                     element = 0
                     for row in range(rows):
                     for row in range(rows):
@@ -518,9 +517,9 @@ class Panelize(FlatCAMTool):
                             element += 1
                             element += 1
                             old_disp_number = 0
                             old_disp_number = 0
 
 
-                            if panel_obj.drills:
+                            if panel_source_obj.drills:
                                 drill_nr = 0
                                 drill_nr = 0
-                                for tool_dict in panel_obj.drills:
+                                for tool_dict in panel_source_obj.drills:
                                     if self.app.abort_flag:
                                     if self.app.abort_flag:
                                         # graceful abort requested by the user
                                         # graceful abort requested by the user
                                         raise grace
                                         raise grace
@@ -543,9 +542,9 @@ class Panelize(FlatCAMTool):
                                                                                   disp_number))
                                                                                   disp_number))
                                         old_disp_number = disp_number
                                         old_disp_number = disp_number
 
 
-                            if panel_obj.slots:
+                            if panel_source_obj.slots:
                                 slot_nr = 0
                                 slot_nr = 0
-                                for tool_dict in panel_obj.slots:
+                                for tool_dict in panel_source_obj.slots:
                                     if self.app.abort_flag:
                                     if self.app.abort_flag:
                                         # graceful abort requested by the user
                                         # graceful abort requested by the user
                                         raise grace
                                         raise grace
@@ -574,8 +573,8 @@ class Panelize(FlatCAMTool):
                         currenty += lenghty
                         currenty += lenghty
 
 
                     obj_fin.create_geometry()
                     obj_fin.create_geometry()
-                    obj_fin.zeros = panel_obj.zeros
-                    obj_fin.units = panel_obj.units
+                    obj_fin.zeros = panel_source_obj.zeros
+                    obj_fin.units = panel_source_obj.units
                     self.app.proc_container.update_view_text('')
                     self.app.proc_container.update_view_text('')
 
 
                 def job_init_geometry(obj_fin, app_obj):
                 def job_init_geometry(obj_fin, app_obj):
@@ -598,36 +597,36 @@ class Panelize(FlatCAMTool):
                     obj_fin.solid_geometry = []
                     obj_fin.solid_geometry = []
 
 
                     # create the initial structure on which to create the panel
                     # create the initial structure on which to create the panel
-                    if panel_obj.kind == 'geometry':
-                        obj_fin.multigeo = panel_obj.multigeo
+                    if panel_source_obj.kind == 'geometry':
+                        obj_fin.multigeo = panel_source_obj.multigeo
                         obj_fin.tools = copied_tools
                         obj_fin.tools = copied_tools
-                        if panel_obj.multigeo is True:
-                            for tool in panel_obj.tools:
+                        if panel_source_obj.multigeo is True:
+                            for tool in panel_source_obj.tools:
                                 obj_fin.tools[tool]['solid_geometry'][:] = []
                                 obj_fin.tools[tool]['solid_geometry'][:] = []
-                    elif panel_obj.kind == 'gerber':
+                    elif panel_source_obj.kind == 'gerber':
                         obj_fin.apertures = copied_apertures
                         obj_fin.apertures = copied_apertures
                         for ap in obj_fin.apertures:
                         for ap in obj_fin.apertures:
                             obj_fin.apertures[ap]['geometry'] = []
                             obj_fin.apertures[ap]['geometry'] = []
 
 
                     # find the number of polygons in the source solid_geometry
                     # find the number of polygons in the source solid_geometry
                     geo_len = 0
                     geo_len = 0
-                    if panel_obj.kind == 'geometry':
-                        if panel_obj.multigeo is True:
-                            for tool in panel_obj.tools:
+                    if panel_source_obj.kind == 'geometry':
+                        if panel_source_obj.multigeo is True:
+                            for tool in panel_source_obj.tools:
                                 try:
                                 try:
-                                    geo_len += len(panel_obj.tools[tool]['solid_geometry'])
+                                    geo_len += len(panel_source_obj.tools[tool]['solid_geometry'])
                                 except TypeError:
                                 except TypeError:
                                     geo_len += 1
                                     geo_len += 1
                         else:
                         else:
                             try:
                             try:
-                                geo_len = len(panel_obj.solid_geometry)
+                                geo_len = len(panel_source_obj.solid_geometry)
                             except TypeError:
                             except TypeError:
                                 geo_len = 1
                                 geo_len = 1
-                    elif panel_obj.kind == 'gerber':
-                        for ap in panel_obj.apertures:
-                            if 'geometry' in panel_obj.apertures[ap]:
+                    elif panel_source_obj.kind == 'gerber':
+                        for ap in panel_source_obj.apertures:
+                            if 'geometry' in panel_source_obj.apertures[ap]:
                                 try:
                                 try:
-                                    geo_len += len(panel_obj.apertures[ap]['geometry'])
+                                    geo_len += len(panel_source_obj.apertures[ap]['geometry'])
                                 except TypeError:
                                 except TypeError:
                                     geo_len += 1
                                     geo_len += 1
 
 
@@ -639,29 +638,23 @@ class Panelize(FlatCAMTool):
                             element += 1
                             element += 1
                             old_disp_number = 0
                             old_disp_number = 0
 
 
-                            if panel_obj.kind == 'geometry':
-                                if panel_obj.multigeo is True:
-                                    for tool in panel_obj.tools:
+                            # Will panelize a Geometry Object
+                            if panel_source_obj.kind == 'geometry':
+                                if panel_source_obj.multigeo is True:
+                                    for tool in panel_source_obj.tools:
                                         if self.app.abort_flag:
                                         if self.app.abort_flag:
                                             # graceful abort requested by the user
                                             # graceful abort requested by the user
                                             raise grace
                                             raise grace
 
 
-                                        # geo = translate_recursion(panel_obj.tools[tool]['solid_geometry'])
-                                        # if isinstance(geo, list):
-                                        #     obj_fin.tools[tool]['solid_geometry'] += geo
-                                        # else:
-                                        #     obj_fin.tools[tool]['solid_geometry'].append(geo)
-
                                         # calculate the number of polygons
                                         # calculate the number of polygons
-                                        geo_len = len(panel_obj.tools[tool]['solid_geometry'])
+                                        geo_len = len(panel_source_obj.tools[tool]['solid_geometry'])
                                         pol_nr = 0
                                         pol_nr = 0
-                                        for geo_el in panel_obj.tools[tool]['solid_geometry']:
+                                        for geo_el in panel_source_obj.tools[tool]['solid_geometry']:
                                             trans_geo = translate_recursion(geo_el)
                                             trans_geo = translate_recursion(geo_el)
                                             obj_fin.tools[tool]['solid_geometry'].append(trans_geo)
                                             obj_fin.tools[tool]['solid_geometry'].append(trans_geo)
 
 
                                             pol_nr += 1
                                             pol_nr += 1
                                             disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100]))
                                             disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100]))
-
                                             if old_disp_number < disp_number <= 100:
                                             if old_disp_number < disp_number <= 100:
                                                 self.app.proc_container.update_view_text(' %s: %d %d%%' %
                                                 self.app.proc_container.update_view_text(' %s: %d %d%%' %
                                                                                          (_("Copy"),
                                                                                          (_("Copy"),
@@ -669,23 +662,18 @@ class Panelize(FlatCAMTool):
                                                                                           disp_number))
                                                                                           disp_number))
                                                 old_disp_number = disp_number
                                                 old_disp_number = disp_number
                                 else:
                                 else:
-                                    # geo = translate_recursion(panel_obj.solid_geometry)
-                                    # if isinstance(geo, list):
-                                    #     obj_fin.solid_geometry += geo
-                                    # else:
-                                    #     obj_fin.solid_geometry.append(geo)
                                     if self.app.abort_flag:
                                     if self.app.abort_flag:
                                         # graceful abort requested by the user
                                         # graceful abort requested by the user
                                         raise grace
                                         raise grace
 
 
                                     try:
                                     try:
                                         # calculate the number of polygons
                                         # calculate the number of polygons
-                                        geo_len = len(panel_obj.solid_geometry)
+                                        geo_len = len(panel_source_obj.solid_geometry)
                                     except TypeError:
                                     except TypeError:
                                         geo_len = 1
                                         geo_len = 1
                                     pol_nr = 0
                                     pol_nr = 0
                                     try:
                                     try:
-                                        for geo_el in panel_obj.solid_geometry:
+                                        for geo_el in panel_source_obj.solid_geometry:
                                             if self.app.abort_flag:
                                             if self.app.abort_flag:
                                                 # graceful abort requested by the user
                                                 # graceful abort requested by the user
                                                 raise grace
                                                 raise grace
@@ -702,21 +690,18 @@ class Panelize(FlatCAMTool):
                                                                                           int(element),
                                                                                           int(element),
                                                                                           disp_number))
                                                                                           disp_number))
                                                 old_disp_number = disp_number
                                                 old_disp_number = disp_number
+
                                     except TypeError:
                                     except TypeError:
-                                        trans_geo = translate_recursion(panel_obj.solid_geometry)
+                                        trans_geo = translate_recursion(panel_source_obj.solid_geometry)
                                         obj_fin.solid_geometry.append(trans_geo)
                                         obj_fin.solid_geometry.append(trans_geo)
+                            # Will panelize a Gerber Object
                             else:
                             else:
-                                # geo = translate_recursion(panel_obj.solid_geometry)
-                                # if isinstance(geo, list):
-                                #     obj_fin.solid_geometry += geo
-                                # else:
-                                #     obj_fin.solid_geometry.append(geo)
                                 if self.app.abort_flag:
                                 if self.app.abort_flag:
                                     # graceful abort requested by the user
                                     # graceful abort requested by the user
                                     raise grace
                                     raise grace
 
 
                                 try:
                                 try:
-                                    for geo_el in panel_obj.solid_geometry:
+                                    for geo_el in panel_source_obj.solid_geometry:
                                         if self.app.abort_flag:
                                         if self.app.abort_flag:
                                             # graceful abort requested by the user
                                             # graceful abort requested by the user
                                             raise grace
                                             raise grace
@@ -724,21 +709,21 @@ class Panelize(FlatCAMTool):
                                         trans_geo = translate_recursion(geo_el)
                                         trans_geo = translate_recursion(geo_el)
                                         obj_fin.solid_geometry.append(trans_geo)
                                         obj_fin.solid_geometry.append(trans_geo)
                                 except TypeError:
                                 except TypeError:
-                                    trans_geo = translate_recursion(panel_obj.solid_geometry)
+                                    trans_geo = translate_recursion(panel_source_obj.solid_geometry)
                                     obj_fin.solid_geometry.append(trans_geo)
                                     obj_fin.solid_geometry.append(trans_geo)
 
 
-                                for apid in panel_obj.apertures:
+                                for apid in panel_source_obj.apertures:
                                     if self.app.abort_flag:
                                     if self.app.abort_flag:
                                         # graceful abort requested by the user
                                         # graceful abort requested by the user
                                         raise grace
                                         raise grace
-                                    if 'geometry' in panel_obj.apertures[apid]:
+                                    if 'geometry' in panel_source_obj.apertures[apid]:
                                         try:
                                         try:
                                             # calculate the number of polygons
                                             # calculate the number of polygons
-                                            geo_len = len(panel_obj.apertures[apid]['geometry'])
+                                            geo_len = len(panel_source_obj.apertures[apid]['geometry'])
                                         except TypeError:
                                         except TypeError:
                                             geo_len = 1
                                             geo_len = 1
                                         pol_nr = 0
                                         pol_nr = 0
-                                        for el in panel_obj.apertures[apid]['geometry']:
+                                        for el in panel_source_obj.apertures[apid]['geometry']:
                                             if self.app.abort_flag:
                                             if self.app.abort_flag:
                                                 # graceful abort requested by the user
                                                 # graceful abort requested by the user
                                                 raise grace
                                                 raise grace
@@ -771,20 +756,34 @@ class Panelize(FlatCAMTool):
                             currentx += lenghtx
                             currentx += lenghtx
                         currenty += lenghty
                         currenty += lenghty
 
 
+                    print("before", obj_fin.tools)
+                    if panel_source_obj.kind == 'geometry' and panel_source_obj.multigeo is True:
+                        # I'm going to do this only here as a fix for panelizing cutouts
+                        # I'm going to separate linestrings out of the solid geometry from other
+                        # possible type of elements and apply unary_union on them to fuse them
+                        for tool in obj_fin.tools:
+                            lines = []
+                            other_geo = []
+                            for geo in obj_fin.tools[tool]['solid_geometry']:
+                                if isinstance(geo, LineString):
+                                    lines.append(geo)
+                                else:
+                                    other_geo.append(geo)
+                            fused_lines = list(unary_union(lines))
+                            obj_fin.tools[tool]['solid_geometry'] = fused_lines + other_geo
+                    print("after", obj_fin.tools)
+
                     if panel_type == 'gerber':
                     if panel_type == 'gerber':
                         self.app.inform.emit('%s' % _("Generating panel ... Adding the Gerber code."))
                         self.app.inform.emit('%s' % _("Generating panel ... Adding the Gerber code."))
                         obj_fin.source_file = self.app.export_gerber(obj_name=self.outname, filename=None,
                         obj_fin.source_file = self.app.export_gerber(obj_name=self.outname, filename=None,
                                                                      local_use=obj_fin, use_thread=False)
                                                                      local_use=obj_fin, use_thread=False)
 
 
-                    # app_obj.log.debug("Found %s geometries. Creating a panel geometry cascaded union ..." %
-                    #                   len(obj_fin.solid_geometry))
-
                     # obj_fin.solid_geometry = cascaded_union(obj_fin.solid_geometry)
                     # obj_fin.solid_geometry = cascaded_union(obj_fin.solid_geometry)
                     # app_obj.log.debug("Finished creating a cascaded union for the panel.")
                     # app_obj.log.debug("Finished creating a cascaded union for the panel.")
                     self.app.proc_container.update_view_text('')
                     self.app.proc_container.update_view_text('')
 
 
                 self.app.inform.emit('%s: %d' % (_("Generating panel... Spawning copies"), (int(rows * columns))))
                 self.app.inform.emit('%s: %d' % (_("Generating panel... Spawning copies"), (int(rows * columns))))
-                if panel_obj.kind == 'excellon':
+                if panel_source_obj.kind == 'excellon':
                     self.app.new_object("excellon", self.outname, job_init_excellon, plot=True, autoselected=True)
                     self.app.new_object("excellon", self.outname, job_init_excellon, plot=True, autoselected=True)
                 else:
                 else:
                     self.app.new_object(panel_type, self.outname, job_init_geometry, plot=True, autoselected=True)
                     self.app.new_object(panel_type, self.outname, job_init_geometry, plot=True, autoselected=True)
@@ -801,7 +800,7 @@ class Panelize(FlatCAMTool):
 
 
         def job_thread(app_obj):
         def job_thread(app_obj):
             try:
             try:
-                panelize_2()
+                panelize_worker()
                 self.app.inform.emit('[success] %s' % _("Panel created successfully."))
                 self.app.inform.emit('[success] %s' % _("Panel created successfully."))
             except Exception as ee:
             except Exception as ee:
                 proc.done()
                 proc.done()

+ 1 - 1
flatcamTools/ToolSolderPaste.py

@@ -155,7 +155,7 @@ class SolderPaste(FlatCAMTool):
         step1_lbl = QtWidgets.QLabel("<b>%s:</b>" % _('STEP 1'))
         step1_lbl = QtWidgets.QLabel("<b>%s:</b>" % _('STEP 1'))
         step1_lbl.setToolTip(
         step1_lbl.setToolTip(
             _("First step is to select a number of nozzle tools for usage\n"
             _("First step is to select a number of nozzle tools for usage\n"
-              "and then optionally modify the GCode parameters bellow.")
+              "and then optionally modify the GCode parameters below.")
         )
         )
         step1_description_lbl = QtWidgets.QLabel(_("Select tools.\n"
         step1_description_lbl = QtWidgets.QLabel(_("Select tools.\n"
                                                    "Modify parameters."))
                                                    "Modify parameters."))

+ 1 - 1
flatcamTools/ToolSub.py

@@ -97,7 +97,7 @@ class ToolSub(FlatCAMTool):
 
 
         form_layout.addRow(self.sub_gerber_label, self.sub_gerber_combo)
         form_layout.addRow(self.sub_gerber_label, self.sub_gerber_combo)
 
 
-        self.intersect_btn = FCButton(_('Substract Gerber'))
+        self.intersect_btn = FCButton(_('Subtract Gerber'))
         self.intersect_btn.setToolTip(
         self.intersect_btn.setToolTip(
             _("Will remove the area occupied by the subtractor\n"
             _("Will remove the area occupied by the subtractor\n"
               "Gerber from the Target Gerber.\n"
               "Gerber from the Target Gerber.\n"

+ 3 - 3
locale/de/LC_MESSAGES/strings.po

@@ -17325,7 +17325,7 @@ msgstr "SCHRITT 1"
 #: flatcamTools/ToolSolderPaste.py:157
 #: flatcamTools/ToolSolderPaste.py:157
 msgid ""
 msgid ""
 "First step is to select a number of nozzle tools for usage\n"
 "First step is to select a number of nozzle tools for usage\n"
-"and then optionally modify the GCode parameters bellow."
+"and then optionally modify the GCode parameters below."
 msgstr ""
 msgstr ""
 "Zunächst müssen Sie eine Reihe von Düsenwerkzeugen auswählen\n"
 "Zunächst müssen Sie eine Reihe von Düsenwerkzeugen auswählen\n"
 "und ändern Sie dann optional die GCode-Parameter."
 "und ändern Sie dann optional die GCode-Parameter."
@@ -17565,7 +17565,7 @@ msgstr ""
 "vom Zielobjekt Gerber."
 "vom Zielobjekt Gerber."
 
 
 #: flatcamTools/ToolSub.py:100
 #: flatcamTools/ToolSub.py:100
-msgid "Substract Gerber"
+msgid "Subtract Gerber"
 msgstr "Gerber abziehen"
 msgstr "Gerber abziehen"
 
 
 #: flatcamTools/ToolSub.py:102
 #: flatcamTools/ToolSub.py:102
@@ -20547,7 +20547,7 @@ msgstr ""
 #~ msgid "[success] Paint Area Done."
 #~ msgid "[success] Paint Area Done."
 #~ msgstr "[success] Lackierbereich fertig."
 #~ msgstr "[success] Lackierbereich fertig."
 
 
-#~ msgid "...proccessing... [%s]"
+#~ msgid "...processing... [%s]"
 #~ msgstr "...wird bearbeitet...[%s]"
 #~ msgstr "...wird bearbeitet...[%s]"
 
 
 #~ msgid "Parsing aperture %s geometry ..."
 #~ msgid "Parsing aperture %s geometry ..."

+ 6 - 6
locale/en/LC_MESSAGES/strings.po

@@ -16981,10 +16981,10 @@ msgstr "STEP 1"
 #: flatcamTools/ToolSolderPaste.py:157
 #: flatcamTools/ToolSolderPaste.py:157
 msgid ""
 msgid ""
 "First step is to select a number of nozzle tools for usage\n"
 "First step is to select a number of nozzle tools for usage\n"
-"and then optionally modify the GCode parameters bellow."
+"and then optionally modify the GCode parameters below."
 msgstr ""
 msgstr ""
 "First step is to select a number of nozzle tools for usage\n"
 "First step is to select a number of nozzle tools for usage\n"
-"and then optionally modify the GCode parameters bellow."
+"and then optionally modify the GCode parameters below."
 
 
 #: flatcamTools/ToolSolderPaste.py:160
 #: flatcamTools/ToolSolderPaste.py:160
 msgid ""
 msgid ""
@@ -17216,8 +17216,8 @@ msgstr ""
 "from the target Gerber object."
 "from the target Gerber object."
 
 
 #: flatcamTools/ToolSub.py:100
 #: flatcamTools/ToolSub.py:100
-msgid "Substract Gerber"
-msgstr "Substract Gerber"
+msgid "Subtract Gerber"
+msgstr "Subtract Gerber"
 
 
 #: flatcamTools/ToolSub.py:102
 #: flatcamTools/ToolSub.py:102
 msgid ""
 msgid ""
@@ -20512,8 +20512,8 @@ msgstr "No Geometry name in args. Provide a name and try again."
 #~ msgid "Generating panel ... Please wait."
 #~ msgid "Generating panel ... Please wait."
 #~ msgstr "Generating panel ... Please wait."
 #~ msgstr "Generating panel ... Please wait."
 
 
-#~ msgid "...proccessing... [%s]"
-#~ msgstr "...proccessing... [%s]"
+#~ msgid "...processing... [%s]"
+#~ msgstr "...processing... [%s]"
 
 
 #~ msgid "Parsing aperture %s geometry ..."
 #~ msgid "Parsing aperture %s geometry ..."
 #~ msgstr "Parsing aperture %s geometry ..."
 #~ msgstr "Parsing aperture %s geometry ..."

+ 3 - 3
locale/es/LC_MESSAGES/strings.po

@@ -17257,7 +17257,7 @@ msgstr "PASO 1"
 #: flatcamTools/ToolSolderPaste.py:157
 #: flatcamTools/ToolSolderPaste.py:157
 msgid ""
 msgid ""
 "First step is to select a number of nozzle tools for usage\n"
 "First step is to select a number of nozzle tools for usage\n"
-"and then optionally modify the GCode parameters bellow."
+"and then optionally modify the GCode parameters below."
 msgstr ""
 msgstr ""
 "El primer paso es seleccionar una serie de herramientas de boquillas para su "
 "El primer paso es seleccionar una serie de herramientas de boquillas para su "
 "uso\n"
 "uso\n"
@@ -17502,7 +17502,7 @@ msgstr ""
 "del objeto objetivo de Gerber."
 "del objeto objetivo de Gerber."
 
 
 #: flatcamTools/ToolSub.py:100
 #: flatcamTools/ToolSub.py:100
-msgid "Substract Gerber"
+msgid "Subtract Gerber"
 msgstr "Restar Gerber"
 msgstr "Restar Gerber"
 
 
 #: flatcamTools/ToolSub.py:102
 #: flatcamTools/ToolSub.py:102
@@ -19224,7 +19224,7 @@ msgstr ""
 #~ msgid "[success] Paint Area Done."
 #~ msgid "[success] Paint Area Done."
 #~ msgstr "[éxito] Área de pintura realizada."
 #~ msgstr "[éxito] Área de pintura realizada."
 
 
-#~ msgid "...proccessing... [%s]"
+#~ msgid "...processing... [%s]"
 #~ msgstr "... procesando ... [% s]"
 #~ msgstr "... procesando ... [% s]"
 
 
 #~ msgid "Parsing aperture %s geometry ..."
 #~ msgid "Parsing aperture %s geometry ..."

+ 2 - 2
locale/fr/LC_MESSAGES/strings.po

@@ -17254,7 +17254,7 @@ msgstr "ÉTAPE 1"
 #: flatcamTools/ToolSolderPaste.py:157
 #: flatcamTools/ToolSolderPaste.py:157
 msgid ""
 msgid ""
 "First step is to select a number of nozzle tools for usage\n"
 "First step is to select a number of nozzle tools for usage\n"
-"and then optionally modify the GCode parameters bellow."
+"and then optionally modify the GCode parameters below."
 msgstr ""
 msgstr ""
 "La première étape consiste à sélectionner un certain nombre d’outils de buse "
 "La première étape consiste à sélectionner un certain nombre d’outils de buse "
 "à utiliser.\n"
 "à utiliser.\n"
@@ -17498,7 +17498,7 @@ msgstr ""
 "à partir de l'objet Gerber cible."
 "à partir de l'objet Gerber cible."
 
 
 #: flatcamTools/ToolSub.py:100
 #: flatcamTools/ToolSub.py:100
-msgid "Substract Gerber"
+msgid "Subtract Gerber"
 msgstr "Soustraire Gerber"
 msgstr "Soustraire Gerber"
 
 
 #: flatcamTools/ToolSub.py:102
 #: flatcamTools/ToolSub.py:102

+ 8 - 8
locale/hu/LC_MESSAGES/strings.po

@@ -7235,11 +7235,11 @@ msgstr "Except"
 #: flatcamGUI/ObjectUI.py:436
 #: flatcamGUI/ObjectUI.py:436
 msgid ""
 msgid ""
 "When the isolation geometry is generated,\n"
 "When the isolation geometry is generated,\n"
-"by checking this, the area of the object bellow\n"
+"by checking this, the area of the object below\n"
 "will be subtracted from the isolation geometry."
 "will be subtracted from the isolation geometry."
 msgstr ""
 msgstr ""
 "When the isolation geometry is generated,\n"
 "When the isolation geometry is generated,\n"
-"by checking this, the area of the object bellow\n"
+"by checking this, the area of the object below\n"
 "will be subtracted from the isolation geometry."
 "will be subtracted from the isolation geometry."
 
 
 #: flatcamGUI/ObjectUI.py:449 flatcamGUI/PreferencesUI.py:6527
 #: flatcamGUI/ObjectUI.py:449 flatcamGUI/PreferencesUI.py:6527
@@ -16986,10 +16986,10 @@ msgstr "STEP 1"
 #: flatcamTools/ToolSolderPaste.py:157
 #: flatcamTools/ToolSolderPaste.py:157
 msgid ""
 msgid ""
 "First step is to select a number of nozzle tools for usage\n"
 "First step is to select a number of nozzle tools for usage\n"
-"and then optionally modify the GCode parameters bellow."
+"and then optionally modify the GCode parameters below."
 msgstr ""
 msgstr ""
 "First step is to select a number of nozzle tools for usage\n"
 "First step is to select a number of nozzle tools for usage\n"
-"and then optionally modify the GCode parameters bellow."
+"and then optionally modify the GCode parameters below."
 
 
 #: flatcamTools/ToolSolderPaste.py:160
 #: flatcamTools/ToolSolderPaste.py:160
 msgid ""
 msgid ""
@@ -17221,8 +17221,8 @@ msgstr ""
 "from the target Gerber object."
 "from the target Gerber object."
 
 
 #: flatcamTools/ToolSub.py:100
 #: flatcamTools/ToolSub.py:100
-msgid "Substract Gerber"
-msgstr "Substract Gerber"
+msgid "Subtract Gerber"
+msgstr "Subtract Gerber"
 
 
 #: flatcamTools/ToolSub.py:102
 #: flatcamTools/ToolSub.py:102
 msgid ""
 msgid ""
@@ -20477,8 +20477,8 @@ msgstr "No Geometry name in args. Provide a name and try again."
 #~ msgid "Generating panel ... Please wait."
 #~ msgid "Generating panel ... Please wait."
 #~ msgstr "Generating panel ... Please wait."
 #~ msgstr "Generating panel ... Please wait."
 
 
-#~ msgid "...proccessing... [%s]"
-#~ msgstr "...proccessing... [%s]"
+#~ msgid "...processing... [%s]"
+#~ msgstr "...processing... [%s]"
 
 
 #~ msgid "Parsing aperture %s geometry ..."
 #~ msgid "Parsing aperture %s geometry ..."
 #~ msgstr "Parsing aperture %s geometry ..."
 #~ msgstr "Parsing aperture %s geometry ..."

+ 4 - 4
locale/it/LC_MESSAGES/strings.po

@@ -6804,7 +6804,7 @@ msgstr ""
 #: flatcamGUI/ObjectUI.py:431
 #: flatcamGUI/ObjectUI.py:431
 msgid ""
 msgid ""
 "When the isolation geometry is generated,\n"
 "When the isolation geometry is generated,\n"
-"by checking this, the area of the object bellow\n"
+"by checking this, the area of the object below\n"
 "will be subtracted from the isolation geometry."
 "will be subtracted from the isolation geometry."
 msgstr ""
 msgstr ""
 
 
@@ -14198,7 +14198,7 @@ msgid "Violations: There are no violations for the current rule."
 msgstr ""
 msgstr ""
 
 
 #: flatcamTools/ToolShell.py:70 flatcamTools/ToolShell.py:72
 #: flatcamTools/ToolShell.py:70 flatcamTools/ToolShell.py:72
-msgid "...proccessing..."
+msgid "...processing..."
 msgstr ""
 msgstr ""
 
 
 #: flatcamTools/ToolSolderPaste.py:37
 #: flatcamTools/ToolSolderPaste.py:37
@@ -14251,7 +14251,7 @@ msgstr ""
 #: flatcamTools/ToolSolderPaste.py:156
 #: flatcamTools/ToolSolderPaste.py:156
 msgid ""
 msgid ""
 "First step is to select a number of nozzle tools for usage\n"
 "First step is to select a number of nozzle tools for usage\n"
-"and then optionally modify the GCode parameters bellow."
+"and then optionally modify the GCode parameters below."
 msgstr ""
 msgstr ""
 
 
 #: flatcamTools/ToolSolderPaste.py:159
 #: flatcamTools/ToolSolderPaste.py:159
@@ -14452,7 +14452,7 @@ msgid ""
 msgstr ""
 msgstr ""
 
 
 #: flatcamTools/ToolSub.py:97
 #: flatcamTools/ToolSub.py:97
-msgid "Substract Gerber"
+msgid "Subtract Gerber"
 msgstr ""
 msgstr ""
 
 
 #: flatcamTools/ToolSub.py:99
 #: flatcamTools/ToolSub.py:99

+ 3 - 3
locale/pt_BR/LC_MESSAGES/strings.po

@@ -17045,7 +17045,7 @@ msgstr "PASSO 1"
 #: flatcamTools/ToolSolderPaste.py:157
 #: flatcamTools/ToolSolderPaste.py:157
 msgid ""
 msgid ""
 "First step is to select a number of nozzle tools for usage\n"
 "First step is to select a number of nozzle tools for usage\n"
-"and then optionally modify the GCode parameters bellow."
+"and then optionally modify the GCode parameters below."
 msgstr ""
 msgstr ""
 "O primeiro passo é selecionar um número de ferramentas de bico para usar,\n"
 "O primeiro passo é selecionar um número de ferramentas de bico para usar,\n"
 "e opcionalmente, modificar os parâmetros do G-Code abaixo."
 "e opcionalmente, modificar os parâmetros do G-Code abaixo."
@@ -17286,7 +17286,7 @@ msgstr ""
 "do objeto Gerber de destino."
 "do objeto Gerber de destino."
 
 
 #: flatcamTools/ToolSub.py:100
 #: flatcamTools/ToolSub.py:100
-msgid "Substract Gerber"
+msgid "Subtract Gerber"
 msgstr "Subtrair Gerber"
 msgstr "Subtrair Gerber"
 
 
 #: flatcamTools/ToolSub.py:102
 #: flatcamTools/ToolSub.py:102
@@ -20225,7 +20225,7 @@ msgstr "Nenhum nome de geometria nos argumentos. Altere e tente novamente."
 #~ msgid "Generating panel ... Please wait."
 #~ msgid "Generating panel ... Please wait."
 #~ msgstr "Gerando painel ... Por favor, aguarde."
 #~ msgstr "Gerando painel ... Por favor, aguarde."
 
 
-#~ msgid "...proccessing... [%s]"
+#~ msgid "...processing... [%s]"
 #~ msgstr "...processando... [%s]"
 #~ msgstr "...processando... [%s]"
 
 
 #~ msgid "Parsing aperture %s geometry ..."
 #~ msgid "Parsing aperture %s geometry ..."

+ 3 - 3
locale/ro/LC_MESSAGES/strings.po

@@ -17265,7 +17265,7 @@ msgstr "PAS 1"
 #: flatcamTools/ToolSolderPaste.py:157
 #: flatcamTools/ToolSolderPaste.py:157
 msgid ""
 msgid ""
 "First step is to select a number of nozzle tools for usage\n"
 "First step is to select a number of nozzle tools for usage\n"
-"and then optionally modify the GCode parameters bellow."
+"and then optionally modify the GCode parameters below."
 msgstr ""
 msgstr ""
 "Primul pas este să se efectueza o selecţie de unelte Nozzl pt \n"
 "Primul pas este să se efectueza o selecţie de unelte Nozzl pt \n"
 "utilizare și apoi in mod optional, să se modifice parametrii\n"
 "utilizare și apoi in mod optional, să se modifice parametrii\n"
@@ -17512,7 +17512,7 @@ msgstr ""
 "obiectul Gerber tintă."
 "obiectul Gerber tintă."
 
 
 #: flatcamTools/ToolSub.py:100
 #: flatcamTools/ToolSub.py:100
-msgid "Substract Gerber"
+msgid "Subtract Gerber"
 msgstr "Execută"
 msgstr "Execută"
 
 
 #: flatcamTools/ToolSub.py:102
 #: flatcamTools/ToolSub.py:102
@@ -20553,7 +20553,7 @@ msgstr ""
 #~ msgid "Generating panel ... Please wait."
 #~ msgid "Generating panel ... Please wait."
 #~ msgstr "Se generează panelul ... Va rugăm asteptati."
 #~ msgstr "Se generează panelul ... Va rugăm asteptati."
 
 
-#~ msgid "...proccessing... [%s]"
+#~ msgid "...processing... [%s]"
 #~ msgstr "...in procesare... [%s]"
 #~ msgstr "...in procesare... [%s]"
 
 
 #~ msgid "Parsing aperture %s geometry ..."
 #~ msgid "Parsing aperture %s geometry ..."

+ 3 - 3
locale/ru/LC_MESSAGES/strings.po

@@ -17107,7 +17107,7 @@ msgstr "ШАГ 1"
 #: flatcamTools/ToolSolderPaste.py:157
 #: flatcamTools/ToolSolderPaste.py:157
 msgid ""
 msgid ""
 "First step is to select a number of nozzle tools for usage\n"
 "First step is to select a number of nozzle tools for usage\n"
-"and then optionally modify the GCode parameters bellow."
+"and then optionally modify the GCode parameters below."
 msgstr ""
 msgstr ""
 "Первый шаг - выбрать несколько инструментов для использования насадок.\n"
 "Первый шаг - выбрать несколько инструментов для использования насадок.\n"
 "а затем при необходимости измените параметры кода G ниже."
 "а затем при необходимости измените параметры кода G ниже."
@@ -17349,7 +17349,7 @@ msgstr ""
 "из целевого Gerber объекта."
 "из целевого Gerber объекта."
 
 
 #: flatcamTools/ToolSub.py:100
 #: flatcamTools/ToolSub.py:100
-msgid "Substract Gerber"
+msgid "Subtract Gerber"
 msgstr "Вычесть Gerber"
 msgstr "Вычесть Gerber"
 
 
 #: flatcamTools/ToolSub.py:102
 #: flatcamTools/ToolSub.py:102
@@ -20369,7 +20369,7 @@ msgstr "Нет имени геометрии в аргументах. Укажи
 #~ msgid "Generating panel ... Please wait."
 #~ msgid "Generating panel ... Please wait."
 #~ msgstr "Выполняется панелизация ... Пожалуйста, подождите."
 #~ msgstr "Выполняется панелизация ... Пожалуйста, подождите."
 
 
-#~ msgid "...proccessing... [%s]"
+#~ msgid "...processing... [%s]"
 #~ msgstr "...обработка... [%s]"
 #~ msgstr "...обработка... [%s]"
 
 
 #~ msgid "Parsing aperture %s geometry ..."
 #~ msgid "Parsing aperture %s geometry ..."

+ 3 - 3
locale_template/strings.pot

@@ -6789,7 +6789,7 @@ msgstr ""
 #: flatcamGUI/ObjectUI.py:436
 #: flatcamGUI/ObjectUI.py:436
 msgid ""
 msgid ""
 "When the isolation geometry is generated,\n"
 "When the isolation geometry is generated,\n"
-"by checking this, the area of the object bellow\n"
+"by checking this, the area of the object below\n"
 "will be subtracted from the isolation geometry."
 "will be subtracted from the isolation geometry."
 msgstr ""
 msgstr ""
 
 
@@ -14604,7 +14604,7 @@ msgstr ""
 #: flatcamTools/ToolSolderPaste.py:158
 #: flatcamTools/ToolSolderPaste.py:158
 msgid ""
 msgid ""
 "First step is to select a number of nozzle tools for usage\n"
 "First step is to select a number of nozzle tools for usage\n"
-"and then optionally modify the GCode parameters bellow."
+"and then optionally modify the GCode parameters below."
 msgstr ""
 msgstr ""
 
 
 #: flatcamTools/ToolSolderPaste.py:161
 #: flatcamTools/ToolSolderPaste.py:161
@@ -14800,7 +14800,7 @@ msgid ""
 msgstr ""
 msgstr ""
 
 
 #: flatcamTools/ToolSub.py:100
 #: flatcamTools/ToolSub.py:100
-msgid "Substract Gerber"
+msgid "Subtract Gerber"
 msgstr ""
 msgstr ""
 
 
 #: flatcamTools/ToolSub.py:102
 #: flatcamTools/ToolSub.py:102

+ 1 - 1
tclCommands/TclCommandJoinExcellon.py

@@ -34,7 +34,7 @@ class TclCommandJoinExcellon(TclCommand):
     help = {
     help = {
         'main': "Runs a merge operation (join) on the Excellon objects.\n"
         'main': "Runs a merge operation (join) on the Excellon objects.\n"
                 "The names of the Excellon objects to be merged will be entered after the outname,\n"
                 "The names of the Excellon objects to be merged will be entered after the outname,\n"
-                "separated by spaces. See the example bellow.\n"
+                "separated by spaces. See the example below.\n"
                 "WARNING: if the name of an Excellon objects has spaces, enclose the name with quotes.",
                 "WARNING: if the name of an Excellon objects has spaces, enclose the name with quotes.",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
             ('outname', 'Name of the new Excellon Object made by joining of other Excellon objects. Required'),
             ('outname', 'Name of the new Excellon Object made by joining of other Excellon objects. Required'),

+ 1 - 1
tclCommands/TclCommandJoinGeometry.py

@@ -34,7 +34,7 @@ class TclCommandJoinGeometry(TclCommand):
     help = {
     help = {
         'main': "Runs a merge operation (join) on the Geometry objects.\n"
         'main': "Runs a merge operation (join) on the Geometry objects.\n"
                 "The names of the Geometry objects to be merged will be entered after the outname,\n"
                 "The names of the Geometry objects to be merged will be entered after the outname,\n"
-                "separated by spaces. See the example bellow.\n"
+                "separated by spaces. See the example below.\n"
                 "WARNING: if the name of an Geometry objects has spaces, enclose the name with quotes.",
                 "WARNING: if the name of an Geometry objects has spaces, enclose the name with quotes.",
         'args': collections.OrderedDict([
         'args': collections.OrderedDict([
             ('outname', 'Name of the new Geometry Object made by joining of other Geometry objects. Required'),
             ('outname', 'Name of the new Geometry Object made by joining of other Geometry objects. Required'),