- added in Preferences a new Category: Gerber Advanced Options. For now it controls the display of Gerber Aperture Table and the "follow" attribute4
- fixed FlatCAMGerber.merge() to merge the self.apertures[ap]['solid_geometry'] too - started to work on a new feature that allow adding a ToolChange GCode macro - GUI added both in CNCJob Selected tab and in CNCJob Preferences - added a limited 'sort-of' Gerber Editor: it allows buffering and scaling of apertures
This commit is contained in:
@@ -330,11 +330,13 @@ class App(QtCore.QObject):
|
|||||||
"global_workspace": self.ui.general_defaults_form.general_gui_group.workspace_cb,
|
"global_workspace": self.ui.general_defaults_form.general_gui_group.workspace_cb,
|
||||||
"global_workspaceT": self.ui.general_defaults_form.general_gui_group.wk_cb,
|
"global_workspaceT": self.ui.general_defaults_form.general_gui_group.wk_cb,
|
||||||
|
|
||||||
|
# Gerber General
|
||||||
"gerber_plot": self.ui.gerber_defaults_form.gerber_gen_group.plot_cb,
|
"gerber_plot": self.ui.gerber_defaults_form.gerber_gen_group.plot_cb,
|
||||||
"gerber_solid": self.ui.gerber_defaults_form.gerber_gen_group.solid_cb,
|
"gerber_solid": self.ui.gerber_defaults_form.gerber_gen_group.solid_cb,
|
||||||
"gerber_multicolored": self.ui.gerber_defaults_form.gerber_gen_group.multicolored_cb,
|
"gerber_multicolored": self.ui.gerber_defaults_form.gerber_gen_group.multicolored_cb,
|
||||||
"gerber_circle_steps": self.ui.gerber_defaults_form.gerber_gen_group.circle_steps_entry,
|
"gerber_circle_steps": self.ui.gerber_defaults_form.gerber_gen_group.circle_steps_entry,
|
||||||
|
|
||||||
|
# Gerber Options
|
||||||
"gerber_isotooldia": self.ui.gerber_defaults_form.gerber_opt_group.iso_tool_dia_entry,
|
"gerber_isotooldia": self.ui.gerber_defaults_form.gerber_opt_group.iso_tool_dia_entry,
|
||||||
"gerber_isopasses": self.ui.gerber_defaults_form.gerber_opt_group.iso_width_entry,
|
"gerber_isopasses": self.ui.gerber_defaults_form.gerber_opt_group.iso_width_entry,
|
||||||
"gerber_isooverlap": self.ui.gerber_defaults_form.gerber_opt_group.iso_overlap_entry,
|
"gerber_isooverlap": self.ui.gerber_defaults_form.gerber_opt_group.iso_overlap_entry,
|
||||||
@@ -345,6 +347,12 @@ class App(QtCore.QObject):
|
|||||||
"gerber_bboxmargin": self.ui.gerber_defaults_form.gerber_opt_group.bbmargin_entry,
|
"gerber_bboxmargin": self.ui.gerber_defaults_form.gerber_opt_group.bbmargin_entry,
|
||||||
"gerber_bboxrounded": self.ui.gerber_defaults_form.gerber_opt_group.bbrounded_cb,
|
"gerber_bboxrounded": self.ui.gerber_defaults_form.gerber_opt_group.bbrounded_cb,
|
||||||
|
|
||||||
|
# Gerber Advanced Options
|
||||||
|
"gerber_aperture_display": self.ui.gerber_defaults_form.gerber_adv_opt_group.aperture_table_visibility_cb,
|
||||||
|
"gerber_aperture_scale_factor": self.ui.gerber_defaults_form.gerber_adv_opt_group.scale_aperture_entry,
|
||||||
|
"gerber_aperture_buffer_factor": self.ui.gerber_defaults_form.gerber_adv_opt_group.buffer_aperture_entry,
|
||||||
|
"gerber_follow": self.ui.gerber_defaults_form.gerber_adv_opt_group.follow_cb,
|
||||||
|
|
||||||
# Excellon General
|
# Excellon General
|
||||||
"excellon_plot": self.ui.excellon_defaults_form.excellon_gen_group.plot_cb,
|
"excellon_plot": self.ui.excellon_defaults_form.excellon_gen_group.plot_cb,
|
||||||
"excellon_solid": self.ui.excellon_defaults_form.excellon_gen_group.solid_cb,
|
"excellon_solid": self.ui.excellon_defaults_form.excellon_gen_group.solid_cb,
|
||||||
@@ -428,9 +436,14 @@ class App(QtCore.QObject):
|
|||||||
"cncjob_fr_decimals": self.ui.cncjob_defaults_form.cncjob_gen_group.fr_dec_entry,
|
"cncjob_fr_decimals": self.ui.cncjob_defaults_form.cncjob_gen_group.fr_dec_entry,
|
||||||
"cncjob_steps_per_circle": self.ui.cncjob_defaults_form.cncjob_gen_group.steps_per_circle_entry,
|
"cncjob_steps_per_circle": self.ui.cncjob_defaults_form.cncjob_gen_group.steps_per_circle_entry,
|
||||||
|
|
||||||
|
# CNC Job Options
|
||||||
"cncjob_prepend": self.ui.cncjob_defaults_form.cncjob_opt_group.prepend_text,
|
"cncjob_prepend": self.ui.cncjob_defaults_form.cncjob_opt_group.prepend_text,
|
||||||
"cncjob_append": self.ui.cncjob_defaults_form.cncjob_opt_group.append_text,
|
"cncjob_append": self.ui.cncjob_defaults_form.cncjob_opt_group.append_text,
|
||||||
|
|
||||||
|
# CNC Job Advanced Options
|
||||||
|
"cncjob_toolchange_macro": self.ui.cncjob_defaults_form.cncjob_adv_opt_group.toolchange_text,
|
||||||
|
"cncjob_toolchange_macro_enable": self.ui.cncjob_defaults_form.cncjob_adv_opt_group.toolchange_cb,
|
||||||
|
|
||||||
# NCC Tool
|
# NCC Tool
|
||||||
"tools_ncctools": self.ui.tools_defaults_form.tools_ncc_group.ncc_tool_dia_entry,
|
"tools_ncctools": self.ui.tools_defaults_form.tools_ncc_group.ncc_tool_dia_entry,
|
||||||
"tools_nccoverlap": self.ui.tools_defaults_form.tools_ncc_group.ncc_overlap_entry,
|
"tools_nccoverlap": self.ui.tools_defaults_form.tools_ncc_group.ncc_overlap_entry,
|
||||||
@@ -605,6 +618,7 @@ class App(QtCore.QObject):
|
|||||||
"global_point_clipboard_format": "(%.4f, %.4f)",
|
"global_point_clipboard_format": "(%.4f, %.4f)",
|
||||||
"global_zdownrate": None,
|
"global_zdownrate": None,
|
||||||
|
|
||||||
|
# Gerber General
|
||||||
"gerber_plot": True,
|
"gerber_plot": True,
|
||||||
"gerber_solid": True,
|
"gerber_solid": True,
|
||||||
"gerber_multicolored": False,
|
"gerber_multicolored": False,
|
||||||
@@ -612,6 +626,7 @@ class App(QtCore.QObject):
|
|||||||
"gerber_isopasses": 1,
|
"gerber_isopasses": 1,
|
||||||
"gerber_isooverlap": 0.15,
|
"gerber_isooverlap": 0.15,
|
||||||
|
|
||||||
|
# Gerber Options
|
||||||
"gerber_combine_passes": False,
|
"gerber_combine_passes": False,
|
||||||
"gerber_milling_type": "cl",
|
"gerber_milling_type": "cl",
|
||||||
"gerber_noncoppermargin": 0.1,
|
"gerber_noncoppermargin": 0.1,
|
||||||
@@ -621,6 +636,12 @@ class App(QtCore.QObject):
|
|||||||
"gerber_circle_steps": 64,
|
"gerber_circle_steps": 64,
|
||||||
"gerber_use_buffer_for_union": True,
|
"gerber_use_buffer_for_union": True,
|
||||||
|
|
||||||
|
# Gerber Advanced Options
|
||||||
|
"gerber_aperture_display": False,
|
||||||
|
"gerber_aperture_scale_factor": 1.0,
|
||||||
|
"gerber_aperture_buffer_factor": 0.0,
|
||||||
|
"gerber_follow": False,
|
||||||
|
|
||||||
# Excellon General
|
# Excellon General
|
||||||
"excellon_plot": True,
|
"excellon_plot": True,
|
||||||
"excellon_solid": True,
|
"excellon_solid": True,
|
||||||
@@ -696,14 +717,21 @@ class App(QtCore.QObject):
|
|||||||
"geometry_segx": 0.0,
|
"geometry_segx": 0.0,
|
||||||
"geometry_segy": 0.0,
|
"geometry_segy": 0.0,
|
||||||
|
|
||||||
|
# CNC Job General
|
||||||
"cncjob_plot": True,
|
"cncjob_plot": True,
|
||||||
"cncjob_plot_kind": 'all',
|
"cncjob_plot_kind": 'all',
|
||||||
"cncjob_tooldia": 0.0393701,
|
"cncjob_tooldia": 0.0393701,
|
||||||
"cncjob_coords_decimals": 4,
|
"cncjob_coords_decimals": 4,
|
||||||
"cncjob_fr_decimals": 2,
|
"cncjob_fr_decimals": 2,
|
||||||
|
"cncjob_steps_per_circle": 64,
|
||||||
|
|
||||||
|
# CNC Job Options
|
||||||
"cncjob_prepend": "",
|
"cncjob_prepend": "",
|
||||||
"cncjob_append": "",
|
"cncjob_append": "",
|
||||||
"cncjob_steps_per_circle": 64,
|
|
||||||
|
# CNC Job Advanced Options
|
||||||
|
"cncjob_toolchange_macro": "",
|
||||||
|
"cncjob_toolchange_macro_enable": False,
|
||||||
|
|
||||||
"tools_ncctools": "1.0, 0.5",
|
"tools_ncctools": "1.0, 0.5",
|
||||||
"tools_nccoverlap": 0.4,
|
"tools_nccoverlap": 0.4,
|
||||||
|
|||||||
169
FlatCAMGUI.py
169
FlatCAMGUI.py
@@ -2576,10 +2576,14 @@ class GerberPreferencesUI(QtWidgets.QWidget):
|
|||||||
self.gerber_gen_group = GerberGenPrefGroupUI()
|
self.gerber_gen_group = GerberGenPrefGroupUI()
|
||||||
self.gerber_gen_group.setFixedWidth(250)
|
self.gerber_gen_group.setFixedWidth(250)
|
||||||
self.gerber_opt_group = GerberOptPrefGroupUI()
|
self.gerber_opt_group = GerberOptPrefGroupUI()
|
||||||
self.gerber_opt_group.setFixedWidth(250)
|
self.gerber_opt_group.setFixedWidth(200)
|
||||||
|
self.gerber_adv_opt_group = GerberAdvOptPrefGroupUI()
|
||||||
|
self.gerber_adv_opt_group.setFixedWidth(200)
|
||||||
|
|
||||||
self.layout.addWidget(self.gerber_gen_group)
|
self.layout.addWidget(self.gerber_gen_group)
|
||||||
self.layout.addWidget(self.gerber_opt_group)
|
self.layout.addWidget(self.gerber_opt_group)
|
||||||
|
self.layout.addWidget(self.gerber_adv_opt_group)
|
||||||
|
|
||||||
self.layout.addStretch()
|
self.layout.addStretch()
|
||||||
|
|
||||||
|
|
||||||
@@ -2700,9 +2704,13 @@ class CNCJobPreferencesUI(QtWidgets.QWidget):
|
|||||||
self.cncjob_gen_group.setFixedWidth(270)
|
self.cncjob_gen_group.setFixedWidth(270)
|
||||||
self.cncjob_opt_group = CNCJobOptPrefGroupUI()
|
self.cncjob_opt_group = CNCJobOptPrefGroupUI()
|
||||||
self.cncjob_opt_group.setFixedWidth(260)
|
self.cncjob_opt_group.setFixedWidth(260)
|
||||||
|
self.cncjob_adv_opt_group = CNCJobAdvOptPrefGroupUI()
|
||||||
|
self.cncjob_adv_opt_group.setFixedWidth(260)
|
||||||
|
|
||||||
self.layout.addWidget(self.cncjob_gen_group)
|
self.layout.addWidget(self.cncjob_gen_group)
|
||||||
self.layout.addWidget(self.cncjob_opt_group)
|
self.layout.addWidget(self.cncjob_opt_group)
|
||||||
|
self.layout.addWidget(self.cncjob_adv_opt_group)
|
||||||
|
|
||||||
self.layout.addStretch()
|
self.layout.addStretch()
|
||||||
|
|
||||||
|
|
||||||
@@ -3288,26 +3296,27 @@ class GerberGenPrefGroupUI(OptionsGroupUI):
|
|||||||
|
|
||||||
grid0 = QtWidgets.QGridLayout()
|
grid0 = QtWidgets.QGridLayout()
|
||||||
self.layout.addLayout(grid0)
|
self.layout.addLayout(grid0)
|
||||||
# Plot CB
|
|
||||||
self.plot_cb = FCCheckBox(label='Plot')
|
|
||||||
self.plot_options_label.setToolTip(
|
|
||||||
"Plot (show) this object."
|
|
||||||
)
|
|
||||||
grid0.addWidget(self.plot_cb, 0, 0)
|
|
||||||
|
|
||||||
# Solid CB
|
# Solid CB
|
||||||
self.solid_cb = FCCheckBox(label='Solid')
|
self.solid_cb = FCCheckBox(label='Solid')
|
||||||
self.solid_cb.setToolTip(
|
self.solid_cb.setToolTip(
|
||||||
"Solid color polygons."
|
"Solid color polygons."
|
||||||
)
|
)
|
||||||
grid0.addWidget(self.solid_cb, 0, 1)
|
grid0.addWidget(self.solid_cb, 0, 0)
|
||||||
|
|
||||||
# Multicolored CB
|
# Multicolored CB
|
||||||
self.multicolored_cb = FCCheckBox(label='M-Color')
|
self.multicolored_cb = FCCheckBox(label='M-Color')
|
||||||
self.multicolored_cb.setToolTip(
|
self.multicolored_cb.setToolTip(
|
||||||
"Draw polygons in different colors."
|
"Draw polygons in different colors."
|
||||||
)
|
)
|
||||||
grid0.addWidget(self.multicolored_cb, 0, 2)
|
grid0.addWidget(self.multicolored_cb, 0, 1)
|
||||||
|
|
||||||
|
# Plot CB
|
||||||
|
self.plot_cb = FCCheckBox(label='Plot')
|
||||||
|
self.plot_options_label.setToolTip(
|
||||||
|
"Plot (show) this object."
|
||||||
|
)
|
||||||
|
grid0.addWidget(self.plot_cb, 0, 2)
|
||||||
|
|
||||||
# Number of circle steps for circular aperture linear approximation
|
# Number of circle steps for circular aperture linear approximation
|
||||||
self.circle_steps_label = QtWidgets.QLabel("Circle Steps:")
|
self.circle_steps_label = QtWidgets.QLabel("Circle Steps:")
|
||||||
@@ -3447,6 +3456,73 @@ class GerberOptPrefGroupUI(OptionsGroupUI):
|
|||||||
self.layout.addStretch()
|
self.layout.addStretch()
|
||||||
|
|
||||||
|
|
||||||
|
class GerberAdvOptPrefGroupUI(OptionsGroupUI):
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
# OptionsGroupUI.__init__(self, "Gerber Adv. Options Preferences", parent=parent)
|
||||||
|
super(GerberAdvOptPrefGroupUI, self).__init__(self)
|
||||||
|
|
||||||
|
self.setTitle(str("Gerber Adv. Options"))
|
||||||
|
|
||||||
|
|
||||||
|
## Advanced Gerber Parameters
|
||||||
|
self.adv_param_label = QtWidgets.QLabel("<b>Advanced Param.:</b>")
|
||||||
|
self.adv_param_label.setToolTip(
|
||||||
|
"A list of Gerber advanced parameters.\n"
|
||||||
|
"Those parameters are available only for\n"
|
||||||
|
"Advanced App. Level."
|
||||||
|
)
|
||||||
|
self.layout.addWidget(self.adv_param_label)
|
||||||
|
|
||||||
|
grid0 = QtWidgets.QGridLayout()
|
||||||
|
self.layout.addLayout(grid0)
|
||||||
|
|
||||||
|
# Follow Attribute
|
||||||
|
self.follow_cb = FCCheckBox(label='"Follow"')
|
||||||
|
self.follow_cb.setToolTip(
|
||||||
|
"Generate a 'Follow' geometry.\n"
|
||||||
|
"This means that it will cut through\n"
|
||||||
|
"the middle of the trace."
|
||||||
|
|
||||||
|
)
|
||||||
|
grid0.addWidget(self.follow_cb, 0, 0)
|
||||||
|
|
||||||
|
# Aperture Table Visibility CB
|
||||||
|
self.aperture_table_visibility_cb = FCCheckBox(label='Table Show/Hide')
|
||||||
|
self.aperture_table_visibility_cb.setToolTip(
|
||||||
|
"Toggle the display of the Gerber Apertures Table.\n"
|
||||||
|
"Also, on hide, it will delete all mark shapes\n"
|
||||||
|
"that are drawn on canvas."
|
||||||
|
|
||||||
|
)
|
||||||
|
grid0.addWidget(self.aperture_table_visibility_cb, 1, 0)
|
||||||
|
|
||||||
|
# Scale Aperture Factor
|
||||||
|
self.scale_aperture_label = QtWidgets.QLabel('Ap. Scale Factor:')
|
||||||
|
self.scale_aperture_label.setToolTip(
|
||||||
|
"Change the size of the selected apertures.\n"
|
||||||
|
"Factor by which to multiply\n"
|
||||||
|
"geometric features of this object."
|
||||||
|
)
|
||||||
|
grid0.addWidget(self.scale_aperture_label, 2, 0)
|
||||||
|
|
||||||
|
self.scale_aperture_entry = FloatEntry2()
|
||||||
|
grid0.addWidget(self.scale_aperture_entry, 2, 1)
|
||||||
|
|
||||||
|
# Buffer Aperture Factor
|
||||||
|
self.buffer_aperture_label = QtWidgets.QLabel('Ap. Buffer Factor:')
|
||||||
|
self.buffer_aperture_label.setToolTip(
|
||||||
|
"Change the size of the selected apertures.\n"
|
||||||
|
"Factor by which to expand/shrink\n"
|
||||||
|
"geometric features of this object."
|
||||||
|
)
|
||||||
|
grid0.addWidget(self.buffer_aperture_label, 3, 0)
|
||||||
|
|
||||||
|
self.buffer_aperture_entry = FloatEntry2()
|
||||||
|
grid0.addWidget(self.buffer_aperture_entry, 3, 1)
|
||||||
|
|
||||||
|
self.layout.addStretch()
|
||||||
|
|
||||||
|
|
||||||
class ExcellonGenPrefGroupUI(OptionsGroupUI):
|
class ExcellonGenPrefGroupUI(OptionsGroupUI):
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
@@ -4546,6 +4622,81 @@ class CNCJobOptPrefGroupUI(OptionsGroupUI):
|
|||||||
self.layout.addStretch()
|
self.layout.addStretch()
|
||||||
|
|
||||||
|
|
||||||
|
class CNCJobAdvOptPrefGroupUI(OptionsGroupUI):
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
# OptionsGroupUI.__init__(self, "CNC Job Advanced Options Preferences", parent=None)
|
||||||
|
super(CNCJobAdvOptPrefGroupUI, self).__init__(self)
|
||||||
|
|
||||||
|
self.setTitle(str("CNC Job Adv. Options"))
|
||||||
|
|
||||||
|
## Export G-Code
|
||||||
|
self.export_gcode_label = QtWidgets.QLabel("<b>Export G-Code:</b>")
|
||||||
|
self.export_gcode_label.setToolTip(
|
||||||
|
"Export and save G-Code to\n"
|
||||||
|
"make this object to a file."
|
||||||
|
)
|
||||||
|
self.layout.addWidget(self.export_gcode_label)
|
||||||
|
|
||||||
|
# Prepend to G-Code
|
||||||
|
toolchangelabel = QtWidgets.QLabel('Toolchange G-Code:')
|
||||||
|
toolchangelabel.setToolTip(
|
||||||
|
"Type here any G-Code commands you would\n"
|
||||||
|
"like to be executed when Toolchange event is encountered.\n"
|
||||||
|
"This will constitute a Custom Toolchange GCode,\n"
|
||||||
|
"or a Toolchange Macro."
|
||||||
|
)
|
||||||
|
self.layout.addWidget(toolchangelabel)
|
||||||
|
|
||||||
|
self.toolchange_text = FCTextArea()
|
||||||
|
self.layout.addWidget(self.toolchange_text)
|
||||||
|
|
||||||
|
hlay = QtWidgets.QHBoxLayout()
|
||||||
|
self.layout.addLayout(hlay)
|
||||||
|
|
||||||
|
# Toolchange Replacement GCode
|
||||||
|
self.toolchange_cb = FCCheckBox(label='Use Toolchange Macro')
|
||||||
|
self.toolchange_cb.setToolTip(
|
||||||
|
"Check this box if you want to use\n"
|
||||||
|
"a Custom Toolchange GCode (macro)."
|
||||||
|
)
|
||||||
|
hlay.addWidget(self.toolchange_cb)
|
||||||
|
hlay.addStretch()
|
||||||
|
|
||||||
|
hlay1 = QtWidgets.QHBoxLayout()
|
||||||
|
self.layout.addLayout(hlay1)
|
||||||
|
|
||||||
|
# Variable list
|
||||||
|
self.tc_variable_combo = FCComboBox()
|
||||||
|
self.tc_variable_combo.setToolTip(
|
||||||
|
"A list of the FlatCAM variables that can be used\n"
|
||||||
|
"in the Toolchange event.\n"
|
||||||
|
"They have to be surrounded by the '%' symbol"
|
||||||
|
)
|
||||||
|
hlay1.addWidget(self.tc_variable_combo)
|
||||||
|
|
||||||
|
# Populate the Combo Box
|
||||||
|
variables = ['tool', 'toolC', 't_drills', 'toolchangex', 'toolchangey', 'toolchangez']
|
||||||
|
self.tc_variable_combo.addItems(variables)
|
||||||
|
self.tc_variable_combo.setItemData(0, "tool = tool number", Qt.ToolTipRole)
|
||||||
|
self.tc_variable_combo.setItemData(1, "toolC = tool diameter", Qt.ToolTipRole)
|
||||||
|
self.tc_variable_combo.setItemData(2, "t_drills = for Excellon, total number of drills", Qt.ToolTipRole)
|
||||||
|
self.tc_variable_combo.setItemData(3, "toolchangex = X coord for Toolchange", Qt.ToolTipRole)
|
||||||
|
self.tc_variable_combo.setItemData(4, "toolchangey = Y coord for Toolchange", Qt.ToolTipRole)
|
||||||
|
self.tc_variable_combo.setItemData(5, "toolchangez = Z coord for Toolchange", Qt.ToolTipRole)
|
||||||
|
|
||||||
|
hlay1.addStretch()
|
||||||
|
|
||||||
|
# Insert Variable into the Toolchange G-Code Text Box
|
||||||
|
self.tc_insert_buton = FCButton("Insert")
|
||||||
|
self.tc_insert_buton.setToolTip(
|
||||||
|
"Insert the variable in the GCode Box\n"
|
||||||
|
"surrounded by the '%' symbol."
|
||||||
|
)
|
||||||
|
hlay1.addWidget(self.tc_insert_buton)
|
||||||
|
|
||||||
|
self.layout.addStretch()
|
||||||
|
|
||||||
|
|
||||||
class ToolsNCCPrefGroupUI(OptionsGroupUI):
|
class ToolsNCCPrefGroupUI(OptionsGroupUI):
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
# OptionsGroupUI.__init__(self, "NCC Tool Options", parent=parent)
|
# OptionsGroupUI.__init__(self, "NCC Tool Options", parent=parent)
|
||||||
|
|||||||
181
FlatCAMObj.py
181
FlatCAMObj.py
@@ -382,11 +382,19 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
|||||||
grb_final.solid_geometry = []
|
grb_final.solid_geometry = []
|
||||||
grb_final.follow_geometry = []
|
grb_final.follow_geometry = []
|
||||||
|
|
||||||
|
if not grb_final.apertures:
|
||||||
|
grb_final.apertures = {}
|
||||||
|
|
||||||
if type(grb_final.solid_geometry) is not list:
|
if type(grb_final.solid_geometry) is not list:
|
||||||
grb_final.solid_geometry = [grb_final.solid_geometry]
|
grb_final.solid_geometry = [grb_final.solid_geometry]
|
||||||
grb_final.follow_geometry = [grb_final.follow_geometry]
|
grb_final.follow_geometry = [grb_final.follow_geometry]
|
||||||
|
|
||||||
for grb in grb_list:
|
for grb in grb_list:
|
||||||
|
|
||||||
|
# Expand lists
|
||||||
|
if type(grb) is list:
|
||||||
|
FlatCAMGerber.merge(grb, grb_final)
|
||||||
|
else: # If not list, just append
|
||||||
for option in grb.options:
|
for option in grb.options:
|
||||||
if option is not 'name':
|
if option is not 'name':
|
||||||
try:
|
try:
|
||||||
@@ -394,14 +402,19 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
|||||||
except:
|
except:
|
||||||
log.warning("Failed to copy option.", option)
|
log.warning("Failed to copy option.", option)
|
||||||
|
|
||||||
# Expand lists
|
|
||||||
if type(grb) is list:
|
|
||||||
FlatCAMGerber.merge(grb, grb_final)
|
|
||||||
else: # If not list, just append
|
|
||||||
for geos in grb.solid_geometry:
|
for geos in grb.solid_geometry:
|
||||||
grb_final.solid_geometry.append(geos)
|
grb_final.solid_geometry.append(geos)
|
||||||
grb_final.follow_geometry.append(geos)
|
grb_final.follow_geometry.append(geos)
|
||||||
|
|
||||||
|
for ap in grb.apertures:
|
||||||
|
if ap not in grb_final.apertures:
|
||||||
|
grb_final.apertures[ap] = grb.apertures[ap]
|
||||||
|
else:
|
||||||
|
if 'solid_geometry' not in grb_final.apertures[ap]:
|
||||||
|
grb_final.apertures[ap]['solid_geometry'] = []
|
||||||
|
for geo in grb.apertures[ap]['solid_geometry']:
|
||||||
|
grb_final.apertures[ap]['solid_geometry'].append(geo)
|
||||||
|
|
||||||
grb_final.solid_geometry = MultiPolygon(grb_final.solid_geometry)
|
grb_final.solid_geometry = MultiPolygon(grb_final.solid_geometry)
|
||||||
grb_final.follow_geometry = MultiPolygon(grb_final.follow_geometry)
|
grb_final.follow_geometry = MultiPolygon(grb_final.follow_geometry)
|
||||||
|
|
||||||
@@ -425,7 +438,11 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
|||||||
"noncoppermargin": 0.0,
|
"noncoppermargin": 0.0,
|
||||||
"noncopperrounded": False,
|
"noncopperrounded": False,
|
||||||
"bboxmargin": 0.0,
|
"bboxmargin": 0.0,
|
||||||
"bboxrounded": False
|
"bboxrounded": False,
|
||||||
|
"aperture_display": False,
|
||||||
|
"aperture_scale_factor": 1.0,
|
||||||
|
"aperture_buffer_factor": 0.0,
|
||||||
|
"follow": False
|
||||||
})
|
})
|
||||||
|
|
||||||
# type of isolation: 0 = exteriors, 1 = interiors, 2 = complete isolation (both interiors and exteriors)
|
# type of isolation: 0 = exteriors, 1 = interiors, 2 = complete isolation (both interiors and exteriors)
|
||||||
@@ -479,7 +496,11 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
|||||||
"noncoppermargin": self.ui.noncopper_margin_entry,
|
"noncoppermargin": self.ui.noncopper_margin_entry,
|
||||||
"noncopperrounded": self.ui.noncopper_rounded_cb,
|
"noncopperrounded": self.ui.noncopper_rounded_cb,
|
||||||
"bboxmargin": self.ui.bbmargin_entry,
|
"bboxmargin": self.ui.bbmargin_entry,
|
||||||
"bboxrounded": self.ui.bbrounded_cb
|
"bboxrounded": self.ui.bbrounded_cb,
|
||||||
|
"aperture_display": self.ui.aperture_table_visibility_cb,
|
||||||
|
"aperture_scale_factor": self.ui.scale_aperture_entry,
|
||||||
|
"aperture_buffer_factor": self.ui.buffer_aperture_entry,
|
||||||
|
"follow": self.ui.follow_cb
|
||||||
})
|
})
|
||||||
|
|
||||||
# Fill form fields only on object create
|
# Fill form fields only on object create
|
||||||
@@ -498,6 +519,9 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
|||||||
self.ui.generate_noncopper_button.clicked.connect(self.on_generatenoncopper_button_click)
|
self.ui.generate_noncopper_button.clicked.connect(self.on_generatenoncopper_button_click)
|
||||||
self.ui.aperture_table_visibility_cb.stateChanged.connect(self.on_aperture_table_visibility_change)
|
self.ui.aperture_table_visibility_cb.stateChanged.connect(self.on_aperture_table_visibility_change)
|
||||||
self.ui.follow_cb.stateChanged.connect(self.on_follow_cb_click)
|
self.ui.follow_cb.stateChanged.connect(self.on_follow_cb_click)
|
||||||
|
self.ui.scale_aperture_button.clicked.connect(self.on_scale_aperture_click)
|
||||||
|
self.ui.buffer_aperture_button.clicked.connect(self.on_buffer_aperture_click)
|
||||||
|
self.ui.new_grb_button.clicked.connect(self.on_new_modified_gerber)
|
||||||
|
|
||||||
# Show/Hide Advanced Options
|
# Show/Hide Advanced Options
|
||||||
if self.app.defaults["global_app_level"] == 'b':
|
if self.app.defaults["global_app_level"] == 'b':
|
||||||
@@ -513,6 +537,9 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
|||||||
else:
|
else:
|
||||||
self.ui.level.setText('<span style="color:red;"><b>Advanced</b></span>')
|
self.ui.level.setText('<span style="color:red;"><b>Advanced</b></span>')
|
||||||
|
|
||||||
|
# set initial state of the aperture table and associated widgets
|
||||||
|
self.on_aperture_table_visibility_change()
|
||||||
|
|
||||||
self.build_ui()
|
self.build_ui()
|
||||||
|
|
||||||
def build_ui(self):
|
def build_ui(self):
|
||||||
@@ -963,17 +990,151 @@ class FlatCAMGerber(FlatCAMObj, Gerber):
|
|||||||
self.ui.scale_aperture_label.setVisible(True)
|
self.ui.scale_aperture_label.setVisible(True)
|
||||||
self.ui.scale_aperture_entry.setVisible(True)
|
self.ui.scale_aperture_entry.setVisible(True)
|
||||||
self.ui.scale_aperture_button.setVisible(True)
|
self.ui.scale_aperture_button.setVisible(True)
|
||||||
|
|
||||||
|
self.ui.buffer_aperture_label.setVisible(True)
|
||||||
|
self.ui.buffer_aperture_entry.setVisible(True)
|
||||||
|
self.ui.buffer_aperture_button.setVisible(True)
|
||||||
|
|
||||||
|
self.ui.new_grb_label.setVisible(True)
|
||||||
|
self.ui.new_grb_button.setVisible(True)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.ui.apertures_table.setVisible(False)
|
self.ui.apertures_table.setVisible(False)
|
||||||
self.ui.scale_aperture_label.setVisible(False)
|
self.ui.scale_aperture_label.setVisible(False)
|
||||||
self.ui.scale_aperture_entry.setVisible(False)
|
self.ui.scale_aperture_entry.setVisible(False)
|
||||||
self.ui.scale_aperture_button.setVisible(False)
|
self.ui.scale_aperture_button.setVisible(False)
|
||||||
|
|
||||||
|
self.ui.buffer_aperture_label.setVisible(False)
|
||||||
|
self.ui.buffer_aperture_entry.setVisible(False)
|
||||||
|
self.ui.buffer_aperture_button.setVisible(False)
|
||||||
|
|
||||||
|
self.ui.new_grb_label.setVisible(False)
|
||||||
|
self.ui.new_grb_button.setVisible(False)
|
||||||
|
|
||||||
# on hide disable all mark plots
|
# on hide disable all mark plots
|
||||||
for row in range(self.ui.apertures_table.rowCount()):
|
for row in range(self.ui.apertures_table.rowCount()):
|
||||||
self.ui.apertures_table.cellWidget(row, 5).set_value(False)
|
self.ui.apertures_table.cellWidget(row, 5).set_value(False)
|
||||||
self.mark_shapes.clear(update=True)
|
self.mark_shapes.clear(update=True)
|
||||||
|
|
||||||
|
def on_scale_aperture_click(self, signal):
|
||||||
|
try:
|
||||||
|
factor = self.ui.scale_aperture_entry.get_value()
|
||||||
|
except Exception as e:
|
||||||
|
log.debug("FlatCAMGerber.on_scale_aperture_click() --> %s" % str(e))
|
||||||
|
self.app.inform.emit("[ERROR_NOTCL] The aperture scale factor value is missing or wrong format.")
|
||||||
|
return
|
||||||
|
|
||||||
|
def scale_recursion(geom):
|
||||||
|
if type(geom) == list or type(geom) is MultiPolygon:
|
||||||
|
geoms=list()
|
||||||
|
for local_geom in geom:
|
||||||
|
geoms.append(scale_recursion(local_geom))
|
||||||
|
return geoms
|
||||||
|
else:
|
||||||
|
return affinity.scale(geom, factor, factor, origin='center')
|
||||||
|
|
||||||
|
if not self.ui.apertures_table.selectedItems():
|
||||||
|
self.app.inform.emit("[WARNING_NOTCL] No aperture to scale. Select at least one aperture and try again.")
|
||||||
|
return
|
||||||
|
|
||||||
|
for x in self.ui.apertures_table.selectedItems():
|
||||||
|
try:
|
||||||
|
apid = self.ui.apertures_table.item(x.row(), 1).text()
|
||||||
|
except Exception as e:
|
||||||
|
log.debug("FlatCAMGerber.on_scale_aperture_click() --> %s" % str(e))
|
||||||
|
|
||||||
|
self.apertures[apid]['solid_geometry'] = scale_recursion(self.apertures[apid]['solid_geometry'])
|
||||||
|
|
||||||
|
self.on_mark_cb_click_table()
|
||||||
|
|
||||||
|
def on_buffer_aperture_click(self, signal):
|
||||||
|
try:
|
||||||
|
buff_value = self.ui.buffer_aperture_entry.get_value()
|
||||||
|
except Exception as e:
|
||||||
|
log.debug("FlatCAMGerber.on_scale_aperture_click() --> %s" % str(e))
|
||||||
|
self.app.inform.emit("[ERROR_NOTCL] The aperture buffer value is missing or wrong format.")
|
||||||
|
return
|
||||||
|
|
||||||
|
def buffer_recursion(geom):
|
||||||
|
if type(geom) == list or type(geom) is MultiPolygon:
|
||||||
|
geoms=list()
|
||||||
|
for local_geom in geom:
|
||||||
|
geoms.append(buffer_recursion(local_geom))
|
||||||
|
return geoms
|
||||||
|
else:
|
||||||
|
return geom.buffer(buff_value, join_style=2)
|
||||||
|
|
||||||
|
if not self.ui.apertures_table.selectedItems():
|
||||||
|
self.app.inform.emit("[WARNING_NOTCL] No aperture to scale. Select at least one aperture and try again.")
|
||||||
|
return
|
||||||
|
|
||||||
|
for x in self.ui.apertures_table.selectedItems():
|
||||||
|
try:
|
||||||
|
apid = self.ui.apertures_table.item(x.row(), 1).text()
|
||||||
|
except Exception as e:
|
||||||
|
log.debug("FlatCAMGerber.on_scale_aperture_click() --> %s" % str(e))
|
||||||
|
|
||||||
|
self.apertures[apid]['solid_geometry'] = buffer_recursion(self.apertures[apid]['solid_geometry'])
|
||||||
|
|
||||||
|
self.on_mark_cb_click_table()
|
||||||
|
|
||||||
|
def on_new_modified_gerber(self, signal):
|
||||||
|
|
||||||
|
name = '%s_ap_mod' % str(self.options['name'])
|
||||||
|
apertures = deepcopy(self.apertures)
|
||||||
|
options = self.options
|
||||||
|
|
||||||
|
# geometry storage
|
||||||
|
poly_buff = []
|
||||||
|
|
||||||
|
# How the object should be initialized
|
||||||
|
def obj_init(gerber_obj, app_obj):
|
||||||
|
assert isinstance(gerber_obj, FlatCAMGerber), \
|
||||||
|
"Expected to initialize a FlatCAMGerber but got %s" % type(gerber_obj)
|
||||||
|
|
||||||
|
gerber_obj.source_file = ''
|
||||||
|
gerber_obj.multigeo = False
|
||||||
|
gerber_obj.follow = False
|
||||||
|
|
||||||
|
gerber_obj.apertures = apertures
|
||||||
|
for option in options:
|
||||||
|
# we don't want to overwrite the new name and we don't want to share the 'plot' state
|
||||||
|
# because the new object should ve visible even if the source is not visible
|
||||||
|
if option != 'name' and option != 'plot':
|
||||||
|
gerber_obj.options[option] = options[option]
|
||||||
|
|
||||||
|
# regenerate solid_geometry
|
||||||
|
app_obj.log.debug("Creating new Gerber object. Joining %s polygons.")
|
||||||
|
for ap in apertures:
|
||||||
|
for geo in apertures[ap]['solid_geometry']:
|
||||||
|
poly_buff.append(geo)
|
||||||
|
|
||||||
|
# buffering the poly_buff
|
||||||
|
new_geo = MultiPolygon(poly_buff)
|
||||||
|
new_geo = new_geo.buffer(0.0000001)
|
||||||
|
new_geo = new_geo.buffer(-0.0000001)
|
||||||
|
|
||||||
|
gerber_obj.solid_geometry = new_geo
|
||||||
|
|
||||||
|
app_obj.log.debug("Finished creation of a new Gerber object. Polygons joined.")
|
||||||
|
|
||||||
|
log.debug("on_new_modified_gerber()")
|
||||||
|
|
||||||
|
with self.app.proc_container.new("Generating Gerber") as proc:
|
||||||
|
|
||||||
|
self.app.progress.emit(10)
|
||||||
|
|
||||||
|
### Object creation ###
|
||||||
|
ret = self.app.new_object("gerber", name, obj_init, autoselected=False)
|
||||||
|
if ret == 'fail':
|
||||||
|
self.app.inform.emit('[ERROR_NOTCL] Cretion of Gerber failed.')
|
||||||
|
return
|
||||||
|
|
||||||
|
self.app.progress.emit(100)
|
||||||
|
|
||||||
|
# GUI feedback
|
||||||
|
self.app.inform.emit("[success] Created: " + name)
|
||||||
|
|
||||||
def convert_units(self, units):
|
def convert_units(self, units):
|
||||||
"""
|
"""
|
||||||
Converts the units of the object by scaling dimensions in all geometry
|
Converts the units of the object by scaling dimensions in all geometry
|
||||||
@@ -4698,7 +4859,9 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
|
|||||||
"prepend": "",
|
"prepend": "",
|
||||||
"dwell": False,
|
"dwell": False,
|
||||||
"dwelltime": 1,
|
"dwelltime": 1,
|
||||||
"type": 'Geometry'
|
"type": 'Geometry',
|
||||||
|
"toolchange_macro": '',
|
||||||
|
"toolchange_macro_enable": False
|
||||||
})
|
})
|
||||||
|
|
||||||
'''
|
'''
|
||||||
@@ -4900,6 +5063,8 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
|
|||||||
# "tooldia": self.ui.tooldia_entry,
|
# "tooldia": self.ui.tooldia_entry,
|
||||||
"append": self.ui.append_text,
|
"append": self.ui.append_text,
|
||||||
"prepend": self.ui.prepend_text,
|
"prepend": self.ui.prepend_text,
|
||||||
|
"toolchange_macro": self.ui.toolchange_text,
|
||||||
|
"toolchange_macro_enable": self.ui.toolchange_cb
|
||||||
})
|
})
|
||||||
|
|
||||||
# Fill form fields only on object create
|
# Fill form fields only on object create
|
||||||
@@ -4924,8 +5089,10 @@ class FlatCAMCNCjob(FlatCAMObj, CNCjob):
|
|||||||
if self.app.defaults["global_app_level"] == 'b':
|
if self.app.defaults["global_app_level"] == 'b':
|
||||||
self.ui.level.setText('<span style="color:green;"><b>Basic</b></span>')
|
self.ui.level.setText('<span style="color:green;"><b>Basic</b></span>')
|
||||||
|
|
||||||
|
self.ui.cnc_frame.hide()
|
||||||
else:
|
else:
|
||||||
self.ui.level.setText('<span style="color:red;"><b>Advanced</b></span>')
|
self.ui.level.setText('<span style="color:red;"><b>Advanced</b></span>')
|
||||||
|
self.ui.cnc_frame.show()
|
||||||
|
|
||||||
self.ui.updateplot_button.clicked.connect(self.on_updateplot_button_click)
|
self.ui.updateplot_button.clicked.connect(self.on_updateplot_button_click)
|
||||||
self.ui.export_gcode_button.clicked.connect(self.on_exportgcode_button_click)
|
self.ui.export_gcode_button.clicked.connect(self.on_exportgcode_button_click)
|
||||||
|
|||||||
140
ObjectUI.py
140
ObjectUI.py
@@ -1,7 +1,8 @@
|
|||||||
import sys
|
import sys
|
||||||
from PyQt5 import QtGui, QtCore, QtWidgets, QtWidgets
|
from PyQt5 import QtGui, QtCore, QtWidgets
|
||||||
|
from PyQt5.QtCore import Qt
|
||||||
from GUIElements import FCEntry, FloatEntry, EvalEntry, FCCheckBox, FCTable, \
|
from GUIElements import FCEntry, FloatEntry, EvalEntry, FCCheckBox, FCTable, \
|
||||||
LengthEntry, FCTextArea, IntEntry, RadioSet, OptionalInputSection, FCComboBox, FloatEntry2, EvalEntry2
|
LengthEntry, FCTextArea, IntEntry, RadioSet, OptionalInputSection, FCComboBox, FloatEntry2, EvalEntry2, FCButton
|
||||||
from camlib import Excellon
|
from camlib import Excellon
|
||||||
|
|
||||||
|
|
||||||
@@ -180,6 +181,12 @@ class GerberObjectUI(ObjectUI):
|
|||||||
|
|
||||||
# Aperture Table Visibility CB
|
# Aperture Table Visibility CB
|
||||||
self.aperture_table_visibility_cb = FCCheckBox('Show/Hide')
|
self.aperture_table_visibility_cb = FCCheckBox('Show/Hide')
|
||||||
|
self.aperture_table_visibility_cb.setToolTip(
|
||||||
|
"Toogle the display of the Gerber Apertures Table.\n"
|
||||||
|
"Also, on hide, it will delete all mark shapes\n"
|
||||||
|
"that are drawn on canvas."
|
||||||
|
|
||||||
|
)
|
||||||
self.aperture_table_visibility_cb.setLayoutDirection(QtCore.Qt.RightToLeft)
|
self.aperture_table_visibility_cb.setLayoutDirection(QtCore.Qt.RightToLeft)
|
||||||
hlay_plot.addWidget(self.aperture_table_visibility_cb)
|
hlay_plot.addWidget(self.aperture_table_visibility_cb)
|
||||||
|
|
||||||
@@ -207,30 +214,69 @@ class GerberObjectUI(ObjectUI):
|
|||||||
# self.apertures_table.setColumnHidden(5, True)
|
# self.apertures_table.setColumnHidden(5, True)
|
||||||
|
|
||||||
#### Aperture Scale ####
|
#### Aperture Scale ####
|
||||||
self.scale_aperture_grid = QtWidgets.QGridLayout()
|
self.transform_aperture_grid = QtWidgets.QGridLayout()
|
||||||
self.custom_box.addLayout(self.scale_aperture_grid)
|
self.custom_box.addLayout(self.transform_aperture_grid)
|
||||||
|
|
||||||
# Factor
|
# Scale Aperture Factor
|
||||||
self.scale_aperture_label = QtWidgets.QLabel('<b>Factor:</b>')
|
self.scale_aperture_label = QtWidgets.QLabel('Scale Factor:')
|
||||||
self.scale_aperture_label.setToolTip(
|
self.scale_aperture_label.setToolTip(
|
||||||
"Change the size of the selected apertures.\n"
|
"Change the size of the selected apertures.\n"
|
||||||
"Factor by which to multiply\n"
|
"Factor by which to multiply\n"
|
||||||
"geometric features of this object."
|
"geometric features of this object."
|
||||||
)
|
)
|
||||||
self.scale_aperture_label.setFixedWidth(90)
|
self.scale_aperture_label.setFixedWidth(90)
|
||||||
self.scale_aperture_grid.addWidget(self.scale_aperture_label, 0, 0)
|
self.transform_aperture_grid.addWidget(self.scale_aperture_label, 0, 0)
|
||||||
|
|
||||||
self.scale_aperture_entry = FloatEntry2()
|
self.scale_aperture_entry = FloatEntry2()
|
||||||
self.scale_aperture_entry.set_value(1.0)
|
self.transform_aperture_grid.addWidget(self.scale_aperture_entry, 0, 1)
|
||||||
self.scale_aperture_grid.addWidget(self.scale_aperture_entry, 0, 1)
|
|
||||||
|
|
||||||
# Scale Button
|
# Scale Button
|
||||||
self.scale_aperture_button = QtWidgets.QPushButton('Scale')
|
self.scale_aperture_button = QtWidgets.QPushButton('Scale')
|
||||||
self.scale_aperture_button.setToolTip(
|
self.scale_aperture_button.setToolTip(
|
||||||
"Perform scaling operation."
|
"Perform scaling operation."
|
||||||
)
|
)
|
||||||
self.scale_aperture_button.setFixedWidth(40)
|
self.scale_aperture_button.setFixedWidth(50)
|
||||||
self.scale_aperture_grid.addWidget(self.scale_aperture_button, 0, 2)
|
self.transform_aperture_grid.addWidget(self.scale_aperture_button, 0, 2)
|
||||||
|
|
||||||
|
# Buffer Aperture Factor
|
||||||
|
self.buffer_aperture_label = QtWidgets.QLabel('Buffer Factor:')
|
||||||
|
self.buffer_aperture_label.setToolTip(
|
||||||
|
"Change the size of the selected apertures.\n"
|
||||||
|
"Factor by which to expand/shrink\n"
|
||||||
|
"geometric features of this object."
|
||||||
|
)
|
||||||
|
self.buffer_aperture_label.setFixedWidth(90)
|
||||||
|
self.transform_aperture_grid.addWidget(self.buffer_aperture_label, 1, 0)
|
||||||
|
|
||||||
|
self.buffer_aperture_entry = FloatEntry2()
|
||||||
|
self.transform_aperture_grid.addWidget(self.buffer_aperture_entry, 1, 1)
|
||||||
|
|
||||||
|
# Buffer Button
|
||||||
|
self.buffer_aperture_button = QtWidgets.QPushButton('Buffer')
|
||||||
|
self.buffer_aperture_button.setToolTip(
|
||||||
|
"Perform scaling operation."
|
||||||
|
)
|
||||||
|
self.buffer_aperture_button.setFixedWidth(50)
|
||||||
|
self.transform_aperture_grid.addWidget(self.buffer_aperture_button, 1, 2)
|
||||||
|
|
||||||
|
new_hlay = QtWidgets.QHBoxLayout()
|
||||||
|
self.custom_box.addLayout(new_hlay)
|
||||||
|
|
||||||
|
self.new_grb_label = QtWidgets.QLabel("<b>Generate new Gerber Object:</b>")
|
||||||
|
self.new_grb_label.setToolTip(
|
||||||
|
"Will generate a new Gerber object from the changed apertures.\n"
|
||||||
|
"This new object can then be isolated etc."
|
||||||
|
)
|
||||||
|
new_hlay.addWidget(self.new_grb_label)
|
||||||
|
|
||||||
|
new_hlay.addStretch()
|
||||||
|
|
||||||
|
self.new_grb_button = FCButton('Go')
|
||||||
|
self.new_grb_button.setToolTip(
|
||||||
|
"Will generate a new Gerber object from the changed apertures.\n"
|
||||||
|
"This new object can then be isolated etc.")
|
||||||
|
self.new_grb_button.setFixedWidth(50)
|
||||||
|
new_hlay.addWidget(self.new_grb_button)
|
||||||
|
|
||||||
# start with apertures table hidden
|
# start with apertures table hidden
|
||||||
self.apertures_table.setVisible(False)
|
self.apertures_table.setVisible(False)
|
||||||
@@ -238,6 +284,10 @@ class GerberObjectUI(ObjectUI):
|
|||||||
self.scale_aperture_entry.setVisible(False)
|
self.scale_aperture_entry.setVisible(False)
|
||||||
self.scale_aperture_button.setVisible(False)
|
self.scale_aperture_button.setVisible(False)
|
||||||
|
|
||||||
|
self.buffer_aperture_label.setVisible(False)
|
||||||
|
self.buffer_aperture_entry.setVisible(False)
|
||||||
|
self.buffer_aperture_button.setVisible(False)
|
||||||
|
|
||||||
# Isolation Routing
|
# Isolation Routing
|
||||||
self.isolation_routing_label = QtWidgets.QLabel("<b>Isolation Routing:</b>")
|
self.isolation_routing_label = QtWidgets.QLabel("<b>Isolation Routing:</b>")
|
||||||
self.isolation_routing_label.setToolTip(
|
self.isolation_routing_label.setToolTip(
|
||||||
@@ -1362,7 +1412,7 @@ class CNCObjectUI(ObjectUI):
|
|||||||
)
|
)
|
||||||
self.custom_box.addWidget(self.export_gcode_label)
|
self.custom_box.addWidget(self.export_gcode_label)
|
||||||
|
|
||||||
# Prepend text to Gerber
|
# Prepend text to GCode
|
||||||
prependlabel = QtWidgets.QLabel('Prepend to CNC Code:')
|
prependlabel = QtWidgets.QLabel('Prepend to CNC Code:')
|
||||||
prependlabel.setToolTip(
|
prependlabel.setToolTip(
|
||||||
"Type here any G-Code commands you would\n"
|
"Type here any G-Code commands you would\n"
|
||||||
@@ -1373,7 +1423,7 @@ class CNCObjectUI(ObjectUI):
|
|||||||
self.prepend_text = FCTextArea()
|
self.prepend_text = FCTextArea()
|
||||||
self.custom_box.addWidget(self.prepend_text)
|
self.custom_box.addWidget(self.prepend_text)
|
||||||
|
|
||||||
# Append text to Gerber
|
# Append text to GCode
|
||||||
appendlabel = QtWidgets.QLabel('Append to CNC Code')
|
appendlabel = QtWidgets.QLabel('Append to CNC Code')
|
||||||
appendlabel.setToolTip(
|
appendlabel.setToolTip(
|
||||||
"Type here any G-Code commands you would\n"
|
"Type here any G-Code commands you would\n"
|
||||||
@@ -1385,6 +1435,70 @@ class CNCObjectUI(ObjectUI):
|
|||||||
self.append_text = FCTextArea()
|
self.append_text = FCTextArea()
|
||||||
self.custom_box.addWidget(self.append_text)
|
self.custom_box.addWidget(self.append_text)
|
||||||
|
|
||||||
|
self.cnc_frame = QtWidgets.QFrame()
|
||||||
|
self.cnc_frame.setContentsMargins(0, 0, 0, 0)
|
||||||
|
self.custom_box.addWidget(self.cnc_frame)
|
||||||
|
self.cnc_box = QtWidgets.QVBoxLayout()
|
||||||
|
self.cnc_box.setContentsMargins(0, 0, 0, 0)
|
||||||
|
self.cnc_frame.setLayout(self.cnc_box)
|
||||||
|
|
||||||
|
# Prepend to G-Code
|
||||||
|
toolchangelabel = QtWidgets.QLabel('Toolchange G-Code:')
|
||||||
|
toolchangelabel.setToolTip(
|
||||||
|
"Type here any G-Code commands you would\n"
|
||||||
|
"like to be executed when Toolchange event is encountered.\n"
|
||||||
|
"This will constitute a Custom Toolchange GCode,\n"
|
||||||
|
"or a Toolchange Macro."
|
||||||
|
)
|
||||||
|
self.cnc_box.addWidget(toolchangelabel)
|
||||||
|
|
||||||
|
self.toolchange_text = FCTextArea()
|
||||||
|
self.cnc_box.addWidget(self.toolchange_text)
|
||||||
|
|
||||||
|
cnclay = QtWidgets.QHBoxLayout()
|
||||||
|
self.cnc_box.addLayout(cnclay)
|
||||||
|
|
||||||
|
# Toolchange Replacement GCode
|
||||||
|
self.toolchange_cb = FCCheckBox(label='Use Toolchange Macro')
|
||||||
|
self.toolchange_cb.setToolTip(
|
||||||
|
"Check this box if you want to use\n"
|
||||||
|
"a Custom Toolchange GCode (macro)."
|
||||||
|
)
|
||||||
|
cnclay.addWidget(self.toolchange_cb)
|
||||||
|
cnclay.addStretch()
|
||||||
|
|
||||||
|
cnclay1 = QtWidgets.QHBoxLayout()
|
||||||
|
self.cnc_box.addLayout(cnclay1)
|
||||||
|
|
||||||
|
# Variable list
|
||||||
|
self.tc_variable_combo = FCComboBox()
|
||||||
|
self.tc_variable_combo.setToolTip(
|
||||||
|
"A list of the FlatCAM variables that can be used\n"
|
||||||
|
"in the Toolchange event.\n"
|
||||||
|
"They have to be surrounded by the '%' symbol"
|
||||||
|
)
|
||||||
|
cnclay1.addWidget(self.tc_variable_combo)
|
||||||
|
|
||||||
|
# Populate the Combo Box
|
||||||
|
variables = ['tool', 'toolC', 't_drills', 'toolchangex', 'toolchangey', 'toolchangez']
|
||||||
|
self.tc_variable_combo.addItems(variables)
|
||||||
|
self.tc_variable_combo.setItemData(0, "tool = tool number", Qt.ToolTipRole)
|
||||||
|
self.tc_variable_combo.setItemData(1, "toolC = tool diameter", Qt.ToolTipRole)
|
||||||
|
self.tc_variable_combo.setItemData(2, "t_drills = for Excellon, total number of drills", Qt.ToolTipRole)
|
||||||
|
self.tc_variable_combo.setItemData(3, "toolchangex = X coord for Toolchange", Qt.ToolTipRole)
|
||||||
|
self.tc_variable_combo.setItemData(4, "toolchangey = Y coord for Toolchange", Qt.ToolTipRole)
|
||||||
|
self.tc_variable_combo.setItemData(5, "toolchangez = Z coord for Toolchange", Qt.ToolTipRole)
|
||||||
|
|
||||||
|
cnclay1.addStretch()
|
||||||
|
|
||||||
|
# Insert Variable into the Toolchange G-Code Text Box
|
||||||
|
self.tc_insert_buton = FCButton("Insert")
|
||||||
|
self.tc_insert_buton.setToolTip(
|
||||||
|
"Insert the variable in the GCode Box\n"
|
||||||
|
"surrounded by the '%' symbol."
|
||||||
|
)
|
||||||
|
cnclay1.addWidget(self.tc_insert_buton)
|
||||||
|
|
||||||
h_lay = QtWidgets.QHBoxLayout()
|
h_lay = QtWidgets.QHBoxLayout()
|
||||||
h_lay.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
|
h_lay.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
|
||||||
self.custom_box.addLayout(h_lay)
|
self.custom_box.addLayout(h_lay)
|
||||||
|
|||||||
@@ -14,6 +14,10 @@ CAD program, and create G-Code for Isolation routing.
|
|||||||
- fixed the Gerber object UI layout
|
- fixed the Gerber object UI layout
|
||||||
- added ability to mark individual apertures in Gerber file using the Gerber Aperture Table
|
- added ability to mark individual apertures in Gerber file using the Gerber Aperture Table
|
||||||
- more modifications for the Gerber UI layout; made 'follow' an advanced Gerber option
|
- more modifications for the Gerber UI layout; made 'follow' an advanced Gerber option
|
||||||
|
- added in Preferences a new Category: Gerber Advanced Options. For now it controls the display of Gerber Aperture Table and the "follow" attribute4
|
||||||
|
- fixed FlatCAMGerber.merge() to merge the self.apertures[ap]['solid_geometry'] too
|
||||||
|
- started to work on a new feature that allow adding a ToolChange GCode macro - GUI added both in CNCJob Selected tab and in CNCJob Preferences
|
||||||
|
- added a limited 'sort-of' Gerber Editor: it allows buffering and scaling of apertures
|
||||||
|
|
||||||
24.02.2019
|
24.02.2019
|
||||||
|
|
||||||
|
|||||||
@@ -105,7 +105,8 @@ G00 X{toolchangex} Y{toolchangey}
|
|||||||
T{tool}
|
T{tool}
|
||||||
M6
|
M6
|
||||||
(MSG, Change to Tool Dia = {toolC} ||| Total drills for tool T{tool} = {t_drills})
|
(MSG, Change to Tool Dia = {toolC} ||| Total drills for tool T{tool} = {t_drills})
|
||||||
M0""".format(toolchangex=self.coordinate_format % (p.coords_decimals, toolchangex),
|
M0
|
||||||
|
""".format(toolchangex=self.coordinate_format % (p.coords_decimals, toolchangex),
|
||||||
toolchangey=self.coordinate_format % (p.coords_decimals, toolchangey),
|
toolchangey=self.coordinate_format % (p.coords_decimals, toolchangey),
|
||||||
toolchangez=self.coordinate_format % (p.coords_decimals, toolchangez),
|
toolchangez=self.coordinate_format % (p.coords_decimals, toolchangez),
|
||||||
tool=int(p.tool),
|
tool=int(p.tool),
|
||||||
|
|||||||
Reference in New Issue
Block a user