diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0b4d0dfd..19054283 100644
--- a/CHANGELOG.md
+++ b/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 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
+- 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
diff --git a/FlatCAMApp.py b/FlatCAMApp.py
index 49cc7d0f..5157f436 100644
--- a/FlatCAMApp.py
+++ b/FlatCAMApp.py
@@ -4111,9 +4111,11 @@ class App(QtCore.QObject):
obj.multigeo = True
for tooluid, dict_value in obj.tools.items():
dict_value['solid_geometry'] = deepcopy(obj.solid_geometry)
+
if not isinstance(obj.solid_geometry, list):
obj.solid_geometry = [obj.solid_geometry]
- obj.solid_geometry[:] = []
+
+ # obj.solid_geometry[:] = []
obj.plot()
self.should_we_save = True
@@ -5024,7 +5026,7 @@ class App(QtCore.QObject):
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
- # See description bellow.
+ # See description below.
def on_delete_keypress(self):
notebook_widget_name = self.ui.notebook.currentWidget().objectName()
diff --git a/flatcamEditors/FlatCAMExcEditor.py b/flatcamEditors/FlatCAMExcEditor.py
index 2f2e274c..49dc5eb5 100644
--- a/flatcamEditors/FlatCAMExcEditor.py
+++ b/flatcamEditors/FlatCAMExcEditor.py
@@ -3226,7 +3226,7 @@ class FlatCAMExcEditor(QtCore.QObject):
spec = {"C": float(tool_dia[0])}
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'] = []
# 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])}
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'] = []
# create the self.slots for the new Excellon object (the one with edited content)
diff --git a/flatcamGUI/FlatCAMGUI.py b/flatcamGUI/FlatCAMGUI.py
index 05c173df..c1b368b4 100644
--- a/flatcamGUI/FlatCAMGUI.py
+++ b/flatcamGUI/FlatCAMGUI.py
@@ -3232,7 +3232,7 @@ class FlatCAMGUI(QtWidgets.QMainWindow):
else:
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:
# make sure it works only for the Project Tab who is an instance of KeySensitiveListView
focused_wdg = QtWidgets.QApplication.focusWidget()
diff --git a/flatcamGUI/preferences/PreferencesUIManager.py b/flatcamGUI/preferences/PreferencesUIManager.py
index 7934cdc6..a8a9eab3 100644
--- a/flatcamGUI/preferences/PreferencesUIManager.py
+++ b/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
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)
self.defaults_form_fields = {
# General App
diff --git a/flatcamObjects/FlatCAMCNCJob.py b/flatcamObjects/FlatCAMCNCJob.py
index fa73b56c..c9a47076 100644
--- a/flatcamObjects/FlatCAMCNCJob.py
+++ b/flatcamObjects/FlatCAMCNCJob.py
@@ -364,7 +364,7 @@ class CNCJobObject(FlatCAMObj, CNCjob):
self.units_found = self.app.defaults['units']
# 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.form_fields.update({
diff --git a/flatcamParsers/ParseExcellon.py b/flatcamParsers/ParseExcellon.py
index ab52e44a..07930005 100644
--- a/flatcamParsers/ParseExcellon.py
+++ b/flatcamParsers/ParseExcellon.py
@@ -426,7 +426,7 @@ class Excellon(Geometry):
# it's possible that tool definition has only tool number and no diameter info
# (those could be in another file like PCB Wizard do)
# 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
self.diameterless = True
self.app.inform.emit('[WARNING] %s%s %s' %
diff --git a/flatcamTools/ToolCutOut.py b/flatcamTools/ToolCutOut.py
index 5f7083d8..31f51b31 100644
--- a/flatcamTools/ToolCutOut.py
+++ b/flatcamTools/ToolCutOut.py
@@ -293,12 +293,12 @@ class CutOut(FlatCAMTool):
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.setFrameShape(QtWidgets.QFrame.HLine)
separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
- grid0.addWidget(separator_line, 21, 0, 1, 2)
+ grid0.addWidget(separator_line, 22, 0, 1, 2)
# Title5
title_manual_label = QtWidgets.QLabel("%s" % _('B. Manual Bridge Gaps'))
@@ -307,7 +307,7 @@ class CutOut(FlatCAMTool):
"This is done by mouse clicking on the perimeter of the\n"
"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
self.man_object_combo = FCComboBox()
@@ -322,8 +322,8 @@ class CutOut(FlatCAMTool):
)
# 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.setToolTip(
@@ -338,7 +338,7 @@ class CutOut(FlatCAMTool):
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.setToolTip(
@@ -354,7 +354,7 @@ class CutOut(FlatCAMTool):
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()
@@ -394,6 +394,9 @@ class CutOut(FlatCAMTool):
self.x_pos = None
self.y_pos = None
+ # store the default data for the resulting Geometry Object
+ self.default_data = {}
+
# Signals
self.ff_cutout_object_btn.clicked.connect(self.on_freeform_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.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):
log.debug("Cutout.on_freeform_cutout() was launched ...")
@@ -622,8 +667,8 @@ class CutOut(FlatCAMTool):
solid_geo += cutout_handler(geom=geom_struct)
- geo_obj.solid_geometry = deepcopy(solid_geo)
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['ymin'] = ymin
geo_obj.options['xmax'] = xmax
@@ -633,6 +678,23 @@ class CutOut(FlatCAMTool):
geo_obj.options['multidepth'] = self.mpass_cb.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"
self.app.new_object('geometry', outname, geo_init)
@@ -759,6 +821,7 @@ class CutOut(FlatCAMTool):
return proc_geometry
if kind == 'single':
+ # fuse the lines
object_geo = unary_union(object_geo)
xmin, ymin, xmax, ymax = object_geo.bounds
@@ -805,11 +868,28 @@ class CutOut(FlatCAMTool):
_("Rectangular cutout with negative margin is not possible."))
return "fail"
- geo_obj.solid_geometry = deepcopy(solid_geo)
geo_obj.options['cnctooldia'] = str(dia)
geo_obj.options['cutz'] = self.cutz_entry.get_value()
geo_obj.options['multidepth'] = self.mpass_cb.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"
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['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"
self.app.new_object('geometry', outname, geo_init)
diff --git a/flatcamTools/ToolPanelize.py b/flatcamTools/ToolPanelize.py
index 4195e303..8995da05 100644
--- a/flatcamTools/ToolPanelize.py
+++ b/flatcamTools/ToolPanelize.py
@@ -14,6 +14,8 @@ from copy import deepcopy
import numpy as np
import shapely.affinity as affinity
+from shapely.ops import unary_union
+from shapely.geometry import LineString
import gettext
import FlatCAMTranslation as fcTranslate
@@ -402,19 +404,18 @@ class Panelize(FlatCAMTool):
def on_panelize(self):
name = self.object_combo.currentText()
- # Get source object.
+ # Get source object to be panelized.
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:
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
- if panel_obj is None:
+ if panel_source_obj is None:
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()
@@ -422,17 +423,15 @@ class Panelize(FlatCAMTool):
box = self.app.collection.get_by_name(boxname)
except Exception as 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
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')
if self.reference_radio.get_value() == 'bbox':
- box = panel_obj
+ box = panel_source_obj
self.outname = name + '_panelized'
@@ -478,20 +477,20 @@ class Panelize(FlatCAMTool):
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
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)
- if panel_obj.kind == 'gerber':
+ if panel_source_obj.kind == 'gerber':
# make a copy of the panelized Gerber 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)
- 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 ... "))
def job_init_excellon(obj_fin, app_obj):
@@ -501,15 +500,15 @@ class Panelize(FlatCAMTool):
obj_fin.slots = []
obj_fin.solid_geometry = []
- for option in panel_obj.options:
+ for option in panel_source_obj.options:
if option != 'name':
try:
- obj_fin.options[option] = panel_obj.options[option]
+ obj_fin.options[option] = panel_source_obj.options[option]
except KeyError:
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
for row in range(rows):
@@ -518,9 +517,9 @@ class Panelize(FlatCAMTool):
element += 1
old_disp_number = 0
- if panel_obj.drills:
+ if panel_source_obj.drills:
drill_nr = 0
- for tool_dict in panel_obj.drills:
+ for tool_dict in panel_source_obj.drills:
if self.app.abort_flag:
# graceful abort requested by the user
raise grace
@@ -543,9 +542,9 @@ class Panelize(FlatCAMTool):
disp_number))
old_disp_number = disp_number
- if panel_obj.slots:
+ if panel_source_obj.slots:
slot_nr = 0
- for tool_dict in panel_obj.slots:
+ for tool_dict in panel_source_obj.slots:
if self.app.abort_flag:
# graceful abort requested by the user
raise grace
@@ -574,8 +573,8 @@ class Panelize(FlatCAMTool):
currenty += lenghty
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('')
def job_init_geometry(obj_fin, app_obj):
@@ -598,36 +597,36 @@ class Panelize(FlatCAMTool):
obj_fin.solid_geometry = []
# 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
- 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'][:] = []
- elif panel_obj.kind == 'gerber':
+ elif panel_source_obj.kind == 'gerber':
obj_fin.apertures = copied_apertures
for ap in obj_fin.apertures:
obj_fin.apertures[ap]['geometry'] = []
# find the number of polygons in the source solid_geometry
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:
- geo_len += len(panel_obj.tools[tool]['solid_geometry'])
+ geo_len += len(panel_source_obj.tools[tool]['solid_geometry'])
except TypeError:
geo_len += 1
else:
try:
- geo_len = len(panel_obj.solid_geometry)
+ geo_len = len(panel_source_obj.solid_geometry)
except TypeError:
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:
- geo_len += len(panel_obj.apertures[ap]['geometry'])
+ geo_len += len(panel_source_obj.apertures[ap]['geometry'])
except TypeError:
geo_len += 1
@@ -639,29 +638,23 @@ class Panelize(FlatCAMTool):
element += 1
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:
# graceful abort requested by the user
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
- geo_len = len(panel_obj.tools[tool]['solid_geometry'])
+ geo_len = len(panel_source_obj.tools[tool]['solid_geometry'])
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)
obj_fin.tools[tool]['solid_geometry'].append(trans_geo)
pol_nr += 1
disp_number = int(np.interp(pol_nr, [0, geo_len], [0, 100]))
-
if old_disp_number < disp_number <= 100:
self.app.proc_container.update_view_text(' %s: %d %d%%' %
(_("Copy"),
@@ -669,23 +662,18 @@ class Panelize(FlatCAMTool):
disp_number))
old_disp_number = disp_number
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:
# graceful abort requested by the user
raise grace
try:
# calculate the number of polygons
- geo_len = len(panel_obj.solid_geometry)
+ geo_len = len(panel_source_obj.solid_geometry)
except TypeError:
geo_len = 1
pol_nr = 0
try:
- for geo_el in panel_obj.solid_geometry:
+ for geo_el in panel_source_obj.solid_geometry:
if self.app.abort_flag:
# graceful abort requested by the user
raise grace
@@ -702,21 +690,18 @@ class Panelize(FlatCAMTool):
int(element),
disp_number))
old_disp_number = disp_number
+
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)
+ # Will panelize a Gerber Object
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:
# graceful abort requested by the user
raise grace
try:
- for geo_el in panel_obj.solid_geometry:
+ for geo_el in panel_source_obj.solid_geometry:
if self.app.abort_flag:
# graceful abort requested by the user
raise grace
@@ -724,21 +709,21 @@ class Panelize(FlatCAMTool):
trans_geo = translate_recursion(geo_el)
obj_fin.solid_geometry.append(trans_geo)
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)
- for apid in panel_obj.apertures:
+ for apid in panel_source_obj.apertures:
if self.app.abort_flag:
# graceful abort requested by the user
raise grace
- if 'geometry' in panel_obj.apertures[apid]:
+ if 'geometry' in panel_source_obj.apertures[apid]:
try:
# calculate the number of polygons
- geo_len = len(panel_obj.apertures[apid]['geometry'])
+ geo_len = len(panel_source_obj.apertures[apid]['geometry'])
except TypeError:
geo_len = 1
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:
# graceful abort requested by the user
raise grace
@@ -771,20 +756,34 @@ class Panelize(FlatCAMTool):
currentx += lenghtx
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':
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,
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)
# app_obj.log.debug("Finished creating a cascaded union for the panel.")
self.app.proc_container.update_view_text('')
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)
else:
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):
try:
- panelize_2()
+ panelize_worker()
self.app.inform.emit('[success] %s' % _("Panel created successfully."))
except Exception as ee:
proc.done()
diff --git a/flatcamTools/ToolSolderPaste.py b/flatcamTools/ToolSolderPaste.py
index f77c2a98..93cb4744 100644
--- a/flatcamTools/ToolSolderPaste.py
+++ b/flatcamTools/ToolSolderPaste.py
@@ -155,7 +155,7 @@ class SolderPaste(FlatCAMTool):
step1_lbl = QtWidgets.QLabel("%s:" % _('STEP 1'))
step1_lbl.setToolTip(
_("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"
"Modify parameters."))
diff --git a/flatcamTools/ToolSub.py b/flatcamTools/ToolSub.py
index ef826a0f..5409fa76 100644
--- a/flatcamTools/ToolSub.py
+++ b/flatcamTools/ToolSub.py
@@ -97,7 +97,7 @@ class ToolSub(FlatCAMTool):
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(
_("Will remove the area occupied by the subtractor\n"
"Gerber from the Target Gerber.\n"
diff --git a/locale/de/LC_MESSAGES/strings.po b/locale/de/LC_MESSAGES/strings.po
index 326937b3..1e37e6cb 100644
--- a/locale/de/LC_MESSAGES/strings.po
+++ b/locale/de/LC_MESSAGES/strings.po
@@ -17325,7 +17325,7 @@ msgstr "SCHRITT 1"
#: flatcamTools/ToolSolderPaste.py:157
msgid ""
"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 ""
"Zunächst müssen Sie eine Reihe von Düsenwerkzeugen auswählen\n"
"und ändern Sie dann optional die GCode-Parameter."
@@ -17565,7 +17565,7 @@ msgstr ""
"vom Zielobjekt Gerber."
#: flatcamTools/ToolSub.py:100
-msgid "Substract Gerber"
+msgid "Subtract Gerber"
msgstr "Gerber abziehen"
#: flatcamTools/ToolSub.py:102
@@ -20547,7 +20547,7 @@ msgstr ""
#~ msgid "[success] Paint Area Done."
#~ msgstr "[success] Lackierbereich fertig."
-#~ msgid "...proccessing... [%s]"
+#~ msgid "...processing... [%s]"
#~ msgstr "...wird bearbeitet...[%s]"
#~ msgid "Parsing aperture %s geometry ..."
diff --git a/locale/en/LC_MESSAGES/strings.po b/locale/en/LC_MESSAGES/strings.po
index 161975b5..83a3b193 100644
--- a/locale/en/LC_MESSAGES/strings.po
+++ b/locale/en/LC_MESSAGES/strings.po
@@ -16981,10 +16981,10 @@ msgstr "STEP 1"
#: flatcamTools/ToolSolderPaste.py:157
msgid ""
"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 ""
"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
msgid ""
@@ -17216,8 +17216,8 @@ msgstr ""
"from the target Gerber object."
#: flatcamTools/ToolSub.py:100
-msgid "Substract Gerber"
-msgstr "Substract Gerber"
+msgid "Subtract Gerber"
+msgstr "Subtract Gerber"
#: flatcamTools/ToolSub.py:102
msgid ""
@@ -20512,8 +20512,8 @@ msgstr "No Geometry name in args. Provide a name and try again."
#~ msgid "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 ..."
#~ msgstr "Parsing aperture %s geometry ..."
diff --git a/locale/es/LC_MESSAGES/strings.po b/locale/es/LC_MESSAGES/strings.po
index 1f495e05..21152ba5 100644
--- a/locale/es/LC_MESSAGES/strings.po
+++ b/locale/es/LC_MESSAGES/strings.po
@@ -17257,7 +17257,7 @@ msgstr "PASO 1"
#: flatcamTools/ToolSolderPaste.py:157
msgid ""
"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 ""
"El primer paso es seleccionar una serie de herramientas de boquillas para su "
"uso\n"
@@ -17502,7 +17502,7 @@ msgstr ""
"del objeto objetivo de Gerber."
#: flatcamTools/ToolSub.py:100
-msgid "Substract Gerber"
+msgid "Subtract Gerber"
msgstr "Restar Gerber"
#: flatcamTools/ToolSub.py:102
@@ -19224,7 +19224,7 @@ msgstr ""
#~ msgid "[success] Paint Area Done."
#~ msgstr "[éxito] Área de pintura realizada."
-#~ msgid "...proccessing... [%s]"
+#~ msgid "...processing... [%s]"
#~ msgstr "... procesando ... [% s]"
#~ msgid "Parsing aperture %s geometry ..."
diff --git a/locale/fr/LC_MESSAGES/strings.po b/locale/fr/LC_MESSAGES/strings.po
index 2b9beb3c..82d6a131 100644
--- a/locale/fr/LC_MESSAGES/strings.po
+++ b/locale/fr/LC_MESSAGES/strings.po
@@ -17254,7 +17254,7 @@ msgstr "ÉTAPE 1"
#: flatcamTools/ToolSolderPaste.py:157
msgid ""
"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 ""
"La première étape consiste à sélectionner un certain nombre d’outils de buse "
"à utiliser.\n"
@@ -17498,7 +17498,7 @@ msgstr ""
"à partir de l'objet Gerber cible."
#: flatcamTools/ToolSub.py:100
-msgid "Substract Gerber"
+msgid "Subtract Gerber"
msgstr "Soustraire Gerber"
#: flatcamTools/ToolSub.py:102
diff --git a/locale/hu/LC_MESSAGES/strings.po b/locale/hu/LC_MESSAGES/strings.po
index bd24dcc7..950d8d23 100644
--- a/locale/hu/LC_MESSAGES/strings.po
+++ b/locale/hu/LC_MESSAGES/strings.po
@@ -7235,11 +7235,11 @@ msgstr "Except"
#: flatcamGUI/ObjectUI.py:436
msgid ""
"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."
msgstr ""
"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."
#: flatcamGUI/ObjectUI.py:449 flatcamGUI/PreferencesUI.py:6527
@@ -16986,10 +16986,10 @@ msgstr "STEP 1"
#: flatcamTools/ToolSolderPaste.py:157
msgid ""
"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 ""
"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
msgid ""
@@ -17221,8 +17221,8 @@ msgstr ""
"from the target Gerber object."
#: flatcamTools/ToolSub.py:100
-msgid "Substract Gerber"
-msgstr "Substract Gerber"
+msgid "Subtract Gerber"
+msgstr "Subtract Gerber"
#: flatcamTools/ToolSub.py:102
msgid ""
@@ -20477,8 +20477,8 @@ msgstr "No Geometry name in args. Provide a name and try again."
#~ msgid "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 ..."
#~ msgstr "Parsing aperture %s geometry ..."
diff --git a/locale/it/LC_MESSAGES/strings.po b/locale/it/LC_MESSAGES/strings.po
index bac53820..15b42fc6 100644
--- a/locale/it/LC_MESSAGES/strings.po
+++ b/locale/it/LC_MESSAGES/strings.po
@@ -6804,7 +6804,7 @@ msgstr ""
#: flatcamGUI/ObjectUI.py:431
msgid ""
"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."
msgstr ""
@@ -14198,7 +14198,7 @@ msgid "Violations: There are no violations for the current rule."
msgstr ""
#: flatcamTools/ToolShell.py:70 flatcamTools/ToolShell.py:72
-msgid "...proccessing..."
+msgid "...processing..."
msgstr ""
#: flatcamTools/ToolSolderPaste.py:37
@@ -14251,7 +14251,7 @@ msgstr ""
#: flatcamTools/ToolSolderPaste.py:156
msgid ""
"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 ""
#: flatcamTools/ToolSolderPaste.py:159
@@ -14452,7 +14452,7 @@ msgid ""
msgstr ""
#: flatcamTools/ToolSub.py:97
-msgid "Substract Gerber"
+msgid "Subtract Gerber"
msgstr ""
#: flatcamTools/ToolSub.py:99
diff --git a/locale/pt_BR/LC_MESSAGES/strings.po b/locale/pt_BR/LC_MESSAGES/strings.po
index b90a1858..386e81b4 100644
--- a/locale/pt_BR/LC_MESSAGES/strings.po
+++ b/locale/pt_BR/LC_MESSAGES/strings.po
@@ -17045,7 +17045,7 @@ msgstr "PASSO 1"
#: flatcamTools/ToolSolderPaste.py:157
msgid ""
"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 ""
"O primeiro passo é selecionar um número de ferramentas de bico para usar,\n"
"e opcionalmente, modificar os parâmetros do G-Code abaixo."
@@ -17286,7 +17286,7 @@ msgstr ""
"do objeto Gerber de destino."
#: flatcamTools/ToolSub.py:100
-msgid "Substract Gerber"
+msgid "Subtract Gerber"
msgstr "Subtrair Gerber"
#: flatcamTools/ToolSub.py:102
@@ -20225,7 +20225,7 @@ msgstr "Nenhum nome de geometria nos argumentos. Altere e tente novamente."
#~ msgid "Generating panel ... Please wait."
#~ msgstr "Gerando painel ... Por favor, aguarde."
-#~ msgid "...proccessing... [%s]"
+#~ msgid "...processing... [%s]"
#~ msgstr "...processando... [%s]"
#~ msgid "Parsing aperture %s geometry ..."
diff --git a/locale/ro/LC_MESSAGES/strings.po b/locale/ro/LC_MESSAGES/strings.po
index a2abeb59..f740e587 100644
--- a/locale/ro/LC_MESSAGES/strings.po
+++ b/locale/ro/LC_MESSAGES/strings.po
@@ -17265,7 +17265,7 @@ msgstr "PAS 1"
#: flatcamTools/ToolSolderPaste.py:157
msgid ""
"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 ""
"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"
@@ -17512,7 +17512,7 @@ msgstr ""
"obiectul Gerber tintă."
#: flatcamTools/ToolSub.py:100
-msgid "Substract Gerber"
+msgid "Subtract Gerber"
msgstr "Execută"
#: flatcamTools/ToolSub.py:102
@@ -20553,7 +20553,7 @@ msgstr ""
#~ msgid "Generating panel ... Please wait."
#~ msgstr "Se generează panelul ... Va rugăm asteptati."
-#~ msgid "...proccessing... [%s]"
+#~ msgid "...processing... [%s]"
#~ msgstr "...in procesare... [%s]"
#~ msgid "Parsing aperture %s geometry ..."
diff --git a/locale/ru/LC_MESSAGES/strings.po b/locale/ru/LC_MESSAGES/strings.po
index 4056ae5f..97a00a7c 100644
--- a/locale/ru/LC_MESSAGES/strings.po
+++ b/locale/ru/LC_MESSAGES/strings.po
@@ -17107,7 +17107,7 @@ msgstr "ШАГ 1"
#: flatcamTools/ToolSolderPaste.py:157
msgid ""
"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 ""
"Первый шаг - выбрать несколько инструментов для использования насадок.\n"
"а затем при необходимости измените параметры кода G ниже."
@@ -17349,7 +17349,7 @@ msgstr ""
"из целевого Gerber объекта."
#: flatcamTools/ToolSub.py:100
-msgid "Substract Gerber"
+msgid "Subtract Gerber"
msgstr "Вычесть Gerber"
#: flatcamTools/ToolSub.py:102
@@ -20369,7 +20369,7 @@ msgstr "Нет имени геометрии в аргументах. Укажи
#~ msgid "Generating panel ... Please wait."
#~ msgstr "Выполняется панелизация ... Пожалуйста, подождите."
-#~ msgid "...proccessing... [%s]"
+#~ msgid "...processing... [%s]"
#~ msgstr "...обработка... [%s]"
#~ msgid "Parsing aperture %s geometry ..."
diff --git a/locale_template/strings.pot b/locale_template/strings.pot
index f195910d..4e2b0c0e 100644
--- a/locale_template/strings.pot
+++ b/locale_template/strings.pot
@@ -6789,7 +6789,7 @@ msgstr ""
#: flatcamGUI/ObjectUI.py:436
msgid ""
"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."
msgstr ""
@@ -14604,7 +14604,7 @@ msgstr ""
#: flatcamTools/ToolSolderPaste.py:158
msgid ""
"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 ""
#: flatcamTools/ToolSolderPaste.py:161
@@ -14800,7 +14800,7 @@ msgid ""
msgstr ""
#: flatcamTools/ToolSub.py:100
-msgid "Substract Gerber"
+msgid "Subtract Gerber"
msgstr ""
#: flatcamTools/ToolSub.py:102
diff --git a/tclCommands/TclCommandJoinExcellon.py b/tclCommands/TclCommandJoinExcellon.py
index e2a209d1..5c1962ff 100644
--- a/tclCommands/TclCommandJoinExcellon.py
+++ b/tclCommands/TclCommandJoinExcellon.py
@@ -34,7 +34,7 @@ class TclCommandJoinExcellon(TclCommand):
help = {
'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"
- "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.",
'args': collections.OrderedDict([
('outname', 'Name of the new Excellon Object made by joining of other Excellon objects. Required'),
diff --git a/tclCommands/TclCommandJoinGeometry.py b/tclCommands/TclCommandJoinGeometry.py
index 52fa83fa..67e3aeb5 100644
--- a/tclCommands/TclCommandJoinGeometry.py
+++ b/tclCommands/TclCommandJoinGeometry.py
@@ -34,7 +34,7 @@ class TclCommandJoinGeometry(TclCommand):
help = {
'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"
- "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.",
'args': collections.OrderedDict([
('outname', 'Name of the new Geometry Object made by joining of other Geometry objects. Required'),