- updated the ToolPanelize tool so the Gerber panel of type FlatCAMGerber can be isolated like any other FlatCAMGerber object
- updated the ToolPanelize tool so it can be edited
This commit is contained in:
@@ -17,6 +17,8 @@ CAD program, and create G-Code for Isolation routing.
|
||||
- fixed some bugs related to moving an Gerber object with the aperture table in view
|
||||
- added a new parameter in the Edit -> Preferences -> App Preferences named Geo Tolerance. This parameter control the level of geometric detail throughout FlatCAM. It directly influence the effect of Circle Steps parameter.
|
||||
- solved a bug in Excellon Editor that caused app crash when trying to edit a tool in Tool Table due of missing a tool offset
|
||||
- updated the ToolPanelize tool so the Gerber panel of type FlatCAMGerber can be isolated like any other FlatCAMGerber object
|
||||
- updated the ToolPanelize tool so it can be edited
|
||||
|
||||
5.05.2019
|
||||
|
||||
|
||||
@@ -13,9 +13,9 @@ import time
|
||||
|
||||
import gettext
|
||||
import FlatCAMTranslation as fcTranslate
|
||||
import builtins
|
||||
|
||||
fcTranslate.apply_language('strings')
|
||||
import builtins
|
||||
if '_' not in builtins.__dict__:
|
||||
_ = gettext.gettext
|
||||
|
||||
@@ -39,11 +39,11 @@ class Panelize(FlatCAMTool):
|
||||
""")
|
||||
self.layout.addWidget(title_label)
|
||||
|
||||
## Form Layout
|
||||
# Form Layout
|
||||
form_layout = QtWidgets.QFormLayout()
|
||||
self.layout.addLayout(form_layout)
|
||||
|
||||
## Type of object to be panelized
|
||||
# Type of object to be panelized
|
||||
self.type_obj_combo = QtWidgets.QComboBox()
|
||||
self.type_obj_combo.addItem("Gerber")
|
||||
self.type_obj_combo.addItem("Excellon")
|
||||
@@ -56,13 +56,13 @@ class Panelize(FlatCAMTool):
|
||||
self.type_obj_combo_label = QtWidgets.QLabel(_("Object Type:"))
|
||||
self.type_obj_combo_label.setToolTip(
|
||||
_("Specify the type of object to be panelized\n"
|
||||
"It can be of type: Gerber, Excellon or Geometry.\n"
|
||||
"The selection here decide the type of objects that will be\n"
|
||||
"in the Object combobox.")
|
||||
"It can be of type: Gerber, Excellon or Geometry.\n"
|
||||
"The selection here decide the type of objects that will be\n"
|
||||
"in the Object combobox.")
|
||||
)
|
||||
form_layout.addRow(self.type_obj_combo_label, self.type_obj_combo)
|
||||
|
||||
## Object to be panelized
|
||||
# Object to be panelized
|
||||
self.object_combo = QtWidgets.QComboBox()
|
||||
self.object_combo.setModel(self.app.collection)
|
||||
self.object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
|
||||
@@ -71,11 +71,11 @@ class Panelize(FlatCAMTool):
|
||||
self.object_label = QtWidgets.QLabel(_("Object:"))
|
||||
self.object_label.setToolTip(
|
||||
_("Object to be panelized. This means that it will\n"
|
||||
"be duplicated in an array of rows and columns.")
|
||||
"be duplicated in an array of rows and columns.")
|
||||
)
|
||||
form_layout.addRow(self.object_label, self.object_combo)
|
||||
|
||||
## Type of Box Object to be used as an envelope for panelization
|
||||
# Type of Box Object to be used as an envelope for panelization
|
||||
self.type_box_combo = QtWidgets.QComboBox()
|
||||
self.type_box_combo.addItem("Gerber")
|
||||
self.type_box_combo.addItem("Excellon")
|
||||
@@ -89,13 +89,13 @@ class Panelize(FlatCAMTool):
|
||||
self.type_box_combo_label = QtWidgets.QLabel(_("Box Type:"))
|
||||
self.type_box_combo_label.setToolTip(
|
||||
_("Specify the type of object to be used as an container for\n"
|
||||
"panelization. It can be: Gerber or Geometry type.\n"
|
||||
"The selection here decide the type of objects that will be\n"
|
||||
"in the Box Object combobox.")
|
||||
"panelization. It can be: Gerber or Geometry type.\n"
|
||||
"The selection here decide the type of objects that will be\n"
|
||||
"in the Box Object combobox.")
|
||||
)
|
||||
form_layout.addRow(self.type_box_combo_label, self.type_box_combo)
|
||||
|
||||
## Box
|
||||
# Box
|
||||
self.box_combo = QtWidgets.QComboBox()
|
||||
self.box_combo.setModel(self.app.collection)
|
||||
self.box_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
|
||||
@@ -104,29 +104,29 @@ class Panelize(FlatCAMTool):
|
||||
self.box_combo_label = QtWidgets.QLabel(_("Box Object:"))
|
||||
self.box_combo_label.setToolTip(
|
||||
_("The actual object that is used a container for the\n "
|
||||
"selected object that is to be panelized.")
|
||||
"selected object that is to be panelized.")
|
||||
)
|
||||
form_layout.addRow(self.box_combo_label, self.box_combo)
|
||||
|
||||
## Spacing Columns
|
||||
# Spacing Columns
|
||||
self.spacing_columns = FCEntry()
|
||||
self.spacing_columns_label = QtWidgets.QLabel(_("Spacing cols:"))
|
||||
self.spacing_columns_label.setToolTip(
|
||||
_("Spacing between columns of the desired panel.\n"
|
||||
"In current units.")
|
||||
"In current units.")
|
||||
)
|
||||
form_layout.addRow(self.spacing_columns_label, self.spacing_columns)
|
||||
|
||||
## Spacing Rows
|
||||
# Spacing Rows
|
||||
self.spacing_rows = FCEntry()
|
||||
self.spacing_rows_label = QtWidgets.QLabel(_("Spacing rows:"))
|
||||
self.spacing_rows_label.setToolTip(
|
||||
_("Spacing between rows of the desired panel.\n"
|
||||
"In current units.")
|
||||
"In current units.")
|
||||
)
|
||||
form_layout.addRow(self.spacing_rows_label, self.spacing_rows)
|
||||
|
||||
## Columns
|
||||
# Columns
|
||||
self.columns = FCEntry()
|
||||
self.columns_label = QtWidgets.QLabel(_("Columns:"))
|
||||
self.columns_label.setToolTip(
|
||||
@@ -134,7 +134,7 @@ class Panelize(FlatCAMTool):
|
||||
)
|
||||
form_layout.addRow(self.columns_label, self.columns)
|
||||
|
||||
## Rows
|
||||
# Rows
|
||||
self.rows = FCEntry()
|
||||
self.rows_label = QtWidgets.QLabel(_("Rows:"))
|
||||
self.rows_label.setToolTip(
|
||||
@@ -142,26 +142,26 @@ class Panelize(FlatCAMTool):
|
||||
)
|
||||
form_layout.addRow(self.rows_label, self.rows)
|
||||
|
||||
## Type of resulting Panel object
|
||||
# Type of resulting Panel object
|
||||
self.panel_type_radio = RadioSet([{'label': 'Gerber', 'value': 'gerber'},
|
||||
{'label': 'Geometry', 'value': 'geometry'}])
|
||||
{'label': 'Geometry', 'value': 'geometry'}])
|
||||
self.panel_type_label = QtWidgets.QLabel(_("Panel Type:"))
|
||||
self.panel_type_label.setToolTip(
|
||||
_("Choose the type of object for the panel object:\n"
|
||||
"- Geometry\n"
|
||||
"- Gerber")
|
||||
"- Geometry\n"
|
||||
"- Gerber")
|
||||
)
|
||||
form_layout.addRow(self.panel_type_label)
|
||||
form_layout.addRow(self.panel_type_radio)
|
||||
|
||||
## Constrains
|
||||
# Constrains
|
||||
self.constrain_cb = FCCheckBox(_("Constrain panel within:"))
|
||||
self.constrain_cb.setToolTip(
|
||||
_("Area define by DX and DY within to constrain the panel.\n"
|
||||
"DX and DY values are in current units.\n"
|
||||
"Regardless of how many columns and rows are desired,\n"
|
||||
"the final panel will have as many columns and rows as\n"
|
||||
"they fit completely within selected area.")
|
||||
"DX and DY values are in current units.\n"
|
||||
"Regardless of how many columns and rows are desired,\n"
|
||||
"the final panel will have as many columns and rows as\n"
|
||||
"they fit completely within selected area.")
|
||||
)
|
||||
form_layout.addRow(self.constrain_cb)
|
||||
|
||||
@@ -169,7 +169,7 @@ class Panelize(FlatCAMTool):
|
||||
self.x_width_lbl = QtWidgets.QLabel(_("Width (DX):"))
|
||||
self.x_width_lbl.setToolTip(
|
||||
_("The width (DX) within which the panel must fit.\n"
|
||||
"In current units.")
|
||||
"In current units.")
|
||||
)
|
||||
form_layout.addRow(self.x_width_lbl, self.x_width_entry)
|
||||
|
||||
@@ -177,14 +177,14 @@ class Panelize(FlatCAMTool):
|
||||
self.y_height_lbl = QtWidgets.QLabel(_("Height (DY):"))
|
||||
self.y_height_lbl.setToolTip(
|
||||
_("The height (DY)within which the panel must fit.\n"
|
||||
"In current units.")
|
||||
"In current units.")
|
||||
)
|
||||
form_layout.addRow(self.y_height_lbl, self.y_height_entry)
|
||||
|
||||
self.constrain_sel = OptionalInputSection(
|
||||
self.constrain_cb, [self.x_width_lbl, self.x_width_entry, self.y_height_lbl, self.y_height_entry])
|
||||
|
||||
## Buttons
|
||||
# Buttons
|
||||
hlay_2 = QtWidgets.QHBoxLayout()
|
||||
self.layout.addLayout(hlay_2)
|
||||
|
||||
@@ -192,14 +192,14 @@ class Panelize(FlatCAMTool):
|
||||
self.panelize_object_button = QtWidgets.QPushButton(_("Panelize Object"))
|
||||
self.panelize_object_button.setToolTip(
|
||||
_("Panelize the specified object around the specified box.\n"
|
||||
"In other words it creates multiple copies of the source object,\n"
|
||||
"arranged in a 2D array of rows and columns.")
|
||||
"In other words it creates multiple copies of the source object,\n"
|
||||
"arranged in a 2D array of rows and columns.")
|
||||
)
|
||||
hlay_2.addWidget(self.panelize_object_button)
|
||||
|
||||
self.layout.addStretch()
|
||||
|
||||
## Signals
|
||||
# Signals
|
||||
self.panelize_object_button.clicked.connect(self.on_panelize)
|
||||
self.type_obj_combo.currentIndexChanged.connect(self.on_type_obj_index_changed)
|
||||
self.type_box_combo.currentIndexChanged.connect(self.on_type_box_index_changed)
|
||||
@@ -387,7 +387,6 @@ class Panelize(FlatCAMTool):
|
||||
|
||||
panel_type = str(self.panel_type_radio.get_value())
|
||||
|
||||
|
||||
if 0 in {columns, rows}:
|
||||
self.app.inform.emit(_("[ERROR_NOTCL] Columns or Rows are zero value. Change them to a positive integer."))
|
||||
return "Columns or Rows are zero value. Change them to a positive integer."
|
||||
@@ -471,7 +470,11 @@ class Panelize(FlatCAMTool):
|
||||
if type(geom) == list:
|
||||
geoms = list()
|
||||
for local_geom in geom:
|
||||
geoms.append(translate_recursion(local_geom))
|
||||
res_geo = translate_recursion(local_geom)
|
||||
try:
|
||||
geoms += (res_geo)
|
||||
except TypeError:
|
||||
geoms.append(res_geo)
|
||||
return geoms
|
||||
else:
|
||||
return affinity.translate(geom, xoff=currentx, yoff=currenty)
|
||||
@@ -485,6 +488,16 @@ class Panelize(FlatCAMTool):
|
||||
for tool in panel_obj.tools:
|
||||
obj_fin.tools[tool]['solid_geometry'][:] = []
|
||||
|
||||
if isinstance(panel_obj, FlatCAMGerber):
|
||||
obj_fin.apertures = deepcopy(panel_obj.apertures)
|
||||
for ap in obj_fin.apertures:
|
||||
if 'solid_geometry' in obj_fin.apertures[ap]:
|
||||
obj_fin.apertures[ap]['solid_geometry'] = []
|
||||
if 'clear_geometry' in obj_fin.apertures[ap]:
|
||||
obj_fin.apertures[ap]['clear_geometry'] = []
|
||||
if 'follow_geometry' in obj_fin.apertures[ap]:
|
||||
obj_fin.apertures[ap]['follow_geometry'] = []
|
||||
|
||||
self.app.progress.emit(0)
|
||||
for row in range(rows):
|
||||
currentx = 0.0
|
||||
@@ -493,21 +506,54 @@ class Panelize(FlatCAMTool):
|
||||
if isinstance(panel_obj, FlatCAMGeometry):
|
||||
if panel_obj.multigeo is True:
|
||||
for tool in panel_obj.tools:
|
||||
obj_fin.tools[tool]['solid_geometry'].append(translate_recursion(
|
||||
panel_obj.tools[tool]['solid_geometry'])
|
||||
)
|
||||
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)
|
||||
else:
|
||||
obj_fin.solid_geometry.append(
|
||||
translate_recursion(panel_obj.solid_geometry)
|
||||
)
|
||||
geo = translate_recursion(panel_obj.solid_geometry)
|
||||
if isinstance(geo, list):
|
||||
obj_fin.solid_geometry += geo
|
||||
else:
|
||||
obj_fin.solid_geometry.append(geo)
|
||||
else:
|
||||
obj_fin.solid_geometry.append(
|
||||
translate_recursion(panel_obj.solid_geometry)
|
||||
)
|
||||
geo = translate_recursion(panel_obj.solid_geometry)
|
||||
if isinstance(geo, list):
|
||||
obj_fin.solid_geometry += geo
|
||||
else:
|
||||
obj_fin.solid_geometry.append(geo)
|
||||
|
||||
for apid in panel_obj.apertures:
|
||||
if 'solid_geometry' in panel_obj.apertures[apid]:
|
||||
geo_aper = translate_recursion(panel_obj.apertures[apid]['solid_geometry'])
|
||||
if isinstance(geo_aper, list):
|
||||
obj_fin.apertures[apid]['solid_geometry'] += geo_aper
|
||||
else:
|
||||
obj_fin.apertures[apid]['solid_geometry'].append(geo_aper)
|
||||
|
||||
if 'clear_geometry' in panel_obj.apertures[apid]:
|
||||
geo_aper = translate_recursion(panel_obj.apertures[apid]['clear_geometry'])
|
||||
if isinstance(geo_aper, list):
|
||||
obj_fin.apertures[apid]['clear_geometry'] += geo_aper
|
||||
else:
|
||||
obj_fin.apertures[apid]['clear_geometry'].append(geo_aper)
|
||||
|
||||
if 'follow_geometry' in panel_obj.apertures[apid]:
|
||||
geo_aper = translate_recursion(panel_obj.apertures[apid]['follow_geometry'])
|
||||
if isinstance(geo_aper, list):
|
||||
obj_fin.apertures[apid]['follow_geometry'] += geo_aper
|
||||
else:
|
||||
obj_fin.apertures[apid]['follow_geometry'].append(geo_aper)
|
||||
|
||||
currentx += lenghtx
|
||||
currenty += lenghty
|
||||
|
||||
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.")
|
||||
|
||||
if isinstance(panel_obj, FlatCAMExcellon):
|
||||
self.app.progress.emit(50)
|
||||
self.app.new_object("excellon", self.outname, job_init_excellon, plot=True, autoselected=True)
|
||||
@@ -520,7 +566,8 @@ class Panelize(FlatCAMTool):
|
||||
self.app.inform.emit(_("[success] Panel done..."))
|
||||
else:
|
||||
self.constrain_flag = False
|
||||
self.app.inform.emit(_("[WARNING] Too big for the constrain area. Final panel has {col} columns and {row} rows").format(
|
||||
self.app.inform.emit(_("[WARNING] Too big for the constrain area. "
|
||||
"Final panel has {col} columns and {row} rows").format(
|
||||
col=columns, row=rows))
|
||||
|
||||
proc = self.app.proc_container.new(_("Generating panel ... Please wait."))
|
||||
|
||||
Reference in New Issue
Block a user