- a series of PEP8 corrections in the FlatCAMGeometry.py
- in Geometry UI finished a very basic way for the Polish feature (this will be upgraded in the future, for now is very rough) - added some new GUI elements by subclassing some widgets for the dialog pop-ups - in NCC Tool and Isolation Tool, pressing the shortcut key 'T' will bring the add new tool pop up in which now it is included the button to get the optimal diameter - in Geometry UI and for Solderpaste Tool replaced the pop up window that is launched when using shortcut key with one that has the context menu translated - some UI cleanup in the Geometry UI
This commit is contained in:
parent
77101be8fd
commit
51afa60e4a
|
@ -7,6 +7,15 @@ CHANGELOG for FlatCAM beta
|
|||
|
||||
=================================================
|
||||
|
||||
28.10.2020
|
||||
|
||||
- a series of PEP8 corrections in the FlatCAMGeometry.py
|
||||
- in Geometry UI finished a very basic way for the Polish feature (this will be upgraded in the future, for now is very rough)
|
||||
- added some new GUI elements by subclassing some widgets for the dialog pop-ups
|
||||
- in NCC Tool and Isolation Tool, pressing the shortcut key 'T' will bring the add new tool pop up in which now it is included the button to get the optimal diameter
|
||||
- in Geometry UI and for Solderpaste Tool replaced the pop up window that is launched when using shortcut key with one that has the context menu translated
|
||||
- some UI cleanup in the Geometry UI
|
||||
|
||||
27.10.2020
|
||||
|
||||
- created custom classes derived from TextEdit and from LineEdit where I overloaded the context menu and I made all the other classes that were inheriting from them to inherit from those new classes
|
||||
|
|
|
@ -1224,6 +1224,55 @@ class FCSliderWithDoubleSpinner(QtWidgets.QFrame):
|
|||
self.spinner.set_value(slider_value)
|
||||
|
||||
|
||||
class FCButtonWithDoubleSpinner(QtWidgets.QFrame):
|
||||
|
||||
def __init__(self, min=0, max=100, step=1, decimals=4, button_text='', button_icon=None, callback=None, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self.button = QtWidgets.QToolButton()
|
||||
if button_text != '':
|
||||
self.button.setText(button_text)
|
||||
if button_icon:
|
||||
self.button.setIcon(button_icon)
|
||||
|
||||
self.spinner = FCDoubleSpinner()
|
||||
self.spinner.set_range(min, max)
|
||||
self.spinner.set_step(step)
|
||||
self.spinner.set_precision(decimals)
|
||||
self.spinner.setMinimumWidth(70)
|
||||
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred)
|
||||
self.spinner.setSizePolicy(sizePolicy)
|
||||
|
||||
self.layout = QtWidgets.QHBoxLayout()
|
||||
self.layout.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
|
||||
self.layout.setContentsMargins(0, 0, 0, 0)
|
||||
self.layout.addWidget(self.spinner)
|
||||
self.layout.addWidget(self.button)
|
||||
self.setLayout(self.layout)
|
||||
|
||||
self.valueChanged = self.spinner.valueChanged
|
||||
|
||||
self._callback = callback
|
||||
self.button.clicked.connect(self._callback)
|
||||
|
||||
def get_value(self) -> float:
|
||||
return self.spinner.get_value()
|
||||
|
||||
def set_value(self, value: float):
|
||||
self.spinner.set_value(value)
|
||||
|
||||
def set_callback(self, callback):
|
||||
self._callback = callback
|
||||
|
||||
def set_text(self, txt: str):
|
||||
if txt:
|
||||
self.button.setText(txt)
|
||||
|
||||
def set_icon(self, icon: QtGui.QIcon):
|
||||
self.button.setIcon(icon)
|
||||
|
||||
|
||||
class FCDoubleSpinner(QtWidgets.QDoubleSpinBox):
|
||||
returnPressed = QtCore.pyqtSignal()
|
||||
confirmation_signal = QtCore.pyqtSignal(bool, float, float)
|
||||
|
@ -2112,6 +2161,7 @@ class FCInputDialog(QtWidgets.QInputDialog):
|
|||
def __init__(self, parent=None, ok=False, val=None, title=None, text=None, min=None, max=None, decimals=None,
|
||||
init_val=None):
|
||||
super(FCInputDialog, self).__init__(parent)
|
||||
|
||||
self.allow_empty = ok
|
||||
self.empty_val = val
|
||||
|
||||
|
@ -2151,6 +2201,70 @@ class FCInputDialog(QtWidgets.QInputDialog):
|
|||
pass
|
||||
|
||||
|
||||
class FCInputSpinner(QtWidgets.QDialog):
|
||||
def __init__(self, parent=None, title=None, text=None, min=None, max=None, decimals=4, step=1, init_val=None):
|
||||
super().__init__(parent)
|
||||
|
||||
self.val = 0.0
|
||||
self.ok = ''
|
||||
|
||||
self.init_value = init_val if init_val else 0.0
|
||||
|
||||
self.setWindowTitle(title) if title else self.setWindowTitle('title')
|
||||
self.text = text if text else 'text'
|
||||
|
||||
self.min = min if min else 0
|
||||
self.max = max if max else 255
|
||||
self.step = step if step else 1
|
||||
|
||||
self.lbl = FCLabel(self.text)
|
||||
|
||||
self.wdg = FCDoubleSpinner()
|
||||
self.wdg.set_value(self.init_value)
|
||||
self.wdg.set_range(self.min, self.max)
|
||||
self.wdg.set_step(self.step)
|
||||
self.wdg.set_precision(decimals)
|
||||
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
|
||||
self.wdg.setSizePolicy(sizePolicy)
|
||||
|
||||
QBtn = QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel
|
||||
|
||||
self.buttonBox = QtWidgets.QDialogButtonBox(QBtn)
|
||||
self.buttonBox.accepted.connect(self.accept)
|
||||
self.buttonBox.rejected.connect(self.reject)
|
||||
|
||||
self.layout = QtWidgets.QVBoxLayout()
|
||||
self.layout.addWidget(self.lbl)
|
||||
self.layout.addWidget(self.wdg)
|
||||
self.layout.addWidget(self.buttonBox)
|
||||
self.setLayout(self.layout)
|
||||
|
||||
def set_title(self, txt):
|
||||
self.setWindowTitle(txt)
|
||||
|
||||
def set_text(self, txt):
|
||||
self.lbl.set_value(txt)
|
||||
|
||||
def set_min(self, val):
|
||||
self.wdg.spinner.setMinimum(val)
|
||||
|
||||
def set_max(self, val):
|
||||
self.wdg.spinner.setMaximum(val)
|
||||
|
||||
def set_range(self, min, max):
|
||||
self.wdg.spinner.set_range(min, max)
|
||||
|
||||
def set_step(self, val):
|
||||
self.wdg.spinner.set_step(val)
|
||||
|
||||
def get_value(self):
|
||||
if self.exec_() == QtWidgets.QDialog.Accepted:
|
||||
return [self.wdg.get_value(), True]
|
||||
else:
|
||||
return [None, False]
|
||||
|
||||
|
||||
class FCInputDialogSlider(QtWidgets.QDialog):
|
||||
|
||||
def __init__(self, parent=None, title=None, text=None, min=None, max=None, step=1, init_val=None):
|
||||
|
@ -2209,6 +2323,70 @@ class FCInputDialogSlider(QtWidgets.QDialog):
|
|||
return None, False
|
||||
|
||||
|
||||
class FCInputDialogSpinnerButton(QtWidgets.QDialog):
|
||||
|
||||
def __init__(self, parent=None, title=None, text=None, min=None, max=None, step=1, decimals=4, init_val=None,
|
||||
button_text='', button_icon=None, callback=None):
|
||||
super().__init__(parent)
|
||||
|
||||
self.val = 0.0
|
||||
|
||||
self.init_value = init_val if init_val else 0.0
|
||||
|
||||
self.setWindowTitle(title) if title else self.setWindowTitle('title')
|
||||
self.text = text if text else 'text'
|
||||
|
||||
self.min = min if min else 0
|
||||
self.max = max if max else 255
|
||||
self.step = step if step else 1
|
||||
self.decimals = decimals if decimals else 4
|
||||
|
||||
self.lbl = FCLabel(self.text)
|
||||
|
||||
self.wdg = FCButtonWithDoubleSpinner(min=self.min, max=self.max, step=self.step, decimals=decimals,
|
||||
button_text=button_text, button_icon=button_icon, callback=callback)
|
||||
self.wdg.set_value(self.init_value)
|
||||
|
||||
QBtn = QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel
|
||||
|
||||
self.buttonBox = QtWidgets.QDialogButtonBox(QBtn)
|
||||
self.buttonBox.accepted.connect(self.accept)
|
||||
self.buttonBox.rejected.connect(self.reject)
|
||||
|
||||
self.layout = QtWidgets.QVBoxLayout()
|
||||
self.layout.addWidget(self.lbl)
|
||||
self.layout.addWidget(self.wdg)
|
||||
self.layout.addWidget(self.buttonBox)
|
||||
self.setLayout(self.layout)
|
||||
|
||||
def set_title(self, txt):
|
||||
self.setWindowTitle(txt)
|
||||
|
||||
def set_text(self, txt):
|
||||
self.lbl.set_value(txt)
|
||||
|
||||
def set_min(self, val):
|
||||
self.wdg.spinner.setMinimum(val)
|
||||
|
||||
def set_max(self, val):
|
||||
self.wdg.spinner.setMaximum(val)
|
||||
|
||||
def set_range(self, min, max):
|
||||
self.wdg.spinner.set_range(min, max)
|
||||
|
||||
def set_step(self, val):
|
||||
self.wdg.spinner.set_step(val)
|
||||
|
||||
def set_value(self, val):
|
||||
self.wdg.spinner.set_value(val)
|
||||
|
||||
def get_results(self):
|
||||
if self.exec_() == QtWidgets.QDialog.Accepted:
|
||||
return self.wdg.get_value(), True
|
||||
else:
|
||||
return None, False
|
||||
|
||||
|
||||
class FCButton(QtWidgets.QPushButton):
|
||||
def __init__(self, text=None, checkable=None, click_callback=None, parent=None):
|
||||
super(FCButton, self).__init__(text, parent)
|
||||
|
|
|
@ -1122,13 +1122,6 @@ class GeometryObjectUI(ObjectUI):
|
|||
grid2 = QtWidgets.QGridLayout()
|
||||
self.geo_table_box.addLayout(grid2)
|
||||
|
||||
self.copytool_btn = QtWidgets.QPushButton(_('Copy'))
|
||||
self.copytool_btn.setIcon(QtGui.QIcon(self.app.resource_location + '/copy16.png'))
|
||||
self.copytool_btn.setToolTip(
|
||||
_("Copy a selection of tools in the Tool Table\n"
|
||||
"by first selecting a row in the Tool Table.")
|
||||
)
|
||||
|
||||
self.deltool_btn = QtWidgets.QPushButton(_('Delete'))
|
||||
self.deltool_btn.setIcon(QtGui.QIcon(self.app.resource_location + '/trash16.png'))
|
||||
self.deltool_btn.setToolTip(
|
||||
|
@ -1136,15 +1129,11 @@ class GeometryObjectUI(ObjectUI):
|
|||
"by first selecting a row in the Tool Table.")
|
||||
)
|
||||
|
||||
grid2.addWidget(self.copytool_btn, 0, 0)
|
||||
grid2.addWidget(self.deltool_btn, 0, 1)
|
||||
|
||||
self.geo_table_box.addWidget(QtWidgets.QLabel(''))
|
||||
grid2.addWidget(self.deltool_btn, 0, 0, 1, 2)
|
||||
|
||||
# ###########################################################
|
||||
# ############# Create CNC Job ##############################
|
||||
# ###########################################################
|
||||
|
||||
self.geo_param_frame = QtWidgets.QFrame()
|
||||
self.geo_param_frame.setContentsMargins(0, 0, 0, 0)
|
||||
self.geo_tools_box.addWidget(self.geo_param_frame)
|
||||
|
@ -1659,6 +1648,21 @@ class GeometryObjectUI(ObjectUI):
|
|||
self.grid4.addWidget(self.polish_dia_lbl, 16, 0)
|
||||
self.grid4.addWidget(self.polish_dia_entry, 16, 1)
|
||||
|
||||
# Polish Travel Z
|
||||
self.polish_travelz_lbl = QtWidgets.QLabel('%s:' % _('Travel Z'))
|
||||
self.polish_travelz_lbl.setToolTip(
|
||||
_("Height of the tool when\n"
|
||||
"moving without cutting.")
|
||||
)
|
||||
self.polish_travelz_entry = FCDoubleSpinner(callback=self.confirmation_message)
|
||||
self.polish_travelz_entry.set_precision(self.decimals)
|
||||
self.polish_travelz_entry.set_range(0.00000, 10000.00000)
|
||||
self.polish_travelz_entry.setSingleStep(0.1)
|
||||
self.polish_travelz_entry.setObjectName("g_polish_travelz")
|
||||
|
||||
self.grid4.addWidget(self.polish_travelz_lbl, 17, 0)
|
||||
self.grid4.addWidget(self.polish_travelz_entry, 17, 1)
|
||||
|
||||
# Polish Pressure
|
||||
self.polish_pressure_lbl = QtWidgets.QLabel('%s:' % _('Pressure'))
|
||||
self.polish_pressure_lbl.setToolTip(
|
||||
|
@ -1670,8 +1674,21 @@ class GeometryObjectUI(ObjectUI):
|
|||
self.polish_pressure_entry.set_range(-9999.9999, 9999.9999)
|
||||
self.polish_pressure_entry.setObjectName("g_polish_pressure")
|
||||
|
||||
self.grid4.addWidget(self.polish_pressure_lbl, 17, 0)
|
||||
self.grid4.addWidget(self.polish_pressure_entry, 17, 1)
|
||||
self.grid4.addWidget(self.polish_pressure_lbl, 18, 0)
|
||||
self.grid4.addWidget(self.polish_pressure_entry, 18, 1)
|
||||
|
||||
# Polish Margin
|
||||
self.polish_margin_lbl = FCLabel('%s:' % _('Margin'))
|
||||
self.polish_margin_lbl.setToolTip(
|
||||
_("Bounding box margin.")
|
||||
)
|
||||
self.polish_margin_entry = FCDoubleSpinner(callback=self.confirmation_message)
|
||||
self.polish_margin_entry.set_precision(self.decimals)
|
||||
self.polish_margin_entry.set_range(-9999.9999, 9999.9999)
|
||||
self.polish_margin_entry.setObjectName("g_polish_margin")
|
||||
|
||||
self.grid4.addWidget(self.polish_margin_lbl, 20, 0)
|
||||
self.grid4.addWidget(self.polish_margin_entry, 20, 1)
|
||||
|
||||
# Polish Overlap
|
||||
self.polish_over_lbl = QtWidgets.QLabel('%s:' % _('Overlap'))
|
||||
|
@ -1685,8 +1702,8 @@ class GeometryObjectUI(ObjectUI):
|
|||
self.polish_over_entry.setSingleStep(0.1)
|
||||
self.polish_over_entry.setObjectName("g_polish_overlap")
|
||||
|
||||
self.grid4.addWidget(self.polish_over_lbl, 18, 0)
|
||||
self.grid4.addWidget(self.polish_over_entry, 18, 1)
|
||||
self.grid4.addWidget(self.polish_over_lbl, 22, 0)
|
||||
self.grid4.addWidget(self.polish_over_entry, 22, 1)
|
||||
|
||||
# Polish Method
|
||||
self.polish_method_lbl = QtWidgets.QLabel('%s:' % _('Method'))
|
||||
|
@ -1703,13 +1720,17 @@ class GeometryObjectUI(ObjectUI):
|
|||
)
|
||||
self.polish_method_combo.setObjectName('g_polish_method')
|
||||
|
||||
self.grid4.addWidget(self.polish_method_lbl, 20, 0)
|
||||
self.grid4.addWidget(self.polish_method_combo, 20, 1)
|
||||
self.grid4.addWidget(self.polish_method_lbl, 24, 0)
|
||||
self.grid4.addWidget(self.polish_method_combo, 24, 1)
|
||||
|
||||
self.polish_dia_lbl.hide()
|
||||
self.polish_dia_entry.hide()
|
||||
self.polish_pressure_lbl.hide()
|
||||
self.polish_pressure_entry.hide()
|
||||
self.polish_travelz_lbl.hide()
|
||||
self.polish_travelz_entry.hide()
|
||||
self.polish_margin_lbl.hide()
|
||||
self.polish_margin_entry.hide()
|
||||
self.polish_over_lbl.hide()
|
||||
self.polish_over_entry.hide()
|
||||
self.polish_method_lbl.hide()
|
||||
|
@ -1722,6 +1743,10 @@ class GeometryObjectUI(ObjectUI):
|
|||
self.polish_dia_entry,
|
||||
self.polish_pressure_lbl,
|
||||
self.polish_pressure_entry,
|
||||
self.polish_travelz_lbl,
|
||||
self.polish_travelz_entry,
|
||||
self.polish_margin_lbl,
|
||||
self.polish_margin_entry,
|
||||
self.polish_over_lbl,
|
||||
self.polish_over_entry,
|
||||
self.polish_method_lbl,
|
||||
|
@ -1732,7 +1757,7 @@ class GeometryObjectUI(ObjectUI):
|
|||
separator_line2 = QtWidgets.QFrame()
|
||||
separator_line2.setFrameShape(QtWidgets.QFrame.HLine)
|
||||
separator_line2.setFrameShadow(QtWidgets.QFrame.Sunken)
|
||||
self.grid4.addWidget(separator_line2, 22, 0, 1, 2)
|
||||
self.grid4.addWidget(separator_line2, 26, 0, 1, 2)
|
||||
|
||||
# Button
|
||||
self.generate_cnc_button = QtWidgets.QPushButton(_('Generate CNCJob object'))
|
||||
|
@ -1750,9 +1775,9 @@ class GeometryObjectUI(ObjectUI):
|
|||
font-weight: bold;
|
||||
}
|
||||
""")
|
||||
self.grid4.addWidget(self.generate_cnc_button, 24, 0, 1, 2)
|
||||
self.grid4.addWidget(self.generate_cnc_button, 28, 0, 1, 2)
|
||||
|
||||
self.grid4.addWidget(QtWidgets.QLabel(''), 26, 0, 1, 2)
|
||||
self.grid4.addWidget(QtWidgets.QLabel(''), 30, 0, 1, 2)
|
||||
|
||||
# ##############
|
||||
# Paint area ##
|
||||
|
@ -1761,7 +1786,7 @@ class GeometryObjectUI(ObjectUI):
|
|||
self.tools_label.setToolTip(
|
||||
_("Launch Paint Tool in Tools Tab.")
|
||||
)
|
||||
self.grid4.addWidget(self.tools_label, 28, 0, 1, 2)
|
||||
self.grid4.addWidget(self.tools_label, 32, 0, 1, 2)
|
||||
|
||||
# Milling Tool - will create GCode for slot holes
|
||||
self.milling_button = QtWidgets.QPushButton(_('Milling Tool'))
|
||||
|
@ -1775,7 +1800,7 @@ class GeometryObjectUI(ObjectUI):
|
|||
font-weight: bold;
|
||||
}
|
||||
""")
|
||||
self.grid4.addWidget(self.milling_button, 30, 0, 1, 2)
|
||||
self.grid4.addWidget(self.milling_button, 34, 0, 1, 2)
|
||||
# FIXME: until the Milling Tool is ready, this get disabled
|
||||
self.milling_button.setDisabled(True)
|
||||
|
||||
|
@ -1793,7 +1818,7 @@ class GeometryObjectUI(ObjectUI):
|
|||
# font-weight: bold;
|
||||
# }
|
||||
# """)
|
||||
self.grid4.addWidget(self.paint_tool_button, 32, 0, 1, 2)
|
||||
self.grid4.addWidget(self.paint_tool_button, 36, 0, 1, 2)
|
||||
|
||||
# NCC Tool
|
||||
self.generate_ncc_button = QtWidgets.QPushButton(_('NCC Tool'))
|
||||
|
@ -1808,7 +1833,7 @@ class GeometryObjectUI(ObjectUI):
|
|||
# font-weight: bold;
|
||||
# }
|
||||
# """)
|
||||
self.grid4.addWidget(self.generate_ncc_button, 34, 0, 1, 2)
|
||||
self.grid4.addWidget(self.generate_ncc_button, 38, 0, 1, 2)
|
||||
|
||||
|
||||
class CNCObjectUI(ObjectUI):
|
||||
|
|
|
@ -282,6 +282,14 @@ class PreferencesUIManager:
|
|||
"geometry_area_shape": self.ui.geometry_defaults_form.geometry_adv_opt_group.area_shape_radio,
|
||||
"geometry_area_strategy": self.ui.geometry_defaults_form.geometry_adv_opt_group.strategy_radio,
|
||||
"geometry_area_overz": self.ui.geometry_defaults_form.geometry_adv_opt_group.over_z_entry,
|
||||
# Polish
|
||||
"geometry_polish": self.ui.geometry_defaults_form.geometry_adv_opt_group.polish_cb,
|
||||
"geometry_polish_dia": self.ui.geometry_defaults_form.geometry_adv_opt_group.polish_dia_entry,
|
||||
"geometry_polish_pressure": self.ui.geometry_defaults_form.geometry_adv_opt_group.polish_pressure_entry,
|
||||
"geometry_polish_travelz": self.ui.geometry_defaults_form.geometry_adv_opt_group.polish_travelz_entry,
|
||||
"geometry_polish_margin": self.ui.geometry_defaults_form.geometry_adv_opt_group.polish_margin_entry,
|
||||
"geometry_polish_overlap": self.ui.geometry_defaults_form.geometry_adv_opt_group.polish_over_entry,
|
||||
"geometry_polish_method": self.ui.geometry_defaults_form.geometry_adv_opt_group.polish_method_combo,
|
||||
|
||||
# Geometry Editor
|
||||
"geometry_editor_sel_limit": self.ui.geometry_defaults_form.geometry_editor_group.sel_limit_entry,
|
||||
|
|
|
@ -2,7 +2,7 @@ from PyQt5 import QtWidgets
|
|||
from PyQt5.QtCore import QSettings
|
||||
|
||||
from appGUI.GUIElements import FCDoubleSpinner, FCCheckBox, RadioSet, FCLabel, NumericalEvalTupleEntry, \
|
||||
NumericalEvalEntry
|
||||
NumericalEvalEntry, FCComboBox
|
||||
from appGUI.preferences.OptionsGroupUI import OptionsGroupUI
|
||||
|
||||
import gettext
|
||||
|
@ -31,7 +31,7 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
# ------------------------------
|
||||
# ## Advanced Options
|
||||
# ------------------------------
|
||||
self.geo_label = QtWidgets.QLabel('<b>%s:</b>' % _('Advanced Options'))
|
||||
self.geo_label = FCLabel('<b>%s:</b>' % _('Advanced Options'))
|
||||
self.geo_label.setToolTip(
|
||||
_("A list of Geometry advanced parameters.\n"
|
||||
"Those parameters are available only for\n"
|
||||
|
@ -43,7 +43,7 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
self.layout.addLayout(grid1)
|
||||
|
||||
# Toolchange X,Y
|
||||
toolchange_xy_label = QtWidgets.QLabel('%s:' % _('Toolchange X-Y'))
|
||||
toolchange_xy_label = FCLabel('%s:' % _('Toolchange X-Y'))
|
||||
toolchange_xy_label.setToolTip(
|
||||
_("Toolchange X,Y position.")
|
||||
)
|
||||
|
@ -53,7 +53,7 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
grid1.addWidget(self.toolchangexy_entry, 1, 1)
|
||||
|
||||
# Start move Z
|
||||
startzlabel = QtWidgets.QLabel('%s:' % _('Start Z'))
|
||||
startzlabel = FCLabel('%s:' % _('Start Z'))
|
||||
startzlabel.setToolTip(
|
||||
_("Height of the tool just after starting the work.\n"
|
||||
"Delete the value if you don't need this feature.")
|
||||
|
@ -64,7 +64,7 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
grid1.addWidget(self.gstartz_entry, 2, 1)
|
||||
|
||||
# Feedrate rapids
|
||||
fr_rapid_label = QtWidgets.QLabel('%s:' % _('Feedrate Rapids'))
|
||||
fr_rapid_label = FCLabel('%s:' % _('Feedrate Rapids'))
|
||||
fr_rapid_label.setToolTip(
|
||||
_("Cutting speed in the XY plane\n"
|
||||
"(in units per minute).\n"
|
||||
|
@ -105,7 +105,7 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
grid1.addWidget(self.e_cut_entry, 5, 1)
|
||||
|
||||
# Probe depth
|
||||
self.pdepth_label = QtWidgets.QLabel('%s:' % _("Probe Z depth"))
|
||||
self.pdepth_label = FCLabel('%s:' % _("Probe Z depth"))
|
||||
self.pdepth_label.setToolTip(
|
||||
_("The maximum depth that the probe is allowed\n"
|
||||
"to probe. Negative value, in current units.")
|
||||
|
@ -120,7 +120,7 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
grid1.addWidget(self.pdepth_entry, 6, 1)
|
||||
|
||||
# Probe feedrate
|
||||
self.feedrate_probe_label = QtWidgets.QLabel('%s:' % _("Feedrate Probe"))
|
||||
self.feedrate_probe_label = FCLabel('%s:' % _("Feedrate Probe"))
|
||||
self.feedrate_probe_label.setToolTip(
|
||||
_("The feedrate used while the probe is probing.")
|
||||
)
|
||||
|
@ -134,7 +134,7 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
grid1.addWidget(self.feedrate_probe_entry, 7, 1)
|
||||
|
||||
# Spindle direction
|
||||
spindle_dir_label = QtWidgets.QLabel('%s:' % _('Spindle direction'))
|
||||
spindle_dir_label = FCLabel('%s:' % _('Spindle direction'))
|
||||
spindle_dir_label.setToolTip(
|
||||
_("This sets the direction that the spindle is rotating.\n"
|
||||
"It can be either:\n"
|
||||
|
@ -158,7 +158,7 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
grid1.addWidget(self.fplunge_cb, 9, 0, 1, 2)
|
||||
|
||||
# Size of trace segment on X axis
|
||||
segx_label = QtWidgets.QLabel('%s:' % _("Segment X size"))
|
||||
segx_label = FCLabel('%s:' % _("Segment X size"))
|
||||
segx_label.setToolTip(
|
||||
_("The size of the trace segment on the X axis.\n"
|
||||
"Useful for auto-leveling.\n"
|
||||
|
@ -174,7 +174,7 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
grid1.addWidget(self.segx_entry, 10, 1)
|
||||
|
||||
# Size of trace segment on Y axis
|
||||
segy_label = QtWidgets.QLabel('%s:' % _("Segment Y size"))
|
||||
segy_label = FCLabel('%s:' % _("Segment Y size"))
|
||||
segy_label.setToolTip(
|
||||
_("The size of the trace segment on the Y axis.\n"
|
||||
"Useful for auto-leveling.\n"
|
||||
|
@ -197,7 +197,7 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
# -----------------------------
|
||||
# --- Area Exclusion ----------
|
||||
# -----------------------------
|
||||
self.area_exc_label = QtWidgets.QLabel('<b>%s:</b>' % _('Area Exclusion'))
|
||||
self.area_exc_label = FCLabel('<b>%s:</b>' % _('Area Exclusion'))
|
||||
self.area_exc_label.setToolTip(
|
||||
_("Area exclusion parameters.")
|
||||
)
|
||||
|
@ -215,7 +215,7 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
grid1.addWidget(self.exclusion_cb, 14, 0, 1, 2)
|
||||
|
||||
# Area Selection shape
|
||||
self.area_shape_label = QtWidgets.QLabel('%s:' % _("Shape"))
|
||||
self.area_shape_label = FCLabel('%s:' % _("Shape"))
|
||||
self.area_shape_label.setToolTip(
|
||||
_("The kind of selection shape used for area selection.")
|
||||
)
|
||||
|
@ -248,5 +248,102 @@ class GeometryAdvOptPrefGroupUI(OptionsGroupUI):
|
|||
|
||||
grid1.addWidget(self.over_z_label, 18, 0)
|
||||
grid1.addWidget(self.over_z_entry, 18, 1)
|
||||
|
||||
separator_line = QtWidgets.QFrame()
|
||||
separator_line.setFrameShape(QtWidgets.QFrame.HLine)
|
||||
separator_line.setFrameShadow(QtWidgets.QFrame.Sunken)
|
||||
grid1.addWidget(separator_line, 20, 0, 1, 2)
|
||||
|
||||
# -----------------------------
|
||||
# --- Area POLISH ----------
|
||||
# -----------------------------
|
||||
# Add Polish
|
||||
self.polish_cb = FCCheckBox(label=_('Add Polish'))
|
||||
self.polish_cb.setToolTip(_(
|
||||
"Will add a Paint section at the end of the GCode.\n"
|
||||
"A metallic brush will clean the material after milling."))
|
||||
grid1.addWidget(self.polish_cb, 22, 0, 1, 2)
|
||||
|
||||
# Polish Tool Diameter
|
||||
self.polish_dia_lbl = FCLabel('%s:' % _('Tool Dia'))
|
||||
self.polish_dia_lbl.setToolTip(
|
||||
_("Diameter for the polishing tool.")
|
||||
)
|
||||
self.polish_dia_entry = FCDoubleSpinner()
|
||||
self.polish_dia_entry.set_precision(self.decimals)
|
||||
self.polish_dia_entry.set_range(0.000, 9999.9999)
|
||||
|
||||
grid1.addWidget(self.polish_dia_lbl, 24, 0)
|
||||
grid1.addWidget(self.polish_dia_entry, 24, 1)
|
||||
|
||||
# Polish Travel Z
|
||||
self.polish_travelz_lbl = FCLabel('%s:' % _('Travel Z'))
|
||||
self.polish_travelz_lbl.setToolTip(
|
||||
_("Height of the tool when\n"
|
||||
"moving without cutting.")
|
||||
)
|
||||
self.polish_travelz_entry = FCDoubleSpinner()
|
||||
self.polish_travelz_entry.set_precision(self.decimals)
|
||||
self.polish_travelz_entry.set_range(0.00000, 10000.00000)
|
||||
self.polish_travelz_entry.setSingleStep(0.1)
|
||||
|
||||
grid1.addWidget(self.polish_travelz_lbl, 26, 0)
|
||||
grid1.addWidget(self.polish_travelz_entry, 26, 1)
|
||||
|
||||
# Polish Pressure
|
||||
self.polish_pressure_lbl = FCLabel('%s:' % _('Pressure'))
|
||||
self.polish_pressure_lbl.setToolTip(
|
||||
_("Negative value. The higher the absolute value\n"
|
||||
"the stronger the pressure of the brush on the material.")
|
||||
)
|
||||
self.polish_pressure_entry = FCDoubleSpinner()
|
||||
self.polish_pressure_entry.set_precision(self.decimals)
|
||||
self.polish_pressure_entry.set_range(-9999.9999, 9999.9999)
|
||||
|
||||
grid1.addWidget(self.polish_pressure_lbl, 28, 0)
|
||||
grid1.addWidget(self.polish_pressure_entry, 28, 1)
|
||||
|
||||
# Polish Margin
|
||||
self.polish_margin_lbl = FCLabel('%s:' % _('Margin'))
|
||||
self.polish_margin_lbl.setToolTip(
|
||||
_("Bounding box margin.")
|
||||
)
|
||||
self.polish_margin_entry = FCDoubleSpinner()
|
||||
self.polish_margin_entry.set_precision(self.decimals)
|
||||
self.polish_margin_entry.set_range(-9999.9999, 9999.9999)
|
||||
|
||||
grid1.addWidget(self.polish_margin_lbl, 30, 0)
|
||||
grid1.addWidget(self.polish_margin_entry, 30, 1)
|
||||
|
||||
# Polish Overlap
|
||||
self.polish_over_lbl = FCLabel('%s:' % _('Overlap'))
|
||||
self.polish_over_lbl.setToolTip(
|
||||
_("How much (percentage) of the tool width to overlap each tool pass.")
|
||||
)
|
||||
self.polish_over_entry = FCDoubleSpinner(suffix='%')
|
||||
self.polish_over_entry.set_precision(self.decimals)
|
||||
self.polish_over_entry.setWrapping(True)
|
||||
self.polish_over_entry.set_range(0.0000, 99.9999)
|
||||
self.polish_over_entry.setSingleStep(0.1)
|
||||
|
||||
grid1.addWidget(self.polish_over_lbl, 32, 0)
|
||||
grid1.addWidget(self.polish_over_entry, 32, 1)
|
||||
|
||||
# Polish Method
|
||||
self.polish_method_lbl = FCLabel('%s:' % _('Method'))
|
||||
self.polish_method_lbl.setToolTip(
|
||||
_("Algorithm for polishing:\n"
|
||||
"- Standard: Fixed step inwards.\n"
|
||||
"- Seed-based: Outwards from seed.\n"
|
||||
"- Line-based: Parallel lines.")
|
||||
)
|
||||
|
||||
self.polish_method_combo = FCComboBox()
|
||||
self.polish_method_combo.addItems(
|
||||
[_("Standard"), _("Seed"), _("Lines")]
|
||||
)
|
||||
|
||||
grid1.addWidget(self.polish_method_lbl, 34, 0)
|
||||
grid1.addWidget(self.polish_method_combo, 34, 1)
|
||||
|
||||
self.layout.addStretch()
|
||||
|
|
|
@ -10,10 +10,10 @@
|
|||
# File modified by: Marius Stanciu #
|
||||
# ##########################################################
|
||||
|
||||
from shapely.geometry import Polygon, MultiPolygon, MultiLineString, LineString, LinearRing
|
||||
from shapely.geometry import Polygon, MultiPolygon, MultiLineString, LineString, LinearRing, box
|
||||
import shapely.affinity as affinity
|
||||
|
||||
from camlib import Geometry
|
||||
from camlib import Geometry, grace
|
||||
|
||||
from appObjects.FlatCAMObj import *
|
||||
|
||||
|
@ -41,6 +41,7 @@ class GeometryObject(FlatCAMObj, Geometry):
|
|||
"""
|
||||
optionChanged = QtCore.pyqtSignal(str)
|
||||
builduiSig = QtCore.pyqtSignal()
|
||||
launch_job = QtCore.pyqtSignal()
|
||||
|
||||
ui_type = GeometryObjectUI
|
||||
|
||||
|
@ -442,6 +443,8 @@ class GeometryObject(FlatCAMObj, Geometry):
|
|||
"polish": self.ui.polish_cb,
|
||||
"polish_dia": self.ui.polish_dia_entry,
|
||||
"polish_pressure": self.ui.polish_pressure_entry,
|
||||
"polish_travelz": self.ui.polish_travelz_entry,
|
||||
"polish_margin": self.ui.polish_margin_entry,
|
||||
"polish_overlap": self.ui.polish_over_entry,
|
||||
"polish_method": self.ui.polish_method_combo,
|
||||
})
|
||||
|
@ -514,7 +517,7 @@ class GeometryObject(FlatCAMObj, Geometry):
|
|||
new_data = deepcopy(self.default_data)
|
||||
self.tools.update({
|
||||
self.tooluid: {
|
||||
'tooldia': float('%.*f' % (self.decimals, float(toold))),
|
||||
'tooldia': self.app.dec_format(float(toold), self.decimals),
|
||||
'offset': 'Path',
|
||||
'offset_value': 0.0,
|
||||
'type': _('Rough'),
|
||||
|
@ -552,14 +555,14 @@ class GeometryObject(FlatCAMObj, Geometry):
|
|||
|
||||
self.ui.geo_tools_table.setupContextMenu()
|
||||
self.ui.geo_tools_table.addContextMenu(
|
||||
_("Add from Tool DB"), self.on_tool_add_from_db_clicked,
|
||||
_("Pick from DB"), self.on_tool_add_from_db_clicked,
|
||||
icon=QtGui.QIcon(self.app.resource_location + "/plus16.png"))
|
||||
self.ui.geo_tools_table.addContextMenu(
|
||||
_("Copy"), self.on_tool_copy,
|
||||
icon=QtGui.QIcon(self.app.resource_location + "/copy16.png"))
|
||||
self.ui.geo_tools_table.addContextMenu(
|
||||
_("Delete"), lambda: self.on_tool_delete(all_tools=None),
|
||||
icon=QtGui.QIcon(self.app.resource_location + "/delete32.png"))
|
||||
icon=QtGui.QIcon(self.app.resource_location + "/trash16.png"))
|
||||
|
||||
# Show/Hide Advanced Options
|
||||
if self.app.defaults["global_app_level"] == 'b':
|
||||
|
@ -625,6 +628,8 @@ class GeometryObject(FlatCAMObj, Geometry):
|
|||
|
||||
self.ui.geo_tools_table.drag_drop_sig.connect(self.rebuild_ui)
|
||||
|
||||
self.launch_job.connect(self.mtool_gen_cncjob)
|
||||
|
||||
def on_properties(self, state):
|
||||
if state:
|
||||
self.ui.properties_frame.show()
|
||||
|
@ -732,7 +737,6 @@ class GeometryObject(FlatCAMObj, Geometry):
|
|||
# I use lambda's because the connected functions have parameters that could be used in certain scenarios
|
||||
self.ui.addtool_btn.clicked.connect(lambda: self.on_tool_add())
|
||||
|
||||
self.ui.copytool_btn.clicked.connect(lambda: self.on_tool_copy())
|
||||
self.ui.deltool_btn.clicked.connect(lambda: self.on_tool_delete())
|
||||
|
||||
self.ui.geo_tools_table.clicked.connect(self.on_row_selection_change)
|
||||
|
@ -797,11 +801,6 @@ class GeometryObject(FlatCAMObj, Geometry):
|
|||
except (TypeError, AttributeError):
|
||||
pass
|
||||
|
||||
try:
|
||||
self.ui.copytool_btn.clicked.disconnect()
|
||||
except (TypeError, AttributeError):
|
||||
pass
|
||||
|
||||
try:
|
||||
self.ui.deltool_btn.clicked.disconnect()
|
||||
except (TypeError, AttributeError):
|
||||
|
@ -1833,7 +1832,7 @@ class GeometryObject(FlatCAMObj, Geometry):
|
|||
except AttributeError:
|
||||
pass
|
||||
|
||||
def on_generatecnc_button_click(self, *args):
|
||||
def on_generatecnc_button_click(self):
|
||||
log.debug("Generating CNCJob from Geometry ...")
|
||||
self.app.defaults.report_usage("geometry_on_generatecnc_button")
|
||||
|
||||
|
@ -1862,7 +1861,11 @@ class GeometryObject(FlatCAMObj, Geometry):
|
|||
self.sel_tools.update({
|
||||
tooluid: deepcopy(tooluid_value)
|
||||
})
|
||||
self.mtool_gen_cncjob()
|
||||
|
||||
if self.ui.polish_cb.get_value():
|
||||
self.on_polish()
|
||||
else:
|
||||
self.mtool_gen_cncjob()
|
||||
self.ui.geo_tools_table.clearSelection()
|
||||
|
||||
elif self.ui.geo_tools_table.rowCount() == 1:
|
||||
|
@ -1873,9 +1876,11 @@ class GeometryObject(FlatCAMObj, Geometry):
|
|||
self.sel_tools.update({
|
||||
tooluid: deepcopy(tooluid_value)
|
||||
})
|
||||
self.mtool_gen_cncjob()
|
||||
if self.ui.polish_cb.get_value():
|
||||
self.on_polish()
|
||||
else:
|
||||
self.mtool_gen_cncjob()
|
||||
self.ui.geo_tools_table.clearSelection()
|
||||
|
||||
else:
|
||||
self.app.inform.emit('[ERROR_NOTCL] %s' % _("Failed. No tool selected in the tool table ..."))
|
||||
|
||||
|
@ -1955,7 +1960,7 @@ class GeometryObject(FlatCAMObj, Geometry):
|
|||
tool_cnt += 1
|
||||
|
||||
dia_cnc_dict = deepcopy(tools_dict[tooluid_key])
|
||||
tooldia_val = float('%.*f' % (self.decimals, float(tools_dict[tooluid_key]['tooldia'])))
|
||||
tooldia_val = app_obj.dec_format(float(tools_dict[tooluid_key]['tooldia']), self.decimals)
|
||||
dia_cnc_dict.update({
|
||||
'tooldia': tooldia_val
|
||||
})
|
||||
|
@ -1972,12 +1977,12 @@ class GeometryObject(FlatCAMObj, Geometry):
|
|||
try:
|
||||
offset_value = float(self.ui.tool_offset_entry.get_value().replace(',', '.'))
|
||||
except ValueError:
|
||||
self.app.inform.emit('[ERROR_NOTCL] %s' % _("Wrong value format entered, use a number."))
|
||||
app_obj.inform.emit('[ERROR_NOTCL] %s' % _("Wrong value format entered, use a number."))
|
||||
return
|
||||
if offset_value:
|
||||
tool_offset = float(offset_value)
|
||||
else:
|
||||
self.app.inform.emit(
|
||||
app_obj.inform.emit(
|
||||
'[WARNING] %s' % _("Tool Offset is selected in Tool Table but no value is provided.\n"
|
||||
"Add a Tool Offset or change the Offset Type.")
|
||||
)
|
||||
|
@ -2048,17 +2053,16 @@ class GeometryObject(FlatCAMObj, Geometry):
|
|||
|
||||
self.app.inform.emit('[success] %s' % _("G-Code parsing in progress..."))
|
||||
dia_cnc_dict['gcode_parsed'] = job_obj.gcode_parse()
|
||||
self.app.inform.emit('[success] %s' % _("G-Code parsing finished..."))
|
||||
app_obj.inform.emit('[success] %s' % _("G-Code parsing finished..."))
|
||||
|
||||
# TODO this serve for bounding box creation only; should be optimized
|
||||
# commented this; there is no need for the actual GCode geometry - the original one will serve as well
|
||||
# for bounding box values
|
||||
# dia_cnc_dict['solid_geometry'] = unary_union([geo['geom'] for geo in dia_cnc_dict['gcode_parsed']])
|
||||
try:
|
||||
dia_cnc_dict['solid_geometry'] = tool_solid_geometry
|
||||
self.app.inform.emit('[success] %s...' % _("Finished G-Code processing"))
|
||||
app_obj.inform.emit('[success] %s...' % _("Finished G-Code processing"))
|
||||
except Exception as er:
|
||||
self.app.inform.emit('[ERROR] %s: %s' % (_("G-Code processing failed with error"), str(er)))
|
||||
app_obj.inform.emit('[ERROR] %s: %s' % (_("G-Code processing failed with error"), str(er)))
|
||||
|
||||
job_obj.cnc_tools.update({
|
||||
tooluid_key: deepcopy(dia_cnc_dict)
|
||||
|
@ -2102,15 +2106,14 @@ class GeometryObject(FlatCAMObj, Geometry):
|
|||
if self.tools[tooluid_key]['solid_geometry'] is None:
|
||||
a += 1
|
||||
if a == len(self.tools):
|
||||
self.app.inform.emit('[ERROR_NOTCL] %s...' % _('Cancelled. Empty file, it has no geometry'))
|
||||
app_obj.inform.emit('[ERROR_NOTCL] %s...' % _('Cancelled. Empty file, it has no geometry'))
|
||||
return 'fail'
|
||||
|
||||
total_gcode = ''
|
||||
for tooluid_key in list(tools_dict.keys()):
|
||||
tool_cnt += 1
|
||||
dia_cnc_dict = deepcopy(tools_dict[tooluid_key])
|
||||
tooldia_val = float('%.*f' % (self.decimals, float(tools_dict[tooluid_key]['tooldia'])))
|
||||
|
||||
tooldia_val = app_obj.dec_format(float(tools_dict[tooluid_key]['tooldia']), self.decimals)
|
||||
dia_cnc_dict.update({
|
||||
'tooldia': tooldia_val
|
||||
})
|
||||
|
@ -2144,27 +2147,27 @@ class GeometryObject(FlatCAMObj, Geometry):
|
|||
'offset_value': tool_offset
|
||||
})
|
||||
|
||||
z_cut = tools_dict[tooluid_key]['data']["cutz"]
|
||||
z_move = tools_dict[tooluid_key]['data']["travelz"]
|
||||
feedrate = tools_dict[tooluid_key]['data']["feedrate"]
|
||||
feedrate_z = tools_dict[tooluid_key]['data']["feedrate_z"]
|
||||
feedrate_rapid = tools_dict[tooluid_key]['data']["feedrate_rapid"]
|
||||
multidepth = tools_dict[tooluid_key]['data']["multidepth"]
|
||||
extracut = tools_dict[tooluid_key]['data']["extracut"]
|
||||
extracut_length = tools_dict[tooluid_key]['data']["extracut_length"]
|
||||
depthpercut = tools_dict[tooluid_key]['data']["depthperpass"]
|
||||
toolchange = tools_dict[tooluid_key]['data']["toolchange"]
|
||||
toolchangez = tools_dict[tooluid_key]['data']["toolchangez"]
|
||||
toolchangexy = tools_dict[tooluid_key]['data']["toolchangexy"]
|
||||
startz = tools_dict[tooluid_key]['data']["startz"]
|
||||
endz = tools_dict[tooluid_key]['data']["endz"]
|
||||
endxy = self.options["endxy"]
|
||||
spindlespeed = tools_dict[tooluid_key]['data']["spindlespeed"]
|
||||
dwell = tools_dict[tooluid_key]['data']["dwell"]
|
||||
dwelltime = tools_dict[tooluid_key]['data']["dwelltime"]
|
||||
pp_geometry_name = tools_dict[tooluid_key]['data']["ppname_g"]
|
||||
|
||||
spindledir = self.app.defaults['geometry_spindledir']
|
||||
# z_cut = tools_dict[tooluid_key]['data']["cutz"]
|
||||
# z_move = tools_dict[tooluid_key]['data']["travelz"]
|
||||
# feedrate = tools_dict[tooluid_key]['data']["feedrate"]
|
||||
# feedrate_z = tools_dict[tooluid_key]['data']["feedrate_z"]
|
||||
# feedrate_rapid = tools_dict[tooluid_key]['data']["feedrate_rapid"]
|
||||
# multidepth = tools_dict[tooluid_key]['data']["multidepth"]
|
||||
# extracut = tools_dict[tooluid_key]['data']["extracut"]
|
||||
# extracut_length = tools_dict[tooluid_key]['data']["extracut_length"]
|
||||
# depthpercut = tools_dict[tooluid_key]['data']["depthperpass"]
|
||||
# toolchange = tools_dict[tooluid_key]['data']["toolchange"]
|
||||
# toolchangez = tools_dict[tooluid_key]['data']["toolchangez"]
|
||||
# toolchangexy = tools_dict[tooluid_key]['data']["toolchangexy"]
|
||||
# startz = tools_dict[tooluid_key]['data']["startz"]
|
||||
# endz = tools_dict[tooluid_key]['data']["endz"]
|
||||
# endxy = self.options["endxy"]
|
||||
# spindlespeed = tools_dict[tooluid_key]['data']["spindlespeed"]
|
||||
# dwell = tools_dict[tooluid_key]['data']["dwell"]
|
||||
# dwelltime = tools_dict[tooluid_key]['data']["dwelltime"]
|
||||
# pp_geometry_name = tools_dict[tooluid_key]['data']["ppname_g"]
|
||||
#
|
||||
# spindledir = self.app.defaults['geometry_spindledir']
|
||||
tool_solid_geometry = self.tools[tooluid_key]['solid_geometry']
|
||||
|
||||
job_obj.coords_decimals = self.app.defaults["cncjob_coords_decimals"]
|
||||
|
@ -2196,11 +2199,10 @@ class GeometryObject(FlatCAMObj, Geometry):
|
|||
if start_gcode != '':
|
||||
job_obj.gc_start = start_gcode
|
||||
|
||||
self.app.inform.emit('[success] %s' % _("G-Code parsing in progress..."))
|
||||
app_obj.inform.emit('[success] %s' % _("G-Code parsing in progress..."))
|
||||
dia_cnc_dict['gcode_parsed'] = job_obj.gcode_parse()
|
||||
self.app.inform.emit('[success] %s' % _("G-Code parsing finished..."))
|
||||
app_obj.inform.emit('[success] %s' % _("G-Code parsing finished..."))
|
||||
|
||||
# TODO this serve for bounding box creation only; should be optimized
|
||||
# commented this; there is no need for the actual GCode geometry - the original one will serve as well
|
||||
# for bounding box values
|
||||
# geo_for_bound_values = unary_union([
|
||||
|
@ -2208,9 +2210,9 @@ class GeometryObject(FlatCAMObj, Geometry):
|
|||
# ])
|
||||
try:
|
||||
dia_cnc_dict['solid_geometry'] = deepcopy(tool_solid_geometry)
|
||||
self.app.inform.emit('[success] %s' % _("Finished G-Code processing..."))
|
||||
app_obj.inform.emit('[success] %s' % _("Finished G-Code processing..."))
|
||||
except Exception as ee:
|
||||
self.app.inform.emit('[ERROR] %s: %s' % (_("G-Code processing failed with error"), str(ee)))
|
||||
app_obj.inform.emit('[ERROR] %s: %s' % (_("G-Code processing failed with error"), str(ee)))
|
||||
|
||||
# tell gcode_parse from which point to start drawing the lines depending on what kind of
|
||||
# object is the source of gcode
|
||||
|
@ -2228,11 +2230,13 @@ class GeometryObject(FlatCAMObj, Geometry):
|
|||
def job_thread(a_obj):
|
||||
if self.multigeo is False:
|
||||
with self.app.proc_container.new(_("Generating CNC Code")):
|
||||
if a_obj.app_obj.new_object("cncjob", outname, job_init_single_geometry, plot=plot) != 'fail':
|
||||
ret_val = a_obj.app_obj.new_object("cncjob", outname, job_init_single_geometry, plot=plot)
|
||||
if ret_val != 'fail':
|
||||
a_obj.inform.emit('[success] %s: %s' % (_("CNCjob created"), outname))
|
||||
else:
|
||||
with self.app.proc_container.new(_("Generating CNC Code")):
|
||||
if a_obj.app_obj.new_object("cncjob", outname, job_init_multi_geometry) != 'fail':
|
||||
ret_val = a_obj.app_obj.new_object("cncjob", outname, job_init_multi_geometry, plot=plot)
|
||||
if ret_val != 'fail':
|
||||
a_obj.inform.emit('[success] %s: %s' % (_("CNCjob created"), outname))
|
||||
|
||||
# Create a promise with the name
|
||||
|
@ -2378,7 +2382,7 @@ class GeometryObject(FlatCAMObj, Geometry):
|
|||
# source of gcode
|
||||
job_obj.toolchange_xy_type = "geometry"
|
||||
job_obj.gcode_parse()
|
||||
self.app.inform.emit('[success] %s' % _("Finished G-Code processing..."))
|
||||
app_obj.inform.emit('[success] %s' % _("Finished G-Code processing..."))
|
||||
|
||||
if use_thread:
|
||||
# To be run in separate thread
|
||||
|
@ -2394,10 +2398,100 @@ class GeometryObject(FlatCAMObj, Geometry):
|
|||
else:
|
||||
self.app.app_obj.new_object("cncjob", outname, job_init, plot=plot)
|
||||
|
||||
# def on_plot_cb_click(self, *args):
|
||||
# if self.muted_ui:
|
||||
# return
|
||||
# self.read_form_item('plot')
|
||||
def on_polish(self):
|
||||
|
||||
def job_thread(obj):
|
||||
with obj.app.proc_container.new(_("Working...")):
|
||||
tooldia = obj.ui.polish_dia_entry.get_value()
|
||||
depth = obj.ui.polish_pressure_entry.get_value()
|
||||
travelz = obj.ui.polish_travelz_entry.get_value()
|
||||
margin = obj.ui.polish_margin_entry.get_value()
|
||||
overlap = obj.ui.polish_over_entry.get_value() / 100
|
||||
paint_method = obj.ui.polish_method_combo.get_value()
|
||||
|
||||
# calculate the max uid form the keys of the self.tools
|
||||
max_uid = max(list(obj.tools.keys()))
|
||||
new_uid = max_uid + 1
|
||||
|
||||
# add a new key in the dict
|
||||
new_data = deepcopy(obj.default_data)
|
||||
new_data["travelz"] = travelz
|
||||
new_data["cutz"] = depth
|
||||
new_dict = {
|
||||
new_uid: {
|
||||
'tooldia': obj.app.dec_format(float(tooldia), obj.decimals),
|
||||
'offset': 'Path',
|
||||
'offset_value': 0.0,
|
||||
'type': _('Polish'),
|
||||
'tool_type': 'C1',
|
||||
'data': new_data,
|
||||
'solid_geometry': []
|
||||
}
|
||||
}
|
||||
obj.tools.update(new_dict)
|
||||
obj.sel_tools.update(new_dict)
|
||||
|
||||
# make a box polygon out of the bounds of the current object
|
||||
# apply the margin
|
||||
xmin, ymin, xmax, ymax = obj.bounds()
|
||||
bbox = box(xmin-margin, ymin-margin, xmax+margin, ymax+margin)
|
||||
|
||||
# paint the box
|
||||
try:
|
||||
# provide the app with a way to process the GUI events when in a blocking loop
|
||||
QtWidgets.QApplication.processEvents()
|
||||
if self.app.abort_flag:
|
||||
# graceful abort requested by the user
|
||||
raise grace
|
||||
|
||||
# Type(cpoly) == FlatCAMRTreeStorage | None
|
||||
cpoly = None
|
||||
if paint_method == _("Standard"):
|
||||
cpoly = self.clear_polygon(bbox,
|
||||
tooldia=tooldia,
|
||||
steps_per_circle=obj.circle_steps,
|
||||
overlap=overlap,
|
||||
contour=True,
|
||||
connect=True,
|
||||
prog_plot=False)
|
||||
elif paint_method == _("Seed"):
|
||||
cpoly = self.clear_polygon2(bbox,
|
||||
tooldia=tooldia,
|
||||
steps_per_circle=obj.circle_steps,
|
||||
overlap=overlap,
|
||||
contour=True,
|
||||
connect=True,
|
||||
prog_plot=False)
|
||||
elif paint_method == _("Lines"):
|
||||
cpoly = self.clear_polygon3(bbox,
|
||||
tooldia=tooldia,
|
||||
steps_per_circle=obj.circle_steps,
|
||||
overlap=overlap,
|
||||
contour=True,
|
||||
connect=True,
|
||||
prog_plot=False)
|
||||
|
||||
if not cpoly or not cpoly.objects:
|
||||
obj.app.inform.emit('[ERROR_NOTCL] %s' % _('Geometry could not be painted completely'))
|
||||
return
|
||||
|
||||
paint_geo = [g for g in cpoly.get_objects() if g and not g.is_empty]
|
||||
except grace:
|
||||
return "fail"
|
||||
except Exception as e:
|
||||
log.debug("Could not Paint the polygons. %s" % str(e))
|
||||
mssg = '[ERROR] %s\n%s' % (_("Could not do Paint. Try a different combination of parameters. "
|
||||
"Or a different strategy of paint"), str(e))
|
||||
self.app.inform.emit(mssg)
|
||||
return
|
||||
|
||||
obj.sel_tools[new_uid]['solid_geometry'] = paint_geo
|
||||
|
||||
# and now create the CNCJob
|
||||
obj.launch_job.emit()
|
||||
|
||||
# Send to worker
|
||||
self.app.worker_task.emit({'fcn': job_thread, 'params': [self]})
|
||||
|
||||
def scale(self, xfactor, yfactor=None, point=None):
|
||||
"""
|
||||
|
@ -2874,7 +2968,7 @@ class GeometryObject(FlatCAMObj, Geometry):
|
|||
except (ObjectDeleted, AttributeError):
|
||||
self.shapes.clear(update=True)
|
||||
|
||||
def on_plot_cb_click(self, *args):
|
||||
def on_plot_cb_click(self):
|
||||
if self.muted_ui:
|
||||
return
|
||||
self.read_form_item('plot')
|
||||
|
@ -2933,7 +3027,7 @@ class GeometryObject(FlatCAMObj, Geometry):
|
|||
self.ui.plot_cb.setChecked(True)
|
||||
self.ui_connect()
|
||||
|
||||
def on_multicolored_cb_click(self, *args):
|
||||
def on_multicolored_cb_click(self):
|
||||
if self.muted_ui:
|
||||
return
|
||||
self.read_form_item('multicolored')
|
||||
|
|
|
@ -9,7 +9,7 @@ from PyQt5 import QtWidgets, QtCore, QtGui
|
|||
|
||||
from appTool import AppTool
|
||||
from appGUI.GUIElements import FCCheckBox, FCDoubleSpinner, RadioSet, FCTable, FCInputDialog, FCButton, \
|
||||
FCComboBox, OptionalInputSection, FCSpinner, FCLabel
|
||||
FCComboBox, OptionalInputSection, FCSpinner, FCLabel, FCInputDialogSpinnerButton
|
||||
from appParsers.ParseGerber import Gerber
|
||||
from camlib import grace
|
||||
|
||||
|
@ -58,7 +58,8 @@ class ToolIsolation(AppTool, Gerber):
|
|||
# #############################################################################
|
||||
self.ui.tools_table.setupContextMenu()
|
||||
self.ui.tools_table.addContextMenu(
|
||||
_("Search and Add"), self.on_add_tool_by_key,
|
||||
_("Search and Add"),
|
||||
self.on_add_tool_by_key,
|
||||
icon=QtGui.QIcon(self.app.resource_location + "/plus16.png")
|
||||
)
|
||||
self.ui.tools_table.addContextMenu(
|
||||
|
@ -779,20 +780,34 @@ class ToolIsolation(AppTool, Gerber):
|
|||
self.blockSignals(False)
|
||||
|
||||
def on_add_tool_by_key(self):
|
||||
tool_add_popup = FCInputDialog(title='%s...' % _("New Tool"),
|
||||
text='%s:' % _('Enter a Tool Diameter'),
|
||||
min=0.0001, max=9999.9999, decimals=self.decimals)
|
||||
# tool_add_popup = FCInputDialog(title='%s...' % _("New Tool"),
|
||||
# text='%s:' % _('Enter a Tool Diameter'),
|
||||
# min=0.0001, max=9999.9999, decimals=self.decimals)
|
||||
btn_icon = QtGui.QIcon(self.app.resource_location + '/open_excellon32.png')
|
||||
|
||||
tool_add_popup = FCInputDialogSpinnerButton(title='%s...' % _("New Tool"),
|
||||
text='%s:' % _('Enter a Tool Diameter'),
|
||||
min=0.0001, max=9999.9999, decimals=self.decimals,
|
||||
button_icon=btn_icon,
|
||||
callback=self.on_find_optimal_tooldia)
|
||||
tool_add_popup.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/letter_t_32.png'))
|
||||
|
||||
val, ok = tool_add_popup.get_value()
|
||||
def find_optimal(val):
|
||||
tool_add_popup.set_value(float(val))
|
||||
|
||||
self.optimal_found_sig.connect(find_optimal)
|
||||
|
||||
val, ok = tool_add_popup.get_results()
|
||||
if ok:
|
||||
if float(val) == 0:
|
||||
self.app.inform.emit('[WARNING_NOTCL] %s' %
|
||||
_("Please enter a tool diameter with non-zero value, in Float format."))
|
||||
self.optimal_found_sig.disconnect(find_optimal)
|
||||
return
|
||||
self.on_tool_add(custom_dia=float(val))
|
||||
else:
|
||||
self.app.inform.emit('[WARNING_NOTCL] %s...' % _("Adding Tool cancelled"))
|
||||
self.optimal_found_sig.disconnect(find_optimal)
|
||||
|
||||
def on_reference_combo_changed(self):
|
||||
obj_type = self.ui.reference_combo_type.currentIndex()
|
||||
|
@ -913,7 +928,7 @@ class ToolIsolation(AppTool, Gerber):
|
|||
return
|
||||
|
||||
def job_thread(app_obj, is_display):
|
||||
with self.app.proc_container.new(_("Working...")) as proc:
|
||||
with self.app.proc_container.new(_("Working...")):
|
||||
try:
|
||||
old_disp_number = 0
|
||||
pol_nr = 0
|
||||
|
|
|
@ -9,7 +9,7 @@ from PyQt5 import QtWidgets, QtCore, QtGui
|
|||
|
||||
from appTool import AppTool
|
||||
from appGUI.GUIElements import FCCheckBox, FCDoubleSpinner, RadioSet, FCTable, FCInputDialog, FCButton,\
|
||||
FCComboBox, OptionalInputSection, FCLabel
|
||||
FCComboBox, OptionalInputSection, FCLabel, FCInputDialogSpinnerButton
|
||||
from appParsers.ParseGerber import Gerber
|
||||
|
||||
from camlib import grace
|
||||
|
@ -451,20 +451,34 @@ class NonCopperClear(AppTool, Gerber):
|
|||
self.blockSignals(False)
|
||||
|
||||
def on_add_tool_by_key(self):
|
||||
tool_add_popup = FCInputDialog(title='%s...' % _("New Tool"),
|
||||
text='%s:' % _('Enter a Tool Diameter'),
|
||||
min=0.0001, max=9999.9999, decimals=self.decimals)
|
||||
# tool_add_popup = FCInputDialog(title='%s...' % _("New Tool"),
|
||||
# text='%s:' % _('Enter a Tool Diameter'),
|
||||
# min=0.0001, max=9999.9999, decimals=self.decimals)
|
||||
btn_icon = QtGui.QIcon(self.app.resource_location + '/open_excellon32.png')
|
||||
|
||||
tool_add_popup = FCInputDialogSpinnerButton(title='%s...' % _("New Tool"),
|
||||
text='%s:' % _('Enter a Tool Diameter'),
|
||||
min=0.0001, max=9999.9999, decimals=self.decimals,
|
||||
button_icon=btn_icon,
|
||||
callback=self.on_find_optimal_tooldia)
|
||||
tool_add_popup.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/letter_t_32.png'))
|
||||
|
||||
val, ok = tool_add_popup.get_value()
|
||||
def find_optimal(val):
|
||||
tool_add_popup.set_value(float(val))
|
||||
|
||||
self.optimal_found_sig.connect(find_optimal)
|
||||
|
||||
val, ok = tool_add_popup.get_results()
|
||||
if ok:
|
||||
if float(val) == 0:
|
||||
self.app.inform.emit('[WARNING_NOTCL] %s' %
|
||||
_("Please enter a tool diameter with non-zero value, in Float format."))
|
||||
self.optimal_found_sig.disconnect(find_optimal)
|
||||
return
|
||||
self.on_tool_add(custom_dia=float(val))
|
||||
else:
|
||||
self.app.inform.emit('[WARNING_NOTCL] %s...' % _("Adding Tool cancelled"))
|
||||
self.optimal_found_sig.disconnect(find_optimal)
|
||||
|
||||
def set_tool_ui(self):
|
||||
self.units = self.app.defaults['units'].upper()
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
from appTool import AppTool
|
||||
from appCommon.Common import LoudDict
|
||||
from appGUI.GUIElements import FCComboBox, FCEntry, FCTable, \
|
||||
FCInputDialog, FCDoubleSpinner, FCSpinner, FCFileSaveDialog
|
||||
FCInputDialog, FCDoubleSpinner, FCSpinner, FCFileSaveDialog, FCInputSpinner
|
||||
from app_Main import log
|
||||
from camlib import distance
|
||||
from appEditors.AppTextEditor import AppTextEditor
|
||||
|
@ -119,9 +119,9 @@ class SolderPaste(AppTool):
|
|||
AppTool.install(self, icon, separator, shortcut='Alt+K', **kwargs)
|
||||
|
||||
def on_add_tool_by_key(self):
|
||||
tool_add_popup = FCInputDialog(title='%s...' % _("New Tool"),
|
||||
text='%s:' % _('Enter a Tool Diameter'),
|
||||
min=0.0000, max=99.9999, decimals=4)
|
||||
tool_add_popup = FCInputSpinner(title='%s...' % _("New Tool"),
|
||||
text='%s:' % _('Enter a Tool Diameter'),
|
||||
min=0.0000, max=100.0000, decimals=self.decimals, step=0.1)
|
||||
tool_add_popup.setWindowIcon(QtGui.QIcon(self.app.resource_location + '/letter_t_32.png'))
|
||||
|
||||
val, ok = tool_add_popup.get_value()
|
||||
|
|
17
app_Main.py
17
app_Main.py
|
@ -4419,9 +4419,9 @@ class App(QtCore.QObject):
|
|||
if self.collection.get_active().kind == 'geometry':
|
||||
# Tool add works for Geometry only if Advanced is True in Preferences
|
||||
if self.defaults["global_app_level"] == 'a':
|
||||
tool_add_popup = FCInputDialog(title="New Tool ...",
|
||||
text='Enter a Tool Diameter:',
|
||||
min=0.0000, max=99.9999, decimals=4)
|
||||
tool_add_popup = FCInputSpinner(title='%s...' % _("New Tool"),
|
||||
text='%s:' % _('Enter a Tool Diameter'),
|
||||
min=0.0000, max=100.0000, decimals=self.decimals, step=0.1)
|
||||
tool_add_popup.setWindowIcon(QtGui.QIcon(self.resource_location + '/letter_t_32.png'))
|
||||
|
||||
val, ok = tool_add_popup.get_value()
|
||||
|
@ -4448,7 +4448,10 @@ class App(QtCore.QObject):
|
|||
|
||||
# work only if the notebook tab on focus is the Tools_Tab
|
||||
if notebook_widget_name == 'tool_tab':
|
||||
tool_widget = self.ui.tool_scroll_area.widget().objectName()
|
||||
try:
|
||||
tool_widget = self.ui.tool_scroll_area.widget().objectName()
|
||||
except AttributeError:
|
||||
return
|
||||
|
||||
# and only if the tool is NCC Tool
|
||||
if tool_widget == self.ncclear_tool.toolName:
|
||||
|
@ -4462,6 +4465,10 @@ class App(QtCore.QObject):
|
|||
elif tool_widget == self.paste_tool.toolName:
|
||||
self.paste_tool.on_add_tool_by_key()
|
||||
|
||||
# and only if the tool is Isolation Tool
|
||||
elif tool_widget == self.isolation_tool.toolName:
|
||||
self.isolation_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 below.
|
||||
def on_delete_keypress(self):
|
||||
|
@ -4469,7 +4476,7 @@ class App(QtCore.QObject):
|
|||
|
||||
# work only if the notebook tab on focus is the properties_tab and only if the object is Geometry
|
||||
if notebook_widget_name == 'properties_tab':
|
||||
if str(type(self.collection.get_active())) == "<class 'FlatCAMObj.GeometryObject'>":
|
||||
if self.collection.get_active().kind == 'geometry':
|
||||
self.collection.get_active().on_tool_delete()
|
||||
|
||||
# work only if the notebook tab on focus is the Tools_Tab
|
||||
|
|
|
@ -345,7 +345,9 @@ class FlatCAMDefaults:
|
|||
"geometry_polish": False,
|
||||
"geometry_polish_dia": 10.0,
|
||||
"geometry_polish_pressure": -1.0,
|
||||
"geometry_polish_overlap": 1.0,
|
||||
"geometry_polish_travelz": 2.0,
|
||||
"geometry_polish_margin": 0.0,
|
||||
"geometry_polish_overlap": 5,
|
||||
"geometry_polish_method": _("Standard"),
|
||||
|
||||
# Geometry Editor
|
||||
|
|
Loading…
Reference in New Issue