- in Cutout Plugin remade the UI and fixed different issues

This commit is contained in:
Marius Stanciu
2021-09-24 21:09:54 +03:00
committed by Marius
parent d3a16df32c
commit 0854101297
7 changed files with 314 additions and 329 deletions

View File

@@ -13,6 +13,7 @@ CHANGELOG for FlatCAM beta
- in Film Plugin added new parameters and improvements: now the negative film can have a box that is convex and it is no longer limited to square shapes. Also, if the box object has only one geometric element (an outline) then that one will be the final shape of the negative
- in Gerber Editor fixed not being able to delete an aperture
- in Gerber Editor fixed the edge case where the user selects apertures in the Tools Table and then uses the Poligonize Tool and not by selecting shapes on canvas
- in Cutout Plugin remade the UI and fixed different issues
21.09.2021

View File

@@ -439,7 +439,7 @@ class PreferencesUIManager:
"tools_cutout_convexshape": self.ui.plugin_pref_form.tools_cutout_group.convex_box,
"tools_cutout_big_cursor": self.ui.plugin_pref_form.tools_cutout_group.big_cursor_cb,
"tools_cutout_gap_type": self.ui.plugin_pref_form.tools_cutout_group.gaptype_radio,
"tools_cutout_gap_type": self.ui.plugin_pref_form.tools_cutout_group.gaptype_combo,
"tools_cutout_gap_depth": self.ui.plugin_pref_form.tools_cutout_group.thin_depth_entry,
"tools_cutout_mb_dia": self.ui.plugin_pref_form.tools_cutout_group.mb_dia_entry,
"tools_cutout_mb_spacing": self.ui.plugin_pref_form.tools_cutout_group.mb_spacing_entry,

View File

@@ -1,7 +1,7 @@
from PyQt6 import QtWidgets
from appGUI.GUIElements import FCDoubleSpinner, FCCheckBox, RadioSet, FCComboBox, FCLabel, OptionalInputSection, \
FCGridLayout
FCGridLayout, FCFrame, FCComboBox2
from appGUI.preferences.OptionsGroupUI import OptionsGroupUI
import gettext
@@ -23,7 +23,7 @@ class ToolsCutoutPrefGroupUI(OptionsGroupUI):
self.defaults = defaults
# ## Board cutout
self.board_cutout_label = FCLabel("<b>%s:</b>" % _("Parameters"))
self.board_cutout_label = FCLabel('<span style="color:blue;"><b>%s</b></span>' % _("Parameters"))
self.board_cutout_label.setToolTip(
_("Create toolpaths to cut around\n"
"the PCB and separate it from\n"
@@ -31,10 +31,17 @@ class ToolsCutoutPrefGroupUI(OptionsGroupUI):
)
self.layout.addWidget(self.board_cutout_label)
grid0 = FCGridLayout(v_spacing=5, h_spacing=3)
self.layout.addLayout(grid0)
# #############################################################################################################
# Tool Params Frame
# #############################################################################################################
tool_par_frame = FCFrame()
self.layout.addWidget(tool_par_frame)
tdclabel = FCLabel('%s:' % _('Tool Diameter'))
param_grid = FCGridLayout(v_spacing=5, h_spacing=3)
tool_par_frame.setLayout(param_grid)
# Tool Diameter
tdclabel = FCLabel('%s:' % _('Tool Dia'))
tdclabel.setToolTip(
_("Diameter of the tool used to cutout\n"
"the PCB shape out of the surrounding material.")
@@ -45,8 +52,16 @@ class ToolsCutoutPrefGroupUI(OptionsGroupUI):
self.cutout_tooldia_entry.set_precision(self.decimals)
self.cutout_tooldia_entry.setSingleStep(0.1)
grid0.addWidget(tdclabel, 0, 0)
grid0.addWidget(self.cutout_tooldia_entry, 0, 1)
param_grid.addWidget(tdclabel, 0, 0)
param_grid.addWidget(self.cutout_tooldia_entry, 0, 1)
# Convex box shape
self.convex_box = FCCheckBox('%s' % _("Convex Shape"))
self.convex_box.setToolTip(
_("Create a convex shape surrounding the entire PCB.\n"
"Used only if the source object type is Gerber.")
)
param_grid.addWidget(self.convex_box, 2, 0, 1, 2)
# Cut Z
cutzlabel = FCLabel('%s:' % _('Cut Z'))
@@ -62,8 +77,8 @@ class ToolsCutoutPrefGroupUI(OptionsGroupUI):
self.cutz_entry.setSingleStep(0.1)
grid0.addWidget(cutzlabel, 1, 0)
grid0.addWidget(self.cutz_entry, 1, 1)
param_grid.addWidget(cutzlabel, 4, 0)
param_grid.addWidget(self.cutz_entry, 4, 1)
# Multi-pass
self.mpass_cb = FCCheckBox('%s:' % _("Multi-Depth"))
@@ -83,8 +98,8 @@ class ToolsCutoutPrefGroupUI(OptionsGroupUI):
self.maxdepth_entry.setToolTip(_("Depth of each pass (positive)."))
grid0.addWidget(self.mpass_cb, 2, 0)
grid0.addWidget(self.maxdepth_entry, 2, 1)
param_grid.addWidget(self.mpass_cb, 6, 0)
param_grid.addWidget(self.maxdepth_entry, 6, 1)
self.ois_md = OptionalInputSection(self.mpass_cb, [self.maxdepth_entry])
@@ -101,8 +116,8 @@ class ToolsCutoutPrefGroupUI(OptionsGroupUI):
{"label": _("Single"), "value": "single"},
{"label": _("Panel"), "value": "panel"},
])
grid0.addWidget(kindlabel, 3, 0)
grid0.addWidget(self.obj_kind_combo, 3, 1)
param_grid.addWidget(kindlabel, 8, 0)
param_grid.addWidget(self.obj_kind_combo, 8, 1)
marginlabel = FCLabel('%s:' % _('Margin'))
marginlabel.setToolTip(
@@ -116,11 +131,23 @@ class ToolsCutoutPrefGroupUI(OptionsGroupUI):
self.cutout_margin_entry.set_precision(self.decimals)
self.cutout_margin_entry.setSingleStep(0.1)
grid0.addWidget(marginlabel, 4, 0)
grid0.addWidget(self.cutout_margin_entry, 4, 1)
param_grid.addWidget(marginlabel, 10, 0)
param_grid.addWidget(self.cutout_margin_entry, 10, 1)
self.gaps_label = FCLabel('<span style="color:green;"><b>%s</b></span>' % _("Gaps"))
self.layout.addWidget(self.gaps_label)
# #############################################################################################################
# Gaps Frame
# #############################################################################################################
gaps_frame = FCFrame()
self.layout.addWidget(gaps_frame)
# Grid Layout
gaps_grid = FCGridLayout(v_spacing=5, h_spacing=3)
gaps_frame.setLayout(gaps_grid)
# Gap Size
gaplabel = FCLabel('%s:' % _('Gap size'))
gaplabel = FCLabel('%s:' % _('Size'))
gaplabel.setToolTip(
_("The size of the bridge gaps in the cutout\n"
"used to keep the board connected to\n"
@@ -133,11 +160,11 @@ class ToolsCutoutPrefGroupUI(OptionsGroupUI):
self.cutout_gap_entry.set_precision(self.decimals)
self.cutout_gap_entry.setSingleStep(0.1)
grid0.addWidget(gaplabel, 5, 0)
grid0.addWidget(self.cutout_gap_entry, 5, 1)
gaps_grid.addWidget(gaplabel, 0, 0)
gaps_grid.addWidget(self.cutout_gap_entry, 0, 1)
# Gap Type
self.gaptype_label = FCLabel('%s:' % _("Gap type"))
self.gaptype_label = FCLabel('%s:' % _("Type"))
self.gaptype_label.setToolTip(
_("The type of gap:\n"
"- Bridge -> the cutout will be interrupted by bridges\n"
@@ -145,17 +172,16 @@ class ToolsCutoutPrefGroupUI(OptionsGroupUI):
"- M-Bites -> 'Mouse Bites' - same as 'bridge' but covered with drill holes")
)
self.gaptype_radio = RadioSet(
[
{'label': _('Bridge'), 'value': 'b'},
{'label': _('Thin'), 'value': 'bt'},
{'label': "M-Bites", 'value': 'mb'}
],
stretch=True
)
self.gaptype_combo = FCComboBox2()
self.gaptype_combo.addItems([_('Bridge'), _('Thin'), _("Mouse Bytes")])
grid0.addWidget(self.gaptype_label, 7, 0)
grid0.addWidget(self.gaptype_radio, 7, 1)
gaps_grid.addWidget(self.gaptype_label, 2, 0)
gaps_grid.addWidget(self.gaptype_combo, 2, 1)
separator_line = QtWidgets.QFrame()
separator_line.setFrameShape(QtWidgets.QFrame.Shape.HLine)
separator_line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken)
gaps_grid.addWidget(separator_line, 4, 0, 1, 2)
# Thin gaps Depth
self.thin_depth_label = FCLabel('%s:' % _("Depth"))
@@ -168,8 +194,13 @@ class ToolsCutoutPrefGroupUI(OptionsGroupUI):
self.thin_depth_entry.setRange(-10000.0000, 10000.0000)
self.thin_depth_entry.setSingleStep(0.1)
grid0.addWidget(self.thin_depth_label, 9, 0)
grid0.addWidget(self.thin_depth_entry, 9, 1)
gaps_grid.addWidget(self.thin_depth_label, 6, 0)
gaps_grid.addWidget(self.thin_depth_entry, 6, 1)
separator_line = QtWidgets.QFrame()
separator_line.setFrameShape(QtWidgets.QFrame.Shape.HLine)
separator_line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken)
gaps_grid.addWidget(separator_line, 8, 0, 1, 2)
# Mouse Bites Tool Diameter
self.mb_dia_label = FCLabel('%s:' % _("Tool Diameter"))
@@ -180,8 +211,8 @@ class ToolsCutoutPrefGroupUI(OptionsGroupUI):
self.mb_dia_entry.set_precision(self.decimals)
self.mb_dia_entry.setRange(0, 100.0000)
grid0.addWidget(self.mb_dia_label, 11, 0)
grid0.addWidget(self.mb_dia_entry, 11, 1)
gaps_grid.addWidget(self.mb_dia_label, 10, 0)
gaps_grid.addWidget(self.mb_dia_entry, 10, 1)
# Mouse Bites Holes Spacing
self.mb_spacing_label = FCLabel('%s:' % _("Spacing"))
@@ -192,9 +223,14 @@ class ToolsCutoutPrefGroupUI(OptionsGroupUI):
self.mb_spacing_entry.set_precision(self.decimals)
self.mb_spacing_entry.setRange(0, 100.0000)
grid0.addWidget(self.mb_spacing_label, 13, 0)
grid0.addWidget(self.mb_spacing_entry, 13, 1)
gaps_grid.addWidget(self.mb_spacing_label, 12, 0)
gaps_grid.addWidget(self.mb_spacing_entry, 12, 1)
separator_line = QtWidgets.QFrame()
separator_line.setFrameShape(QtWidgets.QFrame.Shape.HLine)
separator_line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken)
gaps_grid.addWidget(separator_line, 14, 0, 1, 2)
gaps_label = FCLabel('%s:' % _('Gaps'))
gaps_label.setToolTip(
_("Number of gaps used for the cutout.\n"
@@ -210,28 +246,34 @@ class ToolsCutoutPrefGroupUI(OptionsGroupUI):
)
self.gaps_combo = FCComboBox()
grid0.addWidget(gaps_label, 15, 0)
grid0.addWidget(self.gaps_combo, 15, 1)
gaps_grid.addWidget(gaps_label, 16, 0)
gaps_grid.addWidget(self.gaps_combo, 16, 1)
gaps_items = ['None', 'LR', 'TB', '4', '2LR', '2TB', '8']
for it in gaps_items:
self.gaps_combo.addItem(it)
# self.gaps_combo.setStyleSheet('background-color: rgb(255,255,255)')
# Surrounding convex box shape
self.convex_box = FCCheckBox('%s' % _("Convex Shape"))
self.convex_box.setToolTip(
_("Create a convex shape surrounding the entire PCB.\n"
"Used only if the source object type is Gerber.")
)
grid0.addWidget(self.convex_box, 17, 0, 1, 2)
self.big_cursor_cb = FCCheckBox('%s' % _("Big cursor"))
self.big_cursor_cb.setToolTip(
_("Use a big cursor when adding manual gaps."))
grid0.addWidget(self.big_cursor_cb, 19, 0, 1, 2)
gaps_grid.addWidget(self.big_cursor_cb, 18, 0, 1, 2)
# Cut by Drilling Title
self.title_drillcut_label = FCLabel('<span style="color:red;"><b>%s</b></span>' % _('Cut by Drilling'))
self.title_drillcut_label.setToolTip(_("Create a series of drill holes following a geometry line."))
self.layout.addWidget(self.title_drillcut_label)
# #############################################################################################################
# Cut by Drilling Frame
# #############################################################################################################
self.drill_cut_frame = FCFrame()
self.layout.addWidget(self.drill_cut_frame)
# Grid Layout
drill_cut_grid = FCGridLayout(v_spacing=5, h_spacing=3)
self.drill_cut_frame.setLayout(drill_cut_grid)
# Drill Cut
# Drill Tool Diameter
self.drill_dia_entry = FCDoubleSpinner()
self.drill_dia_entry.set_precision(self.decimals)
@@ -242,8 +284,8 @@ class ToolsCutoutPrefGroupUI(OptionsGroupUI):
_("Diameter of the tool used to cutout\n"
"the PCB by drilling.")
)
grid0.addWidget(self.drill_dia_label, 21, 0)
grid0.addWidget(self.drill_dia_entry, 21, 1)
drill_cut_grid.addWidget(self.drill_dia_label, 0, 0)
drill_cut_grid.addWidget(self.drill_dia_entry, 0, 1)
# Drill Tool Pitch
self.drill_pitch_entry = FCDoubleSpinner()
@@ -255,8 +297,8 @@ class ToolsCutoutPrefGroupUI(OptionsGroupUI):
_("Distance between the center of\n"
"two neighboring drill holes.")
)
grid0.addWidget(self.drill_pitch_label, 23, 0)
grid0.addWidget(self.drill_pitch_entry, 23, 1)
drill_cut_grid.addWidget(self.drill_pitch_label, 2, 0)
drill_cut_grid.addWidget(self.drill_pitch_entry, 2, 1)
# Drill Tool Margin
self.drill_margin_entry = FCDoubleSpinner()
@@ -269,7 +311,10 @@ class ToolsCutoutPrefGroupUI(OptionsGroupUI):
"will make the cutout of the PCB further from\n"
"the actual PCB border")
)
grid0.addWidget(self.drill_margin_label, 25, 0)
grid0.addWidget(self.drill_margin_entry, 25, 1)
drill_cut_grid.addWidget(self.drill_margin_label, 4, 0)
drill_cut_grid.addWidget(self.drill_margin_entry, 4, 1)
self.layout.addStretch()
FCGridLayout.set_common_column_size([param_grid, drill_cut_grid, gaps_grid], 0)
# self.layout.addStretch()

View File

@@ -35,8 +35,8 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI):
adj_frame = FCFrame()
self.layout.addWidget(adj_frame)
grid0 = FCGridLayout(v_spacing=5, h_spacing=3)
adj_frame.setLayout(grid0)
adj_grid = FCGridLayout(v_spacing=5, h_spacing=3)
adj_frame.setLayout(adj_grid)
# Scale Geometry
self.film_scale_cb = FCCheckBox('%s' % _("Scale"))
@@ -49,11 +49,11 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI):
QCheckBox {font-weight: bold; color: black}
"""
)
grid0.addWidget(self.film_scale_cb, 2, 0, 1, 2)
adj_grid.addWidget(self.film_scale_cb, 2, 0, 1, 2)
# SCALE FRAME
scale_frame = FCFrame()
grid0.addWidget(scale_frame, 4, 0, 1, 2)
adj_grid.addWidget(scale_frame, 4, 0, 1, 2)
grid_scale = FCGridLayout(v_spacing=5, h_spacing=3)
scale_frame.setLayout(grid_scale)
@@ -102,11 +102,11 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI):
QCheckBox {font-weight: bold; color: black}
"""
)
grid0.addWidget(self.film_skew_cb, 6, 0, 1, 2)
adj_grid.addWidget(self.film_skew_cb, 6, 0, 1, 2)
# SKEW FRAME
skew_frame = FCFrame()
grid0.addWidget(skew_frame, 8, 0, 1, 2)
adj_grid.addWidget(skew_frame, 8, 0, 1, 2)
grid_skew = FCGridLayout(v_spacing=5, h_spacing=3)
skew_frame.setLayout(grid_skew)
@@ -152,7 +152,7 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI):
QCheckBox {font-weight: bold; color: black}
"""
)
grid0.addWidget(self.film_mirror_cb, 10, 0, 1, 2)
adj_grid.addWidget(self.film_mirror_cb, 10, 0, 1, 2)
self.film_mirror_axis = RadioSet([{'label': _('X'), 'value': 'x'},
{'label': _('Y'), 'value': 'y'},
@@ -160,8 +160,8 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI):
stretch=False)
self.film_mirror_axis_label = FCLabel('%s:' % _("Mirror Axis"))
grid0.addWidget(self.film_mirror_axis_label, 12, 0)
grid0.addWidget(self.film_mirror_axis, 12, 1)
adj_grid.addWidget(self.film_mirror_axis_label, 12, 0)
adj_grid.addWidget(self.film_mirror_axis, 12, 1)
# separator_line3 = QtWidgets.QFrame()
# separator_line3.setFrameShape(QtWidgets.QFrame.Shape.HLine)
@@ -367,7 +367,9 @@ class ToolsFilmPrefGroupUI(OptionsGroupUI):
grid_par.addWidget(self.png_dpi_label, 18, 0)
grid_par.addWidget(self.png_dpi_spinner, 18, 1)
self.layout.addStretch(1)
# self.layout.addStretch(1)
FCGridLayout.set_common_column_size([adj_grid, grid_par, grid_skew, grid_scale], 0)
# Film Tool
self.film_color_entry.editingFinished.connect(self.on_film_color_entry)

View File

@@ -1365,9 +1365,12 @@ class GeometryObject(FlatCAMObj, Geometry):
visible = visible if visible else self.options['plot']
try:
for sub_el in element:
self.plot_element(sub_el, color=color)
if isinstance(element, (MultiPolygon, MultiLineString)):
for sub_el in element.geoms:
self.plot_element(sub_el, color=color)
else:
for sub_el in element:
self.plot_element(sub_el, color=color)
except TypeError: # Element is not iterable...
# if self.app.is_legacy is False:
self.add_shape(shape=element, color=color, visible=visible, layer=0)

View File

@@ -8,7 +8,7 @@
from PyQt6 import QtWidgets, QtGui, QtCore
from appTool import AppTool
from appGUI.GUIElements import FCDoubleSpinner, FCCheckBox, RadioSet, FCComboBox, OptionalInputSection, FCButton, \
FCLabel, VerticalScrollArea, FCGridLayout, FCFrame
FCLabel, VerticalScrollArea, FCGridLayout, FCFrame, FCComboBox2
from shapely.geometry import box, MultiPolygon, Polygon, LineString, LinearRing, MultiLineString, Point
from shapely.ops import unary_union, linemerge
@@ -244,8 +244,6 @@ class CutOut(AppTool):
else:
self.on_type_obj_changed(val='geo')
self.ui.dia.set_value(float(self.app.defaults["tools_cutout_tooldia"]))
# init the working variables
self.default_data.clear()
kind = 'geometry'
@@ -257,62 +255,19 @@ class CutOut(AppTool):
if option.find('tools_') == 0:
self.default_data[option] = self.app.options[option]
# self.default_data.update({
# "plot": True,
#
# "cutz": float(self.app.defaults["geometry_cutz"]),
# "multidepth": self.app.defaults["geometry_multidepth"],
# "depthperpass": float(self.app.defaults["geometry_depthperpass"]),
#
# "vtipdia": float(self.app.defaults["tools_mill_vtipdia"]),
# "vtipangle": float(self.app.defaults["tools_mill_vtipangle"]),
# "travelz": float(self.app.defaults["geometry_travelz"]),
# "feedrate": float(self.app.defaults["geometry_feedrate"]),
# "feedrate_z": float(self.app.defaults["geometry_feedrate_z"]),
# "feedrate_rapid": float(self.app.defaults["geometry_feedrate_rapid"]),
# "spindlespeed": self.app.defaults["geometry_spindlespeed"],
# "dwell": self.app.defaults["geometry_dwell"],
# "dwelltime": float(self.app.defaults["geometry_dwelltime"]),
# "spindledir": self.app.defaults["geometry_spindledir"],
# "ppname_g": self.app.defaults["geometry_ppname_g"],
# "extracut": self.app.defaults["geometry_extracut"],
# "extracut_length": float(self.app.defaults["geometry_extracut_length"]),
# "toolchange": self.app.defaults["geometry_toolchange"],
# "toolchangexy": self.app.defaults["geometry_toolchangexy"],
# "toolchangez": float(self.app.defaults["geometry_toolchangez"]),
# "startz": self.app.defaults["geometry_startz"],
# "endz": float(self.app.defaults["geometry_endz"]),
# "endxy": self.app.defaults["geometry_endxy"],
# "area_exclusion": self.app.defaults["geometry_area_exclusion"],
# "area_shape": self.app.defaults["geometry_area_shape"],
# "area_strategy": self.app.defaults["geometry_area_strategy"],
# "area_overz": float(self.app.defaults["geometry_area_overz"]),
# "optimization_type": self.app.defaults["geometry_optimization_type"],
#
# # Cutout
# "tools_cutout_tooldia": self.app.defaults["tools_cutout_tooldia"],
# "tools_cutout_kind": self.app.defaults["tools_cutout_kind"],
# "tools_cutout_margin": float(self.app.defaults["tools_cutout_margin"]),
# "tools_cutout_z": float(self.app.defaults["tools_cutout_z"]),
# "tools_cutout_depthperpass": float(self.app.defaults["tools_cutout_depthperpass"]),
# "tools_cutout_mdepth": self.app.defaults["tools_cutout_mdepth"],
# "tools_cutout_gapsize": float(self.app.defaults["tools_cutout_gapsize"]),
# "tools_cutout_gaps_ff": self.app.defaults["tools_cutout_gaps_ff"],
# "tools_cutout_convexshape": self.app.defaults["tools_cutout_convexshape"],
#
# "tools_cutout_big_cursor": self.app.defaults["tools_cutout_big_cursor"],
# "tools_cutout_gap_type": self.app.defaults["tools_cutout_gap_type"],
# "tools_cutout_gap_depth": float(self.app.defaults["tools_cutout_gap_depth"]),
# "tools_cutout_mb_dia": float(self.app.defaults["tools_cutout_mb_dia"]),
# "tools_cutout_mb_spacing": float(self.app.defaults["tools_cutout_mb_spacing"]),
#
# })
self.ui.gaptype_combo.set_value(self.app.defaults["tools_cutout_gap_type"])
self.ui.on_gap_type_radio(self.ui.gaptype_combo.get_value())
# add a default tool
self.ui.dia.set_value(float(self.app.defaults["tools_cutout_tooldia"]))
tool_dia = float(self.app.defaults["tools_cutout_tooldia"])
self.on_tool_add(custom_dia=tool_dia)
# set as default the automatic adding of gaps
self.ui.cutout_type_radio.set_value('a')
self.on_cutout_type(val='a')
# set the Cut By Drilling parameters
self.ui.drill_dia_entry.set_value(float(self.app.defaults["tools_cutout_drill_dia"]))
self.ui.drill_pitch_entry.set_value(float(self.app.defaults["tools_cutout_drill_pitch"]))
self.ui.drill_margin_entry.set_value(float(self.app.defaults["tools_cutout_drill_margin"]))
@@ -358,14 +313,16 @@ class CutOut(AppTool):
tool_data = self.cut_tool_dict['data']
tool_data['tools_cutout_convexshape'] = False
tool_data['tools_cutout_gap_type'] = "b"
tool_data['tools_cutout_gap_type'] = 0 # "Basic Type of Gap"
self.ui.gaptype_label.hide()
self.ui.gaptype_radio.hide()
self.ui.gaptype_combo.hide()
self.ui.cutout_type_label.hide()
self.ui.cutout_type_radio.hide()
self.ui.cutout_type_radio.set_value('a')
self.ui.separator_line.hide()
self.ui.drill_cut_frame.hide()
self.ui.title_drillcut_label.hide()
self.ui.drillcut_btn.hide()
@@ -396,15 +353,21 @@ class CutOut(AppTool):
tool_data['tools_cutout_gap_type'] = app_defaults['tools_cutout_gap_type']
self.ui.gaptype_label.show()
self.ui.gaptype_radio.show()
self.ui.gaptype_combo.show()
self.ui.cutout_type_label.show()
self.ui.cutout_type_radio.show()
self.ui.cutout_type_radio.set_value('a')
self.ui.separator_line.show()
self.ui.drill_cut_frame.show()
self.ui.title_drillcut_label.show()
self.ui.drillcut_btn.show()
if self.cut_tool_dict:
tool_data = self.cut_tool_dict['data']
self.ui.on_gap_type_radio(tool_data['tools_cutout_gap_type'])
def update_ui(self, tool_dict):
self.ui.obj_kind_combo.set_value(self.default_data["tools_cutout_kind"])
self.ui.big_cursor_cb.set_value(self.default_data['tools_cutout_big_cursor'])
@@ -412,7 +375,9 @@ class CutOut(AppTool):
# Entries that may be updated from database
self.ui.margin.set_value(float(tool_dict["tools_cutout_margin"]))
self.ui.gapsize.set_value(float(tool_dict["tools_cutout_gapsize"]))
self.ui.gaptype_radio.set_value(tool_dict["tools_cutout_gap_type"])
self.ui.gaptype_combo.set_value(tool_dict["tools_cutout_gap_type"])
self.on_cutout_type(self.ui.gaptype_combo.get_value())
self.ui.thin_depth_entry.set_value(float(tool_dict["tools_cutout_gap_depth"]))
self.ui.mb_dia_entry.set_value(float(tool_dict["tools_cutout_mb_dia"]))
self.ui.mb_spacing_entry.set_value(float(tool_dict["tools_cutout_mb_spacing"]))
@@ -430,24 +395,18 @@ class CutOut(AppTool):
self.ui.ff_cutout_object_btn.show()
self.ui.rect_cutout_object_btn.show()
self.ui.big_cursor_label.hide()
self.ui.big_cursor_cb.hide()
self.ui.man_geo_creation_btn.hide()
self.ui.man_object_combo.hide()
self.ui.man_object_label.hide()
self.ui.man_gaps_creation_btn.hide()
self.ui.man_frame.hide()
else:
self.ui.gaps_label.hide()
self.ui.gaps.hide()
self.ui.ff_cutout_object_btn.hide()
self.ui.rect_cutout_object_btn.hide()
self.ui.big_cursor_label.show()
self.ui.big_cursor_cb.show()
self.ui.man_geo_creation_btn.show()
self.ui.man_object_combo.show()
self.ui.man_object_label.show()
self.ui.man_gaps_creation_btn.show()
self.ui.man_frame.show()
def on_tool_add(self, custom_dia=None):
self.blockSignals(True)
@@ -543,16 +502,15 @@ class CutOut(AppTool):
self.blockSignals(False)
return
# FIXME when the Geometry UI milling functionality will be transferred in the Milling Tool this needs changes
new_tools_dict["tools_cutout_z"] = deepcopy(new_tools_dict["cutz"])
new_tools_dict["tools_cutout_mdepth"] = deepcopy(new_tools_dict["multidepth"])
new_tools_dict["tools_cutout_depthperpass"] = deepcopy(new_tools_dict["depthperpass"])
new_tools_dict["tools_cutout_z"] = deepcopy(new_tools_dict["tools_mill_cutz"])
new_tools_dict["tools_cutout_mdepth"] = deepcopy(new_tools_dict["tools_mill_multidepth"])
new_tools_dict["tools_cutout_depthperpass"] = deepcopy(new_tools_dict["tools_mill_depthperpass"])
new_tdia = deepcopy(updated_tooldia) if updated_tooldia is not None else deepcopy(truncated_tooldia)
self.cut_tool_dict.update({
'tooldia': new_tdia,
'data': deepcopy(new_tools_dict),
'solid_geometry': []
'tooldia': new_tdia,
'data': deepcopy(new_tools_dict),
'solid_geometry': []
})
self.update_ui(new_tools_dict)
@@ -574,61 +532,11 @@ class CutOut(AppTool):
if option.find('tools_') == 0:
self.default_data[option] = self.app.options[option]
# self.default_data.update({
# "plot": True,
#
# "cutz": float(self.app.defaults["geometry_cutz"]),
# "multidepth": self.app.defaults["geometry_multidepth"],
# "depthperpass": float(self.app.defaults["geometry_depthperpass"]),
#
# "vtipdia": float(self.app.defaults["tools_mill_vtipdia"]),
# "vtipangle": float(self.app.defaults["tools_mill_vtipangle"]),
# "travelz": float(self.app.defaults["geometry_travelz"]),
# "feedrate": float(self.app.defaults["geometry_feedrate"]),
# "feedrate_z": float(self.app.defaults["geometry_feedrate_z"]),
# "feedrate_rapid": float(self.app.defaults["geometry_feedrate_rapid"]),
# "spindlespeed": self.app.defaults["geometry_spindlespeed"],
# "dwell": self.app.defaults["geometry_dwell"],
# "dwelltime": float(self.app.defaults["geometry_dwelltime"]),
# "spindledir": self.app.defaults["geometry_spindledir"],
# "ppname_g": self.app.defaults["geometry_ppname_g"],
# "extracut": self.app.defaults["geometry_extracut"],
# "extracut_length": float(self.app.defaults["geometry_extracut_length"]),
# "toolchange": self.app.defaults["geometry_toolchange"],
# "toolchangexy": self.app.defaults["geometry_toolchangexy"],
# "toolchangez": float(self.app.defaults["geometry_toolchangez"]),
# "startz": self.app.defaults["geometry_startz"],
# "endz": float(self.app.defaults["geometry_endz"]),
# "endxy": self.app.defaults["geometry_endxy"],
# "area_exclusion": self.app.defaults["geometry_area_exclusion"],
# "area_shape": self.app.defaults["geometry_area_shape"],
# "area_strategy": self.app.defaults["geometry_area_strategy"],
# "area_overz": float(self.app.defaults["geometry_area_overz"]),
# "optimization_type": self.app.defaults["geometry_optimization_type"],
#
# # Cutout
# "tools_cutout_tooldia": self.app.defaults["tools_cutout_tooldia"],
# "tools_cutout_kind": self.app.defaults["tools_cutout_kind"],
# "tools_cutout_margin": float(self.app.defaults["tools_cutout_margin"]),
# "tools_cutout_z": float(self.app.defaults["tools_cutout_z"]),
# "tools_cutout_depthperpass": float(self.app.defaults["tools_cutout_depthperpass"]),
# "tools_cutout_mdepth": self.app.defaults["tools_cutout_mdepth"],
# "tools_cutout_gapsize": float(self.app.defaults["tools_cutout_gapsize"]),
# "tools_cutout_gaps_ff": self.app.defaults["tools_cutout_gaps_ff"],
# "tools_cutout_convexshape": self.app.defaults["tools_cutout_convexshape"],
#
# "tools_cutout_big_cursor": self.app.defaults["tools_cutout_big_cursor"],
# "tools_cutout_gap_type": self.app.defaults["tools_cutout_gap_type"],
# "tools_cutout_gap_depth": float(self.app.defaults["tools_cutout_gap_depth"]),
# "tools_cutout_mb_dia": float(self.app.defaults["tools_cutout_mb_dia"]),
# "tools_cutout_mb_spacing": float(self.app.defaults["tools_cutout_mb_spacing"]),
#
# })
self.cut_tool_dict.update({
'tooldia': dia,
'data': deepcopy(self.default_data),
'solid_geometry': []
'tooldia': dia,
'data': deepcopy(self.default_data),
'solid_geometry': []
})
self.update_ui(self.default_data)
@@ -653,7 +561,6 @@ class CutOut(AppTool):
tool_from_db = deepcopy(self.default_data)
tool_from_db.update(tool)
# FIXME when the Geometry UI milling functionality will be transferred in the Milling Tool this needs changes
tool_from_db['data']["tools_cutout_tooldia"] = deepcopy(tool["tooldia"])
tool_from_db['data']["tools_cutout_z"] = deepcopy(tool_from_db['data']["tools_mill_cutz"])
tool_from_db['data']["tools_cutout_mdepth"] = deepcopy(tool_from_db['data']["tools_mill_multidepth"])
@@ -685,9 +592,9 @@ class CutOut(AppTool):
truncated_tooldia = self.app.dec_format(tooldia, self.decimals)
self.cutout_tools.update({
1: {
'tooldia': truncated_tooldia,
'data': deepcopy(tool['data']),
'solid_geometry': []
'tooldia': truncated_tooldia,
'data': deepcopy(tool['data']),
'solid_geometry': []
}
})
self.cutout_tools[1]['data']['name'] = '_cutout'
@@ -870,7 +777,7 @@ class CutOut(AppTool):
outname = "%s_cutout" % formatted_name
self.app.collection.promise(outname)
has_mouse_bites = True if self.ui.gaptype_radio.get_value() == 'mb' else False
has_mouse_bites = True if self.ui.gaptype_combo.get_value() == 2 else False # "mouse bytes"
outname_exc = "%s_mouse_bites" % formatted_name
if has_mouse_bites is True:
@@ -887,7 +794,7 @@ class CutOut(AppTool):
mb_dia = self.ui.mb_dia_entry.get_value()
mb_buff_val = mb_dia / 2.0
mb_spacing = self.ui.mb_spacing_entry.get_value()
gap_type = self.ui.gaptype_radio.get_value()
gap_type = self.ui.gaptype_combo.get_value()
thin_entry = self.ui.thin_depth_entry.get_value()
if cutout_obj.kind == 'gerber':
@@ -935,7 +842,7 @@ class CutOut(AppTool):
return 'fail'
solid_geo, rest_geo = cutout_handler(geom=geo, gapsize=gapsize)
if gap_type == 'bt' and thin_entry != 0:
if gap_type == 1 and thin_entry != 0: # "Thin gaps"
gaps_solid_geo = rest_geo
else:
object_geo = flatten_shapely_geometry(object_geo)
@@ -949,7 +856,7 @@ class CutOut(AppTool):
c_geo, r_geo = cutout_handler(geom=geom_struct, gapsize=gapsize)
solid_geo += c_geo
if gap_type == 'bt' and thin_entry != 0:
if gap_type == 1 and thin_entry != 0: # "Thin gaps"
gaps_solid_geo += r_geo
if not solid_geo:
@@ -962,6 +869,7 @@ class CutOut(AppTool):
# there ar enot lines but polygons
pass
# If it has mouse bytes
if has_mouse_bites is True:
gapsize -= dia / 2
mb_object_geo = deepcopy(object_geo)
@@ -1074,7 +982,7 @@ class CutOut(AppTool):
exc_obj.options['ymax'] = ymax
try:
if self.ui.gaptype_radio.get_value() == 'mb':
if self.ui.gaptype_combo.get_value() == 2: # "mouse bytes"
ret = app_obj.app_obj.new_object('excellon', outname_exc, excellon_init, autoselected=False)
if ret == 'fail':
app_obj.inform.emit('[ERROR_NOTCL] %s' % _("Mouse bites failed."))
@@ -1215,7 +1123,7 @@ class CutOut(AppTool):
outname = "%s_cutout" % formatted_name
self.app.collection.promise(outname)
has_mouse_bites = True if self.ui.gaptype_radio.get_value() == 'mb' else False
has_mouse_bites = True if self.ui.gaptype_combo.get_value() == 2 else False # "mouse bytes"
outname_exc = cutout_obj.options["name"] + "_mouse_bites"
if has_mouse_bites is True:
@@ -1231,7 +1139,7 @@ class CutOut(AppTool):
mb_dia = self.ui.mb_dia_entry.get_value()
mb_buff_val = mb_dia / 2.0
mb_spacing = self.ui.mb_spacing_entry.get_value()
gap_type = self.ui.gaptype_radio.get_value()
gap_type = self.ui.gaptype_combo.get_value()
thin_entry = self.ui.thin_depth_entry.get_value()
if cutout_obj.multigeo is False:
@@ -1258,7 +1166,7 @@ class CutOut(AppTool):
solid_geo = cutout_rect_handler(geo, gapsize, xmin, ymin, xmax, ymax)
if gap_type == 'bt' and thin_entry != 0:
if gap_type == 1 and thin_entry != 0: # "Thin gaps"
gaps_solid_geo = self.subtract_geo(geo, deepcopy(solid_geo))
else:
if cutout_obj.kind == 'geometry':
@@ -1270,7 +1178,7 @@ class CutOut(AppTool):
c_geo = cutout_rect_handler(geom_struct, gapsize, xmin, ymin, xmax, ymax)
solid_geo += c_geo
if gap_type == 'bt' and thin_entry != 0:
if gap_type == 1 and thin_entry != 0: # "Thin gaps"
try:
gaps_solid_geo += self.subtract_geo(geom_struct, c_geo)
except TypeError:
@@ -1286,7 +1194,7 @@ class CutOut(AppTool):
c_geo = cutout_rect_handler(geom_struct, gapsize, xmin, ymin, xmax, ymax)
solid_geo += c_geo
if gap_type == 'bt' and thin_entry != 0:
if gap_type == 1 and thin_entry != 0: # "Thin gaps"
try:
gaps_solid_geo += self.subtract_geo(geom_struct, c_geo)
except TypeError:
@@ -1436,7 +1344,7 @@ class CutOut(AppTool):
exc_obj.options['ymax'] = e_ymax
try:
if self.ui.gaptype_radio.get_value() == 'mb':
if self.ui.gaptype_combo.get_value() == 2: # "mouse bytes"
ret = app_obj.app_obj.new_object('excellon', outname_exc, excellon_init, autoselected=False)
if ret == 'fail':
app_obj.inform.emit('[ERROR_NOTCL] %s' % _("Mouse bites failed."))
@@ -1544,7 +1452,7 @@ class CutOut(AppTool):
with self.app.proc_container.new('%s...' % _("Working")):
try:
ret = self.app.app_obj.new_object("excellon", outname, obj_init)
ret = self.app.app_obj.new_object("excellon", outname, obj_init, autoselected=False)
except Exception as e:
log.error("Error on Drill Cutting Excellon object creation: %s" % str(e))
return
@@ -1579,7 +1487,7 @@ class CutOut(AppTool):
_("Tool Diameter is zero value. Change it to a positive real number."))
return
if self.ui.gaptype_radio.get_value() == 'mb':
if self.ui.gaptype_combo.get_value() == 2: # "mouse bytes"
mb_dia = self.ui.mb_dia_entry.get_value()
b_dia = (self.cutting_dia / 2.0) - (mb_dia / 2.0)
# flaten manual geometry
@@ -1638,12 +1546,12 @@ class CutOut(AppTool):
cut_poly = self.cutting_geo(pos=(snapped_pos[0], snapped_pos[1]))
gap_type = self.ui.gaptype_radio.get_value()
gap_type = self.ui.gaptype_combo.get_value()
gaps_solid_geo = None
if gap_type == 'bt' and self.ui.thin_depth_entry.get_value() != 0:
if gap_type == 1 and self.ui.thin_depth_entry.get_value() != 0: # "Thin gaps"
gaps_solid_geo = self.intersect_geo(self.manual_solid_geo, cut_poly)
if gap_type == 'mb':
if gap_type == 2: # "Mouse Bytes"
rests_geo = self.intersect_geo(self.mb_manual_solid_geo, cut_poly)
if isinstance(rests_geo, list):
self.mb_manual_cuts += rests_geo
@@ -1739,7 +1647,7 @@ class CutOut(AppTool):
elif kind == 'single':
if isinstance(geo_union, Polygon) or \
(isinstance(geo_union, list) and len(geo_union) == 1) or \
(isinstance(geo_union, MultiPolygon) and len(geo_union) == 1):
(isinstance(geo_union, MultiPolygon) and len(geo_union.geoms) == 1):
geo_obj.solid_geometry = geo_union.buffer(margin + abs(dia / 2)).exterior
elif isinstance(geo_union, MultiPolygon):
x0, y0, x1, y1 = geo_union.bounds
@@ -1779,7 +1687,7 @@ class CutOut(AppTool):
geo_obj.tools[1]['data']['tools_mill_depthperpass'] = self.ui.maxdepth_entry.get_value()
outname = cutout_obj.options["name"] + "_cutout"
self.app.app_obj.new_object('geometry', outname, geo_init)
self.app.app_obj.new_object('geometry', outname, geo_init, autoselected=False)
def cutting_geo(self, pos):
self.cutting_dia = float(self.ui.dia.get_value())
@@ -1862,7 +1770,7 @@ class CutOut(AppTool):
self.man_cutout_obj.plot()
# mouse bytes
if self.ui.gaptype_radio.get_value() == 'mb':
if self.ui.gaptype_combo.get_value() == 2: # "mouse bytes"
with self.app.proc_container.new("Generating Excellon ..."):
outname_exc = self.man_cutout_obj.options["name"] + "_mouse_bites"
self.app.collection.promise(outname_exc)
@@ -2305,8 +2213,8 @@ class CutoutUI:
self.tools_box.addWidget(obj_frame)
# Grid Layout
grid0 = FCGridLayout(v_spacing=5, h_spacing=3)
obj_frame.setLayout(grid0)
obj_grid = FCGridLayout(v_spacing=5, h_spacing=3)
obj_frame.setLayout(obj_grid)
# Object kind
self.kindlabel = FCLabel('%s:' % _('Kind'))
@@ -2320,8 +2228,8 @@ class CutoutUI:
{"label": _("Single"), "value": "single"},
{"label": _("Panel"), "value": "panel"},
])
grid0.addWidget(self.kindlabel, 2, 0)
grid0.addWidget(self.obj_kind_combo, 2, 1)
obj_grid.addWidget(self.kindlabel, 2, 0)
obj_grid.addWidget(self.obj_kind_combo, 2, 1)
# Type of object to be cutout
self.type_obj_radio = RadioSet([
@@ -2337,8 +2245,8 @@ class CutoutUI:
"of objects that will populate the 'Object' combobox.")
)
grid0.addWidget(self.type_obj_combo_label, 4, 0)
grid0.addWidget(self.type_obj_radio, 4, 1)
obj_grid.addWidget(self.type_obj_combo_label, 4, 0)
obj_grid.addWidget(self.type_obj_radio, 4, 1)
# Object to be cutout
self.obj_combo = FCComboBox()
@@ -2346,7 +2254,7 @@ class CutoutUI:
self.obj_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
self.obj_combo.is_last = False
grid0.addWidget(self.obj_combo, 6, 0, 1, 2)
obj_grid.addWidget(self.obj_combo, 6, 0, 1, 2)
self.tool_sel_label = FCLabel('<span style="color:indigo;"><b>%s</b></span>' % _('Cutout Tool'))
self.tools_box.addWidget(self.tool_sel_label)
@@ -2358,8 +2266,8 @@ class CutoutUI:
self.tools_box.addWidget(tool_frame)
# Grid Layout
grid1 = FCGridLayout(v_spacing=5, h_spacing=3)
tool_frame.setLayout(grid1)
tool_grid = FCGridLayout(v_spacing=5, h_spacing=3)
tool_frame.setLayout(tool_grid)
# Tool Diameter
self.dia = FCDoubleSpinner(callback=self.confirmation_message)
@@ -2371,8 +2279,8 @@ class CutoutUI:
_("Diameter of the tool used to cutout\n"
"the PCB shape out of the surrounding material.")
)
grid1.addWidget(self.dia_label, 0, 0)
grid1.addWidget(self.dia, 0, 1)
tool_grid.addWidget(self.dia_label, 0, 0)
tool_grid.addWidget(self.dia, 0, 1)
hlay = QtWidgets.QHBoxLayout()
@@ -2399,12 +2307,12 @@ class CutoutUI:
)
hlay.addWidget(self.addtool_from_db_btn)
grid1.addLayout(hlay, 2, 0, 1, 2)
tool_grid.addLayout(hlay, 2, 0, 1, 2)
# separator_line = QtWidgets.QFrame()
# separator_line.setFrameShape(QtWidgets.QFrame.Shape.HLine)
# separator_line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken)
# grid0.addWidget(separator_line, 18, 0, 1, 2)
# obj_grid.addWidget(separator_line, 18, 0, 1, 2)
self.param_label = FCLabel('<span style="color:blue;"><b>%s</b></span>' % _("Tool Parameters"))
self.tools_box.addWidget(self.param_label)
@@ -2416,8 +2324,8 @@ class CutoutUI:
self.tools_box.addWidget(tool_par_frame)
# Grid Layout
grid2 = FCGridLayout(v_spacing=5, h_spacing=3)
tool_par_frame.setLayout(grid2)
param_grid = FCGridLayout(v_spacing=5, h_spacing=3)
tool_par_frame.setLayout(param_grid)
# Convex Shape
# Surrounding convex box shape
@@ -2431,8 +2339,8 @@ class CutoutUI:
_("Create a convex shape surrounding the entire PCB.\n"
"Used only if the source object type is Gerber.")
)
grid2.addWidget(self.convex_box_label, 0, 0)
grid2.addWidget(self.convex_box_cb, 0, 1)
param_grid.addWidget(self.convex_box_label, 0, 0)
param_grid.addWidget(self.convex_box_cb, 0, 1)
# Cut Z
cutzlabel = FCLabel('%s:' % _('Cut Z'))
@@ -2446,8 +2354,8 @@ class CutoutUI:
self.cutz_entry.setSingleStep(0.1)
grid2.addWidget(cutzlabel, 2, 0)
grid2.addWidget(self.cutz_entry, 2, 1)
param_grid.addWidget(cutzlabel, 2, 0)
param_grid.addWidget(self.cutz_entry, 2, 1)
# Multi-pass
self.mpass_cb = FCCheckBox('%s:' % _("Multi-Depth"))
@@ -2465,8 +2373,8 @@ class CutoutUI:
self.maxdepth_entry.setToolTip(_("Depth of each pass (positive)."))
grid2.addWidget(self.mpass_cb, 4, 0)
grid2.addWidget(self.maxdepth_entry, 4, 1)
param_grid.addWidget(self.mpass_cb, 4, 0)
param_grid.addWidget(self.maxdepth_entry, 4, 1)
self.ois_mpass_geo = OptionalInputSection(self.mpass_cb, [self.maxdepth_entry])
@@ -2482,11 +2390,24 @@ class CutoutUI:
"will make the cutout of the PCB further from\n"
"the actual PCB border")
)
grid2.addWidget(self.margin_label, 6, 0)
grid2.addWidget(self.margin, 6, 1)
param_grid.addWidget(self.margin_label, 6, 0)
param_grid.addWidget(self.margin, 6, 1)
self.gaps_label = FCLabel('<span style="color:green;"><b>%s</b></span>' % _("Gaps"))
self.tools_box.addWidget(self.gaps_label)
# #############################################################################################################
# Gaps Frame
# #############################################################################################################
gaps_frame = FCFrame()
self.tools_box.addWidget(gaps_frame)
# Grid Layout
gaps_grid = FCGridLayout(v_spacing=5, h_spacing=3)
gaps_frame.setLayout(gaps_grid)
# Gapsize
self.gapsize_label = FCLabel('%s:' % _("Gap size"))
self.gapsize_label = FCLabel('%s:' % _("Size"))
self.gapsize_label.setToolTip(
_("The size of the bridge gaps in the cutout\n"
"used to keep the board connected to\n"
@@ -2498,11 +2419,11 @@ class CutoutUI:
self.gapsize.setRange(0.0000, 10000.0000)
self.gapsize.set_precision(self.decimals)
grid2.addWidget(self.gapsize_label, 8, 0)
grid2.addWidget(self.gapsize, 8, 1)
gaps_grid.addWidget(self.gapsize_label, 2, 0)
gaps_grid.addWidget(self.gapsize, 2, 1)
# Gap Type
self.gaptype_label = FCLabel('%s:' % _("Gap type"))
self.gaptype_label = FCLabel('%s:' % _("Type"))
self.gaptype_label.setToolTip(
_("The type of gap:\n"
"- Bridge -> the cutout will be interrupted by bridges\n"
@@ -2510,17 +2431,19 @@ class CutoutUI:
"- M-Bites -> 'Mouse Bites' - same as 'bridge' but covered with drill holes")
)
self.gaptype_radio = RadioSet(
[
{'label': _('Bridge'), 'value': 'b'},
{'label': _('Thin'), 'value': 'bt'},
{'label': "M-Bites", 'value': 'mb'}
],
stretch=True
)
# self.gaptype_combo = RadioSet(
# [
# {'label': _('Bridge'), 'value': 'b'},
# {'label': _('Thin'), 'value': 'bt'},
# {'label': "M-Bites", 'value': 'mb'}
# ],
# stretch=True
# )
self.gaptype_combo = FCComboBox2()
self.gaptype_combo.addItems([_('Bridge'), _('Thin'), _("Mouse Bytes")])
grid2.addWidget(self.gaptype_label, 10, 0)
grid2.addWidget(self.gaptype_radio, 10, 1)
gaps_grid.addWidget(self.gaptype_label, 4, 0)
gaps_grid.addWidget(self.gaptype_combo, 4, 1)
# Thin gaps Depth
self.thin_depth_label = FCLabel('%s:' % _("Depth"))
@@ -2533,11 +2456,11 @@ class CutoutUI:
self.thin_depth_entry.setRange(-10000.0000, 10000.0000)
self.thin_depth_entry.setSingleStep(0.1)
grid2.addWidget(self.thin_depth_label, 12, 0)
grid2.addWidget(self.thin_depth_entry, 12, 1)
gaps_grid.addWidget(self.thin_depth_label, 6, 0)
gaps_grid.addWidget(self.thin_depth_entry, 6, 1)
# Mouse Bites Tool Diameter
self.mb_dia_label = FCLabel('%s:' % _("Tool Diameter"))
self.mb_dia_label = FCLabel('%s:' % _("Tool Dia"))
self.mb_dia_label.setToolTip(
_("The drill hole diameter when doing mouse bites.")
)
@@ -2545,8 +2468,8 @@ class CutoutUI:
self.mb_dia_entry.set_precision(self.decimals)
self.mb_dia_entry.setRange(0, 10000.0000)
grid2.addWidget(self.mb_dia_label, 14, 0)
grid2.addWidget(self.mb_dia_entry, 14, 1)
gaps_grid.addWidget(self.mb_dia_label, 8, 0)
gaps_grid.addWidget(self.mb_dia_entry, 8, 1)
# Mouse Bites Holes Spacing
self.mb_spacing_label = FCLabel('%s:' % _("Spacing"))
@@ -2557,18 +2480,18 @@ class CutoutUI:
self.mb_spacing_entry.set_precision(self.decimals)
self.mb_spacing_entry.setRange(0, 10000.0000)
grid2.addWidget(self.mb_spacing_label, 16, 0)
grid2.addWidget(self.mb_spacing_entry, 16, 1)
gaps_grid.addWidget(self.mb_spacing_label, 10, 0)
gaps_grid.addWidget(self.mb_spacing_entry, 10, 1)
separator_line = QtWidgets.QFrame()
separator_line.setFrameShape(QtWidgets.QFrame.Shape.HLine)
separator_line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken)
grid2.addWidget(separator_line, 18, 0, 1, 2)
self.separator_line = QtWidgets.QFrame()
self.separator_line.setFrameShape(QtWidgets.QFrame.Shape.HLine)
self.separator_line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken)
gaps_grid.addWidget(self.separator_line, 12, 0, 1, 2)
# ##############################################################################################################
# ######################################## Type of CUTOUT ######################################################
# ##############################################################################################################
self.cutout_type_label = FCLabel('%s:' % _("Bridge Gaps"))
self.cutout_type_label = FCLabel('%s:' % _("Bridge"))
self.cutout_type_label.setToolTip(
_("Selection of the type of cutout.")
)
@@ -2578,8 +2501,8 @@ class CutoutUI:
{"label": _("Manual"), "value": "m"},
])
grid2.addWidget(self.cutout_type_label, 20, 0)
grid2.addWidget(self.cutout_type_radio, 20, 1)
gaps_grid.addWidget(self.cutout_type_label, 14, 0)
gaps_grid.addWidget(self.cutout_type_radio, 14, 1)
# Gaps
# How gaps wil be rendered:
@@ -2609,8 +2532,24 @@ class CutoutUI:
for it in gaps_items:
self.gaps.addItem(it)
# self.gaps.setStyleSheet('background-color: rgb(255,255,255)')
grid2.addWidget(self.gaps_label, 22, 0)
grid2.addWidget(self.gaps, 22, 1)
gaps_grid.addWidget(self.gaps_label, 16, 0)
gaps_grid.addWidget(self.gaps, 16, 1)
# #############################################################################################################
# Manual Gaps Frame
# #############################################################################################################
self.man_frame = QtWidgets.QFrame()
self.man_frame.setContentsMargins(0, 0, 0, 0)
gaps_grid.addWidget(self.man_frame, 18, 0, 1, 2)
man_grid = FCGridLayout(v_spacing=5, h_spacing=3)
man_grid.setContentsMargins(0, 0, 0, 0)
self.man_frame.setLayout(man_grid)
separator_line = QtWidgets.QFrame()
separator_line.setFrameShape(QtWidgets.QFrame.Shape.HLine)
separator_line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken)
man_grid.addWidget(separator_line, 0, 0, 1, 2)
# Big Cursor
self.big_cursor_label = FCLabel('%s:' % _("Big cursor"))
@@ -2618,8 +2557,8 @@ class CutoutUI:
_("Use a big cursor when adding manual gaps."))
self.big_cursor_cb = FCCheckBox()
grid2.addWidget(self.big_cursor_label, 24, 0)
grid2.addWidget(self.big_cursor_cb, 24, 1)
man_grid.addWidget(self.big_cursor_label, 2, 0)
man_grid.addWidget(self.big_cursor_cb, 2, 1)
# Manual Geo Object
self.man_object_combo = FCComboBox()
@@ -2634,13 +2573,41 @@ class CutoutUI:
)
# self.man_object_label.setMinimumWidth(60)
grid2.addWidget(self.man_object_label, 26, 0, 1, 2)
grid2.addWidget(self.man_object_combo, 26, 0, 1, 2)
man_grid.addWidget(self.man_object_label, 4, 0, 1, 2)
man_grid.addWidget(self.man_object_combo, 6, 0, 1, 2)
# #############################################################################################################
# Buttons
# #############################################################################################################
man_hlay = QtWidgets.QHBoxLayout()
self.tools_box.addLayout(man_hlay)
# Generate a surrounding Geometry object Button
self.man_geo_creation_btn = FCButton(_("Manual Geometry"))
self.man_geo_creation_btn.setIcon(QtGui.QIcon(self.app.resource_location + '/rectangle32.png'))
self.man_geo_creation_btn.setToolTip(
_("Generate a Geometry to be used as cutout.")
)
# self.man_geo_creation_btn.setStyleSheet("""
# QPushButton
# {
# font-weight: bold;
# }
# """)
# Manual Add of Gaps Button
self.man_gaps_creation_btn = QtWidgets.QToolButton()
self.man_gaps_creation_btn.setToolButtonStyle(QtCore.Qt.ToolButtonStyle.ToolButtonTextBesideIcon)
self.man_gaps_creation_btn.setIcon(QtGui.QIcon(self.app.resource_location + '/plus32.png'))
self.man_gaps_creation_btn.setText(_("Gaps"))
self.man_gaps_creation_btn.setToolTip(
_("Add new gaps on the selected Geometry object\n"
"by clicking mouse left button on the Geometry outline.")
)
man_hlay.addWidget(self.man_geo_creation_btn)
man_hlay.addWidget(self.man_gaps_creation_btn)
# Freeform Geometry Button
self.ff_cutout_object_btn = FCButton(_("Generate Geometry"))
self.ff_cutout_object_btn.setIcon(QtGui.QIcon(self.app.resource_location + '/irregular32.png'))
@@ -2674,47 +2641,12 @@ class CutoutUI:
""")
self.tools_box.addWidget(self.rect_cutout_object_btn)
# Generate a surrounding Geometry object Button
self.man_geo_creation_btn = FCButton(_("Generate Manual Geometry"))
self.man_geo_creation_btn.setIcon(QtGui.QIcon(self.app.resource_location + '/rectangle32.png'))
self.man_geo_creation_btn.setToolTip(
_("If the object to be cutout is a Gerber\n"
"first create a Geometry that surrounds it,\n"
"to be used as the cutout, if one doesn't exist yet.\n"
"Select the source Gerber file in the top object combobox.")
)
# self.man_geo_creation_btn.setStyleSheet("""
# QPushButton
# {
# font-weight: bold;
# }
# """)
self.tools_box.addWidget(self.man_geo_creation_btn)
# Manual Add of Gaps Button
self.man_gaps_creation_btn = FCButton(_("Manual Add Bridge Gaps"))
self.man_gaps_creation_btn.setIcon(QtGui.QIcon(self.app.resource_location + '/gaps32.png'))
self.man_gaps_creation_btn.setToolTip(
_("Use the left mouse button (LMB) click\n"
"to create a bridge gap to separate the PCB from\n"
"the surrounding material.\n"
"The LMB click has to be done on the perimeter of\n"
"the Geometry object used as a cutout geometry.")
)
self.man_gaps_creation_btn.setStyleSheet("""
QPushButton
{
font-weight: bold;
}
""")
self.tools_box.addWidget(self.man_gaps_creation_btn)
# self.tool_param_separator_line = QtWidgets.QFrame()
# self.tool_param_separator_line.setFrameShape(QtWidgets.QFrame.Shape.HLine)
# self.tool_param_separator_line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken)
# grid0.addWidget(self.tool_param_separator_line, 60, 0, 1, 2)
# obj_grid.addWidget(self.tool_param_separator_line, 60, 0, 1, 2)
# grid0.addWidget(FCLabel(""), 62, 0, 1, 2)
# obj_grid.addWidget(FCLabel(""), 62, 0, 1, 2)
# Cut by Drilling Title
self.title_drillcut_label = FCLabel('<span style="color:red;"><b>%s</b></span>' % _('Cut by Drilling'))
@@ -2728,8 +2660,8 @@ class CutoutUI:
self.tools_box.addWidget(self.drill_cut_frame)
# Grid Layout
grid3 = FCGridLayout(v_spacing=5, h_spacing=3)
self.drill_cut_frame.setLayout(grid3)
drill_cut_grid = FCGridLayout(v_spacing=5, h_spacing=3)
self.drill_cut_frame.setLayout(drill_cut_grid)
# Drilling Geo Object Label
self.drillcut_object_lbl = FCLabel('%s:' % _("Geometry"))
@@ -2737,16 +2669,16 @@ class CutoutUI:
_("Geometry object used to create the manual cutout.")
)
grid3.addWidget(self.drillcut_object_lbl, 0, 0, 1, 2)
drill_cut_grid.addWidget(self.drillcut_object_lbl, 0, 0, 1, 2)
# Drilling Geo Object
self.drillcut_object_combo = FCComboBox()
self.drillcut_object_combo.setModel(self.app.collection)
self.drillcut_object_combo.setRootModelIndex(self.app.collection.index(2, 0, QtCore.QModelIndex()))
self.drillcut_object_combo.is_last = True
self.drillcut_object_combo.is_last = False
self.drillcut_object_combo.obj_type = "Geometry"
grid3.addWidget(self.drillcut_object_combo, 2, 0, 1, 2)
drill_cut_grid.addWidget(self.drillcut_object_combo, 2, 0, 1, 2)
# Drill Tool Diameter
self.drill_dia_entry = FCDoubleSpinner(callback=self.confirmation_message)
@@ -2758,8 +2690,8 @@ class CutoutUI:
_("Diameter of the tool used to cutout\n"
"the PCB by drilling.")
)
grid3.addWidget(self.drill_dia_label, 4, 0)
grid3.addWidget(self.drill_dia_entry, 4, 1)
drill_cut_grid.addWidget(self.drill_dia_label, 4, 0)
drill_cut_grid.addWidget(self.drill_dia_entry, 4, 1)
# Drill Tool Pitch
self.drill_pitch_entry = FCDoubleSpinner(callback=self.confirmation_message)
@@ -2771,8 +2703,8 @@ class CutoutUI:
_("Distance between the center of\n"
"two neighboring drill holes.")
)
grid3.addWidget(self.drill_pitch_label, 6, 0)
grid3.addWidget(self.drill_pitch_entry, 6, 1)
drill_cut_grid.addWidget(self.drill_pitch_label, 6, 0)
drill_cut_grid.addWidget(self.drill_pitch_entry, 6, 1)
# Drill Tool Margin
self.drill_margin_entry = FCDoubleSpinner(callback=self.confirmation_message)
@@ -2785,8 +2717,10 @@ class CutoutUI:
"will make the cutout of the PCB further from\n"
"the actual PCB border")
)
grid3.addWidget(self.drill_margin_label, 8, 0)
grid3.addWidget(self.drill_margin_entry, 8, 1)
drill_cut_grid.addWidget(self.drill_margin_label, 8, 0)
drill_cut_grid.addWidget(self.drill_margin_entry, 8, 1)
FCGridLayout.set_common_column_size([obj_grid, tool_grid, param_grid, man_grid, drill_cut_grid, gaps_grid], 0)
# Drill Cut Button
self.drillcut_btn = FCButton(_("Cut by Drilling"))
@@ -2818,27 +2752,27 @@ class CutoutUI:
""")
self.layout.addWidget(self.reset_button)
self.gaptype_radio.activated_custom.connect(self.on_gap_type_radio)
self.gaptype_combo.currentIndexChanged.connect(self.on_gap_type_radio)
# ############################ FINSIHED GUI ###################################
# #############################################################################
def on_gap_type_radio(self, val):
if val == 'b':
def on_gap_type_radio(self, index):
if index == 0: # Normal gap
self.thin_depth_label.hide()
self.thin_depth_entry.hide()
self.mb_dia_label.hide()
self.mb_dia_entry.hide()
self.mb_spacing_label.hide()
self.mb_spacing_entry.hide()
elif val == 'bt':
elif index == 1: # "Thin gaps"
self.thin_depth_label.show()
self.thin_depth_entry.show()
self.mb_dia_label.hide()
self.mb_dia_entry.hide()
self.mb_spacing_label.hide()
self.mb_spacing_entry.hide()
elif val == 'mb':
elif index == 2: # "Mouse Bytes"
self.thin_depth_label.hide()
self.thin_depth_entry.hide()
self.mb_dia_label.show()

View File

@@ -510,7 +510,7 @@ class FlatCAMDefaults:
"tools_cutout_gaps_ff": "4",
"tools_cutout_convexshape": False,
"tools_cutout_big_cursor": True,
"tools_cutout_gap_type": 'b',
"tools_cutout_gap_type": 0, # "Basic Gap"
"tools_cutout_gap_depth": -1.0,
"tools_cutout_mb_dia": 0.6,
"tools_cutout_mb_spacing": 0.3,