flatcam/flatcamTools/ToolPanelize.py

653 lines
29 KiB
Python
Raw Normal View History

# ########################################################## ##
# FlatCAM: 2D Post-processing for Manufacturing #
# http://flatcam.org #
# File Author: Marius Adrian Stanciu (c) #
# Date: 3/10/2019 #
# MIT Licence #
# ########################################################## ##
2019-01-03 19:25:08 +00:00
from FlatCAMTool import FlatCAMTool
from copy import copy, deepcopy
from ObjectCollection import *
import time
2019-03-07 16:04:11 +00:00
import gettext
import FlatCAMTranslation as fcTranslate
import builtins
fcTranslate.apply_language('strings')
if '_' not in builtins.__dict__:
_ = gettext.gettext
2019-01-03 19:25:08 +00:00
class Panelize(FlatCAMTool):
toolName = _("Panelize PCB")
2019-01-03 19:25:08 +00:00
def __init__(self, app):
super(Panelize, self).__init__(self)
self.app = app
# ## Title
title_label = QtWidgets.QLabel("%s" % self.toolName)
title_label.setStyleSheet("""
QLabel
{
font-size: 16px;
font-weight: bold;
}
""")
2019-01-03 19:25:08 +00:00
self.layout.addWidget(title_label)
# Form Layout
2019-05-07 10:55:20 +00:00
form_layout_0 = QtWidgets.QFormLayout()
self.layout.addLayout(form_layout_0)
2019-01-03 19:25:08 +00:00
# Type of object to be panelized
2019-01-03 19:25:08 +00:00
self.type_obj_combo = QtWidgets.QComboBox()
self.type_obj_combo.addItem("Gerber")
self.type_obj_combo.addItem("Excellon")
self.type_obj_combo.addItem("Geometry")
self.type_obj_combo.setItemIcon(0, QtGui.QIcon("share/flatcam_icon16.png"))
self.type_obj_combo.setItemIcon(1, QtGui.QIcon("share/drill16.png"))
self.type_obj_combo.setItemIcon(2, QtGui.QIcon("share/geometry16.png"))
self.type_obj_combo_label = QtWidgets.QLabel(_("Object Type:"))
2019-01-03 19:25:08 +00:00
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.")
2019-01-03 19:25:08 +00:00
)
2019-05-07 10:55:20 +00:00
form_layout_0.addRow(self.type_obj_combo_label, self.type_obj_combo)
2019-01-03 19:25:08 +00:00
# Object to be panelized
2019-01-03 19:25:08 +00:00
self.object_combo = QtWidgets.QComboBox()
self.object_combo.setModel(self.app.collection)
self.object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
self.object_combo.setCurrentIndex(1)
self.object_label = QtWidgets.QLabel(_("Object:"))
2019-01-03 19:25:08 +00:00
self.object_label.setToolTip(
_("Object to be panelized. This means that it will\n"
"be duplicated in an array of rows and columns.")
2019-01-03 19:25:08 +00:00
)
2019-05-07 10:55:20 +00:00
form_layout_0.addRow(self.object_label, self.object_combo)
form_layout_0.addRow(QtWidgets.QLabel(""))
# Form Layout
form_layout = QtWidgets.QFormLayout()
self.layout.addLayout(form_layout)
# Type of box Panel object
self.reference_radio = RadioSet([{'label': _('Object'), 'value': 'object'},
{'label': _('Bounding Box'), 'value': 'bbox'}])
2019-05-07 10:55:20 +00:00
self.box_label = QtWidgets.QLabel(_("<b>Penelization Reference:</b>"))
self.box_label.setToolTip(
_("Choose the reference for panelization:\n"
"- Object = the bounding box of a different object\n"
"- Bounding Box = the bounding box of the object to be panelized\n"
"\n"
"The reference is useful when doing panelization for more than one\n"
"object. The spacings (really offsets) will be applied in reference\n"
"to this reference object therefore maintaining the panelized\n"
"objects in sync.")
)
form_layout.addRow(self.box_label)
form_layout.addRow(self.reference_radio)
2019-01-03 19:25:08 +00:00
# Type of Box Object to be used as an envelope for panelization
2019-01-03 19:25:08 +00:00
self.type_box_combo = QtWidgets.QComboBox()
self.type_box_combo.addItem("Gerber")
self.type_box_combo.addItem("Excellon")
self.type_box_combo.addItem("Geometry")
# we get rid of item1 ("Excellon") as it is not suitable for use as a "box" for panelizing
self.type_box_combo.view().setRowHidden(1, True)
self.type_box_combo.setItemIcon(0, QtGui.QIcon("share/flatcam_icon16.png"))
self.type_box_combo.setItemIcon(2, QtGui.QIcon("share/geometry16.png"))
self.type_box_combo_label = QtWidgets.QLabel(_("Box Type:"))
2019-01-03 19:25:08 +00:00
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.")
2019-01-03 19:25:08 +00:00
)
form_layout.addRow(self.type_box_combo_label, self.type_box_combo)
# Box
2019-01-03 19:25:08 +00:00
self.box_combo = QtWidgets.QComboBox()
self.box_combo.setModel(self.app.collection)
self.box_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
self.box_combo.setCurrentIndex(1)
self.box_combo_label = QtWidgets.QLabel(_("Box Object:"))
2019-01-03 19:25:08 +00:00
self.box_combo_label.setToolTip(
_("The actual object that is used a container for the\n "
"selected object that is to be panelized.")
2019-01-03 19:25:08 +00:00
)
form_layout.addRow(self.box_combo_label, self.box_combo)
2019-05-07 10:55:20 +00:00
form_layout.addRow(QtWidgets.QLabel(""))
panel_data_label = QtWidgets.QLabel(_("<b>Panel Data:</b>"))
panel_data_label.setToolTip(
_("This informations will shape the resulting panel.\n"
"The number of rows and columns will set how many\n"
"duplicates of the original geometry will be generated.\n"
"\n"
"The spacings will set the distance between any two\n"
"elements of the panel array.")
)
form_layout.addRow(panel_data_label)
2019-01-03 19:25:08 +00:00
# Spacing Columns
self.spacing_columns = FCEntry()
self.spacing_columns_label = QtWidgets.QLabel(_("Spacing cols:"))
2019-01-03 19:25:08 +00:00
self.spacing_columns_label.setToolTip(
_("Spacing between columns of the desired panel.\n"
"In current units.")
2019-01-03 19:25:08 +00:00
)
form_layout.addRow(self.spacing_columns_label, self.spacing_columns)
# Spacing Rows
self.spacing_rows = FCEntry()
self.spacing_rows_label = QtWidgets.QLabel(_("Spacing rows:"))
2019-01-03 19:25:08 +00:00
self.spacing_rows_label.setToolTip(
_("Spacing between rows of the desired panel.\n"
"In current units.")
2019-01-03 19:25:08 +00:00
)
form_layout.addRow(self.spacing_rows_label, self.spacing_rows)
# Columns
self.columns = FCEntry()
self.columns_label = QtWidgets.QLabel(_("Columns:"))
2019-01-03 19:25:08 +00:00
self.columns_label.setToolTip(
_("Number of columns of the desired panel")
2019-01-03 19:25:08 +00:00
)
form_layout.addRow(self.columns_label, self.columns)
# Rows
self.rows = FCEntry()
self.rows_label = QtWidgets.QLabel(_("Rows:"))
2019-01-03 19:25:08 +00:00
self.rows_label.setToolTip(
_("Number of rows of the desired panel")
2019-01-03 19:25:08 +00:00
)
form_layout.addRow(self.rows_label, self.rows)
2019-05-07 10:55:20 +00:00
form_layout.addRow(QtWidgets.QLabel(""))
2019-01-03 19:25:08 +00:00
# Type of resulting Panel object
self.panel_type_radio = RadioSet([{'label': _('Gerber'), 'value': 'gerber'},
{'label': _('Geo'), 'value': 'geometry'}])
2019-05-07 10:55:20 +00:00
self.panel_type_label = QtWidgets.QLabel(_("<b>Panel Type:</b>"))
2019-02-18 21:50:33 +00:00
self.panel_type_label.setToolTip(
_("Choose the type of object for the panel object:\n"
"- Geometry\n"
"- Gerber")
2019-02-18 21:50:33 +00:00
)
form_layout.addRow(self.panel_type_label)
form_layout.addRow(self.panel_type_radio)
# Constrains
self.constrain_cb = FCCheckBox(_("Constrain panel within:"))
2019-01-03 19:25:08 +00:00
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.")
2019-01-03 19:25:08 +00:00
)
form_layout.addRow(self.constrain_cb)
self.x_width_entry = FCEntry()
self.x_width_lbl = QtWidgets.QLabel(_("Width (DX):"))
2019-01-03 19:25:08 +00:00
self.x_width_lbl.setToolTip(
_("The width (DX) within which the panel must fit.\n"
"In current units.")
2019-01-03 19:25:08 +00:00
)
form_layout.addRow(self.x_width_lbl, self.x_width_entry)
self.y_height_entry = FCEntry()
self.y_height_lbl = QtWidgets.QLabel(_("Height (DY):"))
2019-01-03 19:25:08 +00:00
self.y_height_lbl.setToolTip(
_("The height (DY)within which the panel must fit.\n"
"In current units.")
2019-01-03 19:25:08 +00:00
)
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
2019-01-03 19:25:08 +00:00
hlay_2 = QtWidgets.QHBoxLayout()
self.layout.addLayout(hlay_2)
hlay_2.addStretch()
self.panelize_object_button = QtWidgets.QPushButton(_("Panelize Object"))
2019-01-03 19:25:08 +00:00
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.")
2019-01-03 19:25:08 +00:00
)
hlay_2.addWidget(self.panelize_object_button)
self.layout.addStretch()
# Signals
2019-05-07 10:55:20 +00:00
self.reference_radio.activated_custom.connect(self.on_reference_radio_changed)
2019-01-03 19:25:08 +00:00
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)
# list to hold the temporary objects
self.objs = []
# final name for the panel object
self.outname = ""
# flag to signal the constrain was activated
self.constrain_flag = False
def run(self, toggle=True):
self.app.report_usage("ToolPanelize()")
if toggle:
# if the splitter is hidden, display it, else hide it but only if the current widget is the same
if self.app.ui.splitter.sizes()[0] == 0:
self.app.ui.splitter.setSizes([1, 1])
else:
try:
if self.app.ui.tool_scroll_area.widget().objectName() == self.toolName:
self.app.ui.splitter.setSizes([0, 1])
except AttributeError:
pass
else:
if self.app.ui.splitter.sizes()[0] == 0:
self.app.ui.splitter.setSizes([1, 1])
FlatCAMTool.run(self)
self.set_tool_ui()
self.app.ui.notebook.setTabText(2, _("Panel. Tool"))
def install(self, icon=None, separator=None, **kwargs):
FlatCAMTool.install(self, icon, separator, shortcut='ALT+Z', **kwargs)
def set_tool_ui(self):
self.reset_fields()
2019-05-07 10:55:20 +00:00
self.reference_radio.set_value('bbox')
sp_c = self.app.defaults["tools_panelize_spacing_columns"] if \
self.app.defaults["tools_panelize_spacing_columns"] else 0.0
self.spacing_columns.set_value(float(sp_c))
sp_r = self.app.defaults["tools_panelize_spacing_rows"] if \
self.app.defaults["tools_panelize_spacing_rows"] else 0.0
self.spacing_rows.set_value(float(sp_r))
rr = self.app.defaults["tools_panelize_rows"] if \
self.app.defaults["tools_panelize_rows"] else 0.0
self.rows.set_value(int(rr))
cc = self.app.defaults["tools_panelize_columns"] if \
self.app.defaults["tools_panelize_columns"] else 0.0
self.columns.set_value(int(cc))
c_cb = self.app.defaults["tools_panelize_constrain"] if \
self.app.defaults["tools_panelize_constrain"] else False
self.constrain_cb.set_value(c_cb)
x_w = self.app.defaults["tools_panelize_constrainx"] if \
self.app.defaults["tools_panelize_constrainx"] else 0.0
self.x_width_entry.set_value(float(x_w))
y_w = self.app.defaults["tools_panelize_constrainy"] if \
self.app.defaults["tools_panelize_constrainy"] else 0.0
self.y_height_entry.set_value(float(y_w))
panel_type = self.app.defaults["tools_panelize_panel_type"] if \
self.app.defaults["tools_panelize_panel_type"] else 'gerber'
self.panel_type_radio.set_value(panel_type)
2019-01-03 19:25:08 +00:00
def on_type_obj_index_changed(self):
obj_type = self.type_obj_combo.currentIndex()
self.object_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex()))
self.object_combo.setCurrentIndex(0)
2019-05-07 10:55:20 +00:00
# hide the panel type for Excellons, the panel can be only of type Geometry
if self.type_obj_combo.currentText() != 'Excellon':
self.panel_type_label.setDisabled(False)
self.panel_type_radio.setDisabled(False)
else:
self.panel_type_label.setDisabled(True)
self.panel_type_radio.setDisabled(True)
self.panel_type_radio.set_value('geometry')
2019-01-03 19:25:08 +00:00
def on_type_box_index_changed(self):
obj_type = self.type_box_combo.currentIndex()
self.box_combo.setRootModelIndex(self.app.collection.index(obj_type, 0, QtCore.QModelIndex()))
self.box_combo.setCurrentIndex(0)
2019-05-07 10:55:20 +00:00
def on_reference_radio_changed(self, current_val):
if current_val == 'object':
self.type_box_combo.setDisabled(False)
self.type_box_combo_label.setDisabled(False)
self.box_combo.setDisabled(False)
self.box_combo_label.setDisabled(False)
else:
self.type_box_combo.setDisabled(True)
self.type_box_combo_label.setDisabled(True)
self.box_combo.setDisabled(True)
self.box_combo_label.setDisabled(True)
2019-01-03 19:25:08 +00:00
def on_panelize(self):
name = self.object_combo.currentText()
# Get source object.
try:
obj = self.app.collection.get_by_name(str(name))
except:
self.app.inform.emit(_("[ERROR_NOTCL] Could not retrieve object: %s") % name)
2019-01-03 19:25:08 +00:00
return "Could not retrieve object: %s" % name
panel_obj = obj
if panel_obj is None:
self.app.inform.emit(_("[ERROR_NOTCL] Object not found: %s") % panel_obj)
2019-01-03 19:25:08 +00:00
return "Object not found: %s" % panel_obj
boxname = self.box_combo.currentText()
try:
box = self.app.collection.get_by_name(boxname)
except:
self.app.inform.emit(_("[ERROR_NOTCL] Could not retrieve object: %s") % boxname)
2019-01-03 19:25:08 +00:00
return "Could not retrieve object: %s" % boxname
if box is None:
2019-05-07 10:55:20 +00:00
self.app.inform.emit(_("[WARNING_NOTCL]No object Box. Using instead %s") % panel_obj)
self.reference_radio.set_value('bbox')
if self.reference_radio.get_value() == 'bbox':
2019-01-03 19:25:08 +00:00
box = panel_obj
self.outname = name + '_panelized'
try:
spacing_columns = float(self.spacing_columns.get_value())
except ValueError:
# try to convert comma to decimal point. if it's still not working error message and return
try:
spacing_columns = float(self.spacing_columns.get_value().replace(',', '.'))
except ValueError:
self.app.inform.emit(_("[ERROR_NOTCL] Wrong value format entered, "
"use a number."))
return
2019-01-03 19:25:08 +00:00
spacing_columns = spacing_columns if spacing_columns is not None else 0
try:
spacing_rows = float(self.spacing_rows.get_value())
except ValueError:
# try to convert comma to decimal point. if it's still not working error message and return
try:
spacing_rows = float(self.spacing_rows.get_value().replace(',', '.'))
except ValueError:
self.app.inform.emit(_("[ERROR_NOTCL] Wrong value format entered, "
"use a number."))
return
2019-01-03 19:25:08 +00:00
spacing_rows = spacing_rows if spacing_rows is not None else 0
try:
rows = int(self.rows.get_value())
except ValueError:
# try to convert comma to decimal point. if it's still not working error message and return
try:
rows = float(self.rows.get_value().replace(',', '.'))
rows = int(rows)
except ValueError:
self.app.inform.emit(_("[ERROR_NOTCL] Wrong value format entered, "
"use a number."))
return
2019-01-03 19:25:08 +00:00
rows = rows if rows is not None else 1
try:
columns = int(self.columns.get_value())
except ValueError:
# try to convert comma to decimal point. if it's still not working error message and return
try:
columns = float(self.columns.get_value().replace(',', '.'))
columns = int(columns)
except ValueError:
self.app.inform.emit(_("[ERROR_NOTCL] Wrong value format entered, "
"use a number."))
return
2019-01-03 19:25:08 +00:00
columns = columns if columns is not None else 1
try:
constrain_dx = float(self.x_width_entry.get_value())
except ValueError:
# try to convert comma to decimal point. if it's still not working error message and return
try:
constrain_dx = float(self.x_width_entry.get_value().replace(',', '.'))
except ValueError:
self.app.inform.emit(_("[ERROR_NOTCL] Wrong value format entered, "
"use a number."))
return
try:
constrain_dy = float(self.y_height_entry.get_value())
except ValueError:
# try to convert comma to decimal point. if it's still not working error message and return
try:
constrain_dy = float(self.y_height_entry.get_value().replace(',', '.'))
except ValueError:
self.app.inform.emit(_("[ERROR_NOTCL] Wrong value format entered, "
"use a number."))
return
2019-01-03 19:25:08 +00:00
panel_type = str(self.panel_type_radio.get_value())
2019-01-03 19:25:08 +00:00
if 0 in {columns, rows}:
self.app.inform.emit(_("[ERROR_NOTCL] Columns or Rows are zero value. Change them to a positive integer."))
2019-01-03 19:25:08 +00:00
return "Columns or Rows are zero value. Change them to a positive integer."
xmin, ymin, xmax, ymax = box.bounds()
lenghtx = xmax - xmin + spacing_columns
lenghty = ymax - ymin + spacing_rows
# check if constrain within an area is desired
if self.constrain_cb.isChecked():
panel_lengthx = ((xmax - xmin) * columns) + (spacing_columns * (columns - 1))
panel_lengthy = ((ymax - ymin) * rows) + (spacing_rows * (rows - 1))
# adjust the number of columns and/or rows so the panel will fit within the panel constraint area
if (panel_lengthx > constrain_dx) or (panel_lengthy > constrain_dy):
self.constrain_flag = True
while panel_lengthx > constrain_dx:
columns -= 1
panel_lengthx = ((xmax - xmin) * columns) + (spacing_columns * (columns - 1))
while panel_lengthy > constrain_dy:
rows -= 1
panel_lengthy = ((ymax - ymin) * rows) + (spacing_rows * (rows - 1))
def panelize_2():
2019-01-03 19:25:08 +00:00
if panel_obj is not None:
self.app.inform.emit(_("Generating panel ... Please wait."))
2019-01-03 19:25:08 +00:00
self.app.progress.emit(0)
2019-01-03 19:25:08 +00:00
def job_init_excellon(obj_fin, app_obj):
2019-01-03 19:25:08 +00:00
currenty = 0.0
self.app.progress.emit(10)
obj_fin.tools = panel_obj.tools.copy()
obj_fin.drills = []
obj_fin.slots = []
obj_fin.solid_geometry = []
2019-01-03 19:25:08 +00:00
for option in panel_obj.options:
if option is not 'name':
try:
obj_fin.options[option] = panel_obj.options[option]
except:
log.warning("Failed to copy option.", option)
2019-01-03 19:25:08 +00:00
for row in range(rows):
currentx = 0.0
for col in range(columns):
if panel_obj.drills:
for tool_dict in panel_obj.drills:
point_offseted = affinity.translate(tool_dict['point'], currentx, currenty)
obj_fin.drills.append(
{
"point": point_offseted,
"tool": tool_dict['tool']
}
)
if panel_obj.slots:
for tool_dict in panel_obj.slots:
start_offseted = affinity.translate(tool_dict['start'], currentx, currenty)
stop_offseted = affinity.translate(tool_dict['stop'], currentx, currenty)
obj_fin.slots.append(
{
"start": start_offseted,
"stop": stop_offseted,
"tool": tool_dict['tool']
}
)
2019-01-03 19:25:08 +00:00
currentx += lenghtx
currenty += lenghty
obj_fin.create_geometry()
obj_fin.zeros = panel_obj.zeros
obj_fin.units = panel_obj.units
def job_init_geometry(obj_fin, app_obj):
currentx = 0.0
currenty = 0.0
def translate_recursion(geom):
if type(geom) == list:
geoms = list()
for local_geom in 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)
obj_fin.solid_geometry = []
if isinstance(panel_obj, FlatCAMGeometry):
obj_fin.multigeo = panel_obj.multigeo
obj_fin.tools = deepcopy(panel_obj.tools)
if panel_obj.multigeo is True:
for tool in panel_obj.tools:
obj_fin.tools[tool]['solid_geometry'][:] = []
2019-01-03 19:25:08 +00:00
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'] = []
2019-01-03 19:25:08 +00:00
self.app.progress.emit(0)
for row in range(rows):
currentx = 0.0
2019-01-03 19:25:08 +00:00
for col in range(columns):
if isinstance(panel_obj, FlatCAMGeometry):
if panel_obj.multigeo is True:
for tool in panel_obj.tools:
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:
geo = translate_recursion(panel_obj.solid_geometry)
if isinstance(geo, list):
obj_fin.solid_geometry += geo
else:
obj_fin.solid_geometry.append(geo)
else:
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)
2019-01-03 19:25:08 +00:00
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.")
2019-01-03 19:25:08 +00:00
if isinstance(panel_obj, FlatCAMExcellon):
self.app.progress.emit(50)
self.app.new_object("excellon", self.outname, job_init_excellon, plot=True, autoselected=True)
else:
self.app.progress.emit(50)
self.app.new_object(panel_type, self.outname, job_init_geometry,
plot=True, autoselected=True)
2019-01-03 19:25:08 +00:00
if self.constrain_flag is False:
self.app.inform.emit(_("[success] Panel done..."))
2019-01-03 19:25:08 +00:00
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(
col=columns, row=rows))
2019-01-03 19:25:08 +00:00
proc = self.app.proc_container.new(_("Generating panel ... Please wait."))
def job_thread(app_obj):
try:
panelize_2()
self.app.inform.emit(_("[success] Panel created successfully."))
except Exception as e:
proc.done()
log.debug(str(e))
return
proc.done()
self.app.collection.promise(self.outname)
self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
2019-01-03 19:25:08 +00:00
def reset_fields(self):
self.object_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
self.box_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))