- 2Sided Tool - fixed newly introduced issues in the Alignment section
- 2Sided Tool - modified the UI such that some of the fields will allow only numbers and some special characters ([,],(,),/,*,,,+,-,%) - Cutout Tool - working on adding mouse bites for the Freeform cutout - updated the translation files to the current state of the app
This commit is contained in:
parent
6c9c367540
commit
f73f6fb5da
|
@ -7,6 +7,13 @@ CHANGELOG for FlatCAM beta
|
|||
|
||||
=================================================
|
||||
|
||||
29.08.2020
|
||||
|
||||
- 2Sided Tool - fixed newly introduced issues in the Alignment section
|
||||
- 2Sided Tool - modified the UI such that some of the fields will allow only numbers and some special characters ([,],(,),/,*,,,+,-,%)
|
||||
- Cutout Tool - working on adding mouse bites for the Freeform cutout
|
||||
- updated the translation files to the current state of the app
|
||||
|
||||
28.08.2020
|
||||
|
||||
- Paint Tool - upgraded the UI and added the functionality that now adding a new tool is done by first searching the Tools DB for a suitable tool and if fails then it adds an default tool
|
||||
|
|
|
@ -286,7 +286,7 @@ class LengthEntry(QtWidgets.QLineEdit):
|
|||
# Unit conversion table OUTPUT-INPUT
|
||||
self.scales = {
|
||||
'IN': {'IN': 1.0,
|
||||
'MM': 1/25.4},
|
||||
'MM': 1 / 25.4},
|
||||
'MM': {'IN': 25.4,
|
||||
'MM': 1.0}
|
||||
}
|
||||
|
@ -668,6 +668,7 @@ class NumericalEvalEntry(FCEntry):
|
|||
"""
|
||||
Will evaluate the input and return a value. Accepts only float numbers and formulas using the operators: /,*,+,-,%
|
||||
"""
|
||||
|
||||
def __init__(self, border_color=None):
|
||||
super().__init__(border_color=border_color)
|
||||
|
||||
|
@ -691,10 +692,11 @@ class NumericalEvalTupleEntry(EvalEntry):
|
|||
"""
|
||||
Will return a text value. Accepts only float numbers and formulas using the operators: /,*,+,-,%
|
||||
"""
|
||||
|
||||
def __init__(self, border_color=None):
|
||||
super().__init__(border_color=border_color)
|
||||
|
||||
regex = QtCore.QRegExp("[0-9\/\*\+\-\%\.\s\,\[\]]*")
|
||||
regex = QtCore.QRegExp("[0-9\/\*\+\-\%\.\s\,\[\]\(\)]*")
|
||||
validator = QtGui.QRegExpValidator(regex, self)
|
||||
self.setValidator(validator)
|
||||
|
||||
|
@ -802,7 +804,6 @@ class FCSliderWithSpinner(QtWidgets.QFrame):
|
|||
|
||||
|
||||
class FCSpinner(QtWidgets.QSpinBox):
|
||||
|
||||
returnPressed = QtCore.pyqtSignal()
|
||||
confirmation_signal = QtCore.pyqtSignal(bool, float, float)
|
||||
|
||||
|
@ -1040,7 +1041,6 @@ class FCSliderWithDoubleSpinner(QtWidgets.QFrame):
|
|||
|
||||
|
||||
class FCDoubleSpinner(QtWidgets.QDoubleSpinBox):
|
||||
|
||||
returnPressed = QtCore.pyqtSignal()
|
||||
confirmation_signal = QtCore.pyqtSignal(bool, float, float)
|
||||
|
||||
|
@ -1694,7 +1694,6 @@ class FCButton(QtWidgets.QPushButton):
|
|||
|
||||
|
||||
class FCLabel(QtWidgets.QLabel):
|
||||
|
||||
clicked = QtCore.pyqtSignal(bool)
|
||||
right_clicked = QtCore.pyqtSignal(bool)
|
||||
middle_clicked = QtCore.pyqtSignal(bool)
|
||||
|
@ -2018,7 +2017,7 @@ class FCDetachableTab(QtWidgets.QTabWidget):
|
|||
if str(tab_name) == str(self.tabText(index)):
|
||||
self.protectTab(index)
|
||||
|
||||
# Make this tab the current tab
|
||||
# Make this tab the current tab
|
||||
if index > -1:
|
||||
self.setCurrentIndex(insert_index) if self.use_old_index else self.setCurrentIndex(index)
|
||||
|
||||
|
@ -2101,7 +2100,6 @@ class FCDetachableTab(QtWidgets.QTabWidget):
|
|||
# area to the side of the QTabBar) or there are not tabs
|
||||
# currently attached...
|
||||
if tabDropPos.y() < self.tabBar.height() or self.count() == 0:
|
||||
|
||||
# Close the detached tab and allow it to re-attach
|
||||
# automatically
|
||||
self.detachedTabs[name].close()
|
||||
|
@ -2422,6 +2420,7 @@ class VerticalScrollArea(QtWidgets.QScrollArea):
|
|||
scroll area that also expands horizontally to accommodate
|
||||
its contents.
|
||||
"""
|
||||
|
||||
def __init__(self, parent=None):
|
||||
QtWidgets.QScrollArea.__init__(self, parent=parent)
|
||||
self.setWidgetResizable(True)
|
||||
|
@ -2537,7 +2536,6 @@ class OptionalHideInputSection:
|
|||
|
||||
|
||||
class FCTable(QtWidgets.QTableWidget):
|
||||
|
||||
drag_drop_sig = QtCore.pyqtSignal(object, int)
|
||||
lost_focus = QtCore.pyqtSignal()
|
||||
|
||||
|
@ -3011,7 +3009,7 @@ class _BrowserTextEdit(QTextEdit):
|
|||
save_action.triggered.connect(lambda: self.save_log(app=self.app))
|
||||
|
||||
clear_action = QAction(_("Clear"), self)
|
||||
clear_action.setShortcut(QKeySequence(Qt.Key_Delete)) # it's not working, the shortcut
|
||||
clear_action.setShortcut(QKeySequence(Qt.Key_Delete)) # it's not working, the shortcut
|
||||
self.menu.addAction(clear_action)
|
||||
clear_action.triggered.connect(self.clear)
|
||||
|
||||
|
@ -3507,8 +3505,8 @@ class FCZeroAxes(QtWidgets.QFrame):
|
|||
|
||||
|
||||
class RotatedToolButton(QtWidgets.QToolButton):
|
||||
def __init__(self, orientation = "east", *args, **kwargs):
|
||||
super(RotatedToolButton,self).__init__(*args, **kwargs)
|
||||
def __init__(self, orientation="east", *args, **kwargs):
|
||||
super(RotatedToolButton, self).__init__(*args, **kwargs)
|
||||
self.orientation = orientation
|
||||
|
||||
def paintEvent(self, event):
|
||||
|
@ -3560,8 +3558,8 @@ class RotatedToolButton(QtWidgets.QToolButton):
|
|||
|
||||
|
||||
class RotatedButton(QtWidgets.QPushButton):
|
||||
def __init__(self, orientation = "west", *args, **kwargs):
|
||||
super(RotatedButton,self).__init__(*args, **kwargs)
|
||||
def __init__(self, orientation="west", *args, **kwargs):
|
||||
super(RotatedButton, self).__init__(*args, **kwargs)
|
||||
self.orientation = orientation
|
||||
|
||||
def paintEvent(self, event):
|
||||
|
|
|
@ -10,7 +10,7 @@ from appTool import AppTool
|
|||
from appGUI.GUIElements import FCDoubleSpinner, FCCheckBox, RadioSet, FCComboBox, OptionalInputSection, FCButton, \
|
||||
FCLabel
|
||||
|
||||
from shapely.geometry import box, MultiPolygon, Polygon, LineString, LinearRing, MultiLineString
|
||||
from shapely.geometry import box, MultiPolygon, Polygon, LineString, LinearRing, MultiLineString, Point
|
||||
from shapely.ops import cascaded_union, unary_union, linemerge
|
||||
import shapely.affinity as affinity
|
||||
|
||||
|
@ -187,52 +187,52 @@ class CutOut(AppTool):
|
|||
self.ui.dia.set_value(float(self.app.defaults["tools_cutout_tooldia"]))
|
||||
|
||||
self.default_data.update({
|
||||
"plot": True,
|
||||
"plot": True,
|
||||
|
||||
"cutz": float(self.app.defaults["geometry_cutz"]),
|
||||
"multidepth": self.app.defaults["geometry_multidepth"],
|
||||
"depthperpass": float(self.app.defaults["geometry_depthperpass"]),
|
||||
"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["geometry_vtipdia"]),
|
||||
"vtipangle": float(self.app.defaults["geometry_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"]),
|
||||
"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"],
|
||||
"vtipdia": float(self.app.defaults["geometry_vtipdia"]),
|
||||
"vtipangle": float(self.app.defaults["geometry_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"]),
|
||||
"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_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"]),
|
||||
"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"]),
|
||||
|
||||
})
|
||||
tool_dia = float(self.app.defaults["tools_cutout_tooldia"])
|
||||
|
@ -366,14 +366,14 @@ class CutOut(AppTool):
|
|||
|
||||
new_tdia = deepcopy(updated_tooldia) if updated_tooldia is not None else deepcopy(truncated_tooldia)
|
||||
self.cut_tool_dict.update({
|
||||
'tooldia': new_tdia,
|
||||
'offset': deepcopy(offset),
|
||||
'offset_value': deepcopy(offset_val),
|
||||
'type': deepcopy(typ),
|
||||
'tool_type': deepcopy(tool_type),
|
||||
'data': deepcopy(new_tools_dict),
|
||||
'solid_geometry': []
|
||||
})
|
||||
'tooldia': new_tdia,
|
||||
'offset': deepcopy(offset),
|
||||
'offset_value': deepcopy(offset_val),
|
||||
'type': deepcopy(typ),
|
||||
'tool_type': deepcopy(tool_type),
|
||||
'data': deepcopy(new_tools_dict),
|
||||
'solid_geometry': []
|
||||
})
|
||||
|
||||
self.update_ui(new_tools_dict)
|
||||
|
||||
|
@ -381,65 +381,67 @@ class CutOut(AppTool):
|
|||
self.app.inform.emit('[success] %s' % _("Updated tool from Tools Database."))
|
||||
|
||||
def on_tool_default_add(self, dia=None, muted=None):
|
||||
|
||||
dia = dia
|
||||
self.default_data.update({
|
||||
"plot": True,
|
||||
"plot": True,
|
||||
|
||||
"cutz": float(self.app.defaults["geometry_cutz"]),
|
||||
"multidepth": self.app.defaults["geometry_multidepth"],
|
||||
"depthperpass": float(self.app.defaults["geometry_depthperpass"]),
|
||||
"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["geometry_vtipdia"]),
|
||||
"vtipangle": float(self.app.defaults["geometry_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"]),
|
||||
"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"],
|
||||
"vtipdia": float(self.app.defaults["geometry_vtipdia"]),
|
||||
"vtipangle": float(self.app.defaults["geometry_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"]),
|
||||
"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_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"]),
|
||||
"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': str(self.app.defaults["tools_cutout_tooldia"]),
|
||||
'offset': 'Path',
|
||||
'offset_value': 0.0,
|
||||
'type': _('Rough'),
|
||||
'tool_type': 'C1',
|
||||
'data': deepcopy(self.default_data),
|
||||
'solid_geometry': []
|
||||
})
|
||||
'tooldia': str(self.app.defaults["tools_cutout_tooldia"]),
|
||||
'offset': 'Path',
|
||||
'offset_value': 0.0,
|
||||
'type': _('Rough'),
|
||||
'tool_type': 'C1',
|
||||
'data': deepcopy(self.default_data),
|
||||
'solid_geometry': []
|
||||
})
|
||||
|
||||
self.update_ui(self.default_data)
|
||||
|
||||
|
@ -490,13 +492,13 @@ class CutOut(AppTool):
|
|||
truncated_tooldia = self.app.dec_format(tooldia, self.decimals)
|
||||
self.cutout_tools.update({
|
||||
1: {
|
||||
'tooldia': truncated_tooldia,
|
||||
'offset': tool['offset'],
|
||||
'offset_value': tool['offset_value'],
|
||||
'type': tool['type'],
|
||||
'tool_type': tool['tool_type'],
|
||||
'data': deepcopy(tool['data']),
|
||||
'solid_geometry': []
|
||||
'tooldia': truncated_tooldia,
|
||||
'offset': tool['offset'],
|
||||
'offset_value': tool['offset_value'],
|
||||
'type': tool['type'],
|
||||
'tool_type': tool['tool_type'],
|
||||
'data': deepcopy(tool['data']),
|
||||
'solid_geometry': []
|
||||
}
|
||||
})
|
||||
self.cutout_tools[1]['data']['name'] = '_cutout'
|
||||
|
@ -554,7 +556,6 @@ class CutOut(AppTool):
|
|||
return
|
||||
|
||||
margin = float(self.ui.margin.get_value())
|
||||
gapsize = float(self.ui.gapsize.get_value())
|
||||
|
||||
try:
|
||||
gaps = self.ui.gaps.get_value()
|
||||
|
@ -575,225 +576,274 @@ class CutOut(AppTool):
|
|||
"and after that perform Cutout."))
|
||||
return
|
||||
|
||||
convex_box = self.ui.convex_box_cb.get_value()
|
||||
def cutout_handler(geom, gapsize):
|
||||
proc_geometry = []
|
||||
rest_geometry = []
|
||||
r_temp_geo = []
|
||||
initial_geo = deepcopy(geom)
|
||||
|
||||
gapsize = gapsize / 2 + (dia / 2)
|
||||
# Get min and max data for each object as we just cut rectangles across X or Y
|
||||
xxmin, yymin, xxmax, yymax = CutOut.recursive_bounds(geom)
|
||||
|
||||
def geo_init(geo_obj, app_obj):
|
||||
solid_geo = []
|
||||
gaps_solid_geo = None
|
||||
px = 0.5 * (xxmin + xxmax) + margin
|
||||
py = 0.5 * (yymin + yymax) + margin
|
||||
lenx = (xxmax - xxmin) + (margin * 2)
|
||||
leny = (yymax - yymin) + (margin * 2)
|
||||
|
||||
if cutout_obj.kind == 'gerber':
|
||||
if isinstance(cutout_obj.solid_geometry, list):
|
||||
cutout_obj.solid_geometry = MultiPolygon(cutout_obj.solid_geometry)
|
||||
|
||||
try:
|
||||
if convex_box:
|
||||
object_geo = cutout_obj.solid_geometry.convex_hull
|
||||
else:
|
||||
object_geo = cutout_obj.solid_geometry
|
||||
except Exception as err:
|
||||
log.debug("CutOut.on_freeform_cutout().geo_init() --> %s" % str(err))
|
||||
object_geo = cutout_obj.solid_geometry
|
||||
if gaps == 'None':
|
||||
pass
|
||||
else:
|
||||
object_geo = cutout_obj.solid_geometry
|
||||
if gaps == '8' or gaps == '2LR':
|
||||
points = (
|
||||
xxmin - gapsize, # botleft_x
|
||||
py - gapsize + leny / 4, # botleft_y
|
||||
xxmax + gapsize, # topright_x
|
||||
py + gapsize + leny / 4 # topright_y
|
||||
)
|
||||
geom = self.subtract_poly_from_geo(geom, points)
|
||||
r_temp_geo.append(
|
||||
self.intersect_geo(initial_geo, box(points[0], points[1], points[2], points[3]))
|
||||
)
|
||||
|
||||
def cutout_handler(geom):
|
||||
proc_geometry = []
|
||||
rest_geometry = []
|
||||
r_temp_geo = []
|
||||
initial_geo = deepcopy(geom)
|
||||
points = (
|
||||
xxmin - gapsize,
|
||||
py - gapsize - leny / 4,
|
||||
xxmax + gapsize,
|
||||
py + gapsize - leny / 4
|
||||
)
|
||||
geom = self.subtract_poly_from_geo(geom, points)
|
||||
r_temp_geo.append(
|
||||
self.intersect_geo(initial_geo, box(points[0], points[1], points[2], points[3]))
|
||||
)
|
||||
|
||||
# Get min and max data for each object as we just cut rectangles across X or Y
|
||||
xxmin, yymin, xxmax, yymax = CutOut.recursive_bounds(geom)
|
||||
if gaps == '8' or gaps == '2TB':
|
||||
points = (
|
||||
px - gapsize + lenx / 4,
|
||||
yymin - gapsize,
|
||||
px + gapsize + lenx / 4,
|
||||
yymax + gapsize
|
||||
)
|
||||
geom = self.subtract_poly_from_geo(geom, points)
|
||||
r_temp_geo.append(
|
||||
self.intersect_geo(initial_geo, box(points[0], points[1], points[2], points[3]))
|
||||
)
|
||||
|
||||
px = 0.5 * (xxmin + xxmax) + margin
|
||||
py = 0.5 * (yymin + yymax) + margin
|
||||
lenx = (xxmax - xxmin) + (margin * 2)
|
||||
leny = (yymax - yymin) + (margin * 2)
|
||||
points = (
|
||||
px - gapsize - lenx / 4,
|
||||
yymin - gapsize,
|
||||
px + gapsize - lenx / 4,
|
||||
yymax + gapsize
|
||||
)
|
||||
geom = self.subtract_poly_from_geo(geom, points)
|
||||
r_temp_geo.append(
|
||||
self.intersect_geo(initial_geo, box(points[0], points[1], points[2], points[3]))
|
||||
)
|
||||
|
||||
if gaps == 'None':
|
||||
pass
|
||||
else:
|
||||
if gaps == '8' or gaps == '2LR':
|
||||
points = (
|
||||
xxmin - gapsize, # botleft_x
|
||||
py - gapsize + leny / 4, # botleft_y
|
||||
xxmax + gapsize, # topright_x
|
||||
py + gapsize + leny / 4 # topright_y
|
||||
)
|
||||
geom = self.subtract_poly_from_geo(geom, points)
|
||||
r_temp_geo.append(
|
||||
self.intersect_geo(initial_geo, box(points[0], points[1], points[2], points[3]))
|
||||
)
|
||||
if gaps == '4' or gaps == 'LR':
|
||||
points = (
|
||||
xxmin - gapsize,
|
||||
py - gapsize,
|
||||
xxmax + gapsize,
|
||||
py + gapsize
|
||||
)
|
||||
geom = self.subtract_poly_from_geo(geom, points)
|
||||
r_temp_geo.append(
|
||||
self.intersect_geo(initial_geo, box(points[0], points[1], points[2], points[3]))
|
||||
)
|
||||
|
||||
points = (
|
||||
xxmin - gapsize,
|
||||
py - gapsize - leny / 4,
|
||||
xxmax + gapsize,
|
||||
py + gapsize - leny / 4
|
||||
)
|
||||
geom = self.subtract_poly_from_geo(geom, points)
|
||||
r_temp_geo.append(
|
||||
self.intersect_geo(initial_geo, box(points[0], points[1], points[2], points[3]))
|
||||
)
|
||||
if gaps == '4' or gaps == 'TB':
|
||||
points = (
|
||||
px - gapsize,
|
||||
yymin - gapsize,
|
||||
px + gapsize,
|
||||
yymax + gapsize
|
||||
)
|
||||
geom = self.subtract_poly_from_geo(geom, points)
|
||||
r_temp_geo.append(
|
||||
self.intersect_geo(initial_geo, box(points[0], points[1], points[2], points[3]))
|
||||
)
|
||||
|
||||
if gaps == '8' or gaps == '2TB':
|
||||
points = (
|
||||
px - gapsize + lenx / 4,
|
||||
yymin - gapsize,
|
||||
px + gapsize + lenx / 4,
|
||||
yymax + gapsize
|
||||
)
|
||||
geom = self.subtract_poly_from_geo(geom, points)
|
||||
r_temp_geo.append(
|
||||
self.intersect_geo(initial_geo, box(points[0], points[1], points[2], points[3]))
|
||||
)
|
||||
|
||||
points = (
|
||||
px - gapsize - lenx / 4,
|
||||
yymin - gapsize,
|
||||
px + gapsize - lenx / 4,
|
||||
yymax + gapsize
|
||||
)
|
||||
geom = self.subtract_poly_from_geo(geom, points)
|
||||
r_temp_geo.append(
|
||||
self.intersect_geo(initial_geo, box(points[0], points[1], points[2], points[3]))
|
||||
)
|
||||
|
||||
if gaps == '4' or gaps == 'LR':
|
||||
points = (
|
||||
xxmin - gapsize,
|
||||
py - gapsize,
|
||||
xxmax + gapsize,
|
||||
py + gapsize
|
||||
)
|
||||
geom = self.subtract_poly_from_geo(geom, points)
|
||||
r_temp_geo.append(
|
||||
self.intersect_geo(initial_geo, box(points[0], points[1], points[2], points[3]))
|
||||
)
|
||||
|
||||
if gaps == '4' or gaps == 'TB':
|
||||
points = (
|
||||
px - gapsize,
|
||||
yymin - gapsize,
|
||||
px + gapsize,
|
||||
yymax + gapsize
|
||||
)
|
||||
geom = self.subtract_poly_from_geo(geom, points)
|
||||
r_temp_geo.append(
|
||||
self.intersect_geo(initial_geo, box(points[0], points[1], points[2], points[3]))
|
||||
)
|
||||
|
||||
try:
|
||||
for g in geom:
|
||||
if g and not g.is_empty:
|
||||
proc_geometry.append(g)
|
||||
except TypeError:
|
||||
if geom and not geom.is_empty:
|
||||
proc_geometry.append(geom)
|
||||
|
||||
r_temp_geo = CutOut.flatten(r_temp_geo)
|
||||
for g in r_temp_geo:
|
||||
try:
|
||||
for g in geom:
|
||||
if g and not g.is_empty:
|
||||
rest_geometry.append(g)
|
||||
proc_geometry.append(g)
|
||||
except TypeError:
|
||||
if geom and not geom.is_empty:
|
||||
proc_geometry.append(geom)
|
||||
|
||||
return proc_geometry, rest_geometry
|
||||
r_temp_geo = CutOut.flatten(r_temp_geo)
|
||||
for g in r_temp_geo:
|
||||
if g and not g.is_empty:
|
||||
rest_geometry.append(g)
|
||||
|
||||
if kind == 'single':
|
||||
object_geo = unary_union(object_geo)
|
||||
return proc_geometry, rest_geometry
|
||||
|
||||
with self.app.proc_container.new("Generating Cutout ..."):
|
||||
outname = cutout_obj.options["name"] + "_cutout"
|
||||
self.app.collection.promise(outname)
|
||||
|
||||
outname_exc = cutout_obj.options["name"] + "_mouse_bites"
|
||||
if self.ui.gaptype_radio.get_value() == 'mb':
|
||||
self.app.collection.promise(outname_exc)
|
||||
|
||||
def job_thread(app_obj):
|
||||
solid_geo = []
|
||||
gaps_solid_geo = []
|
||||
mouse_bites_geo = []
|
||||
|
||||
convex_box = self.ui.convex_box_cb.get_value()
|
||||
gapsize = self.ui.gapsize.get_value()
|
||||
gapsize = gapsize / 2 + (dia / 2)
|
||||
|
||||
# for geo in object_geo:
|
||||
if cutout_obj.kind == 'gerber':
|
||||
if isinstance(object_geo, MultiPolygon):
|
||||
x0, y0, x1, y1 = object_geo.bounds
|
||||
object_geo = box(x0, y0, x1, y1)
|
||||
if margin >= 0:
|
||||
geo_buf = object_geo.buffer(margin + abs(dia / 2))
|
||||
else:
|
||||
geo_buf = object_geo.buffer(margin - abs(dia / 2))
|
||||
if isinstance(cutout_obj.solid_geometry, list):
|
||||
cutout_obj.solid_geometry = MultiPolygon(cutout_obj.solid_geometry)
|
||||
|
||||
geo = geo_buf.exterior
|
||||
else:
|
||||
geo = object_geo
|
||||
|
||||
solid_geo, rest_geo = cutout_handler(geom=geo)
|
||||
if self.ui.gaptype_radio.get_value() == 'bt' and self.ui.thin_depth_entry.get_value() > 0:
|
||||
gaps_solid_geo = rest_geo
|
||||
else:
|
||||
try:
|
||||
__ = iter(object_geo)
|
||||
except TypeError:
|
||||
object_geo = [object_geo]
|
||||
|
||||
for geom_struct in object_geo:
|
||||
if cutout_obj.kind == 'gerber':
|
||||
if margin >= 0:
|
||||
geom_struct = (geom_struct.buffer(margin + abs(dia / 2))).exterior
|
||||
try:
|
||||
if convex_box:
|
||||
object_geo = cutout_obj.solid_geometry.convex_hull
|
||||
else:
|
||||
geom_struct_buff = geom_struct.buffer(-margin + abs(dia / 2))
|
||||
geom_struct = geom_struct_buff.interiors
|
||||
object_geo = cutout_obj.solid_geometry
|
||||
except Exception as err:
|
||||
log.debug("CutOut.on_freeform_cutout().geo_init() --> %s" % str(err))
|
||||
object_geo = cutout_obj.solid_geometry
|
||||
else:
|
||||
object_geo = cutout_obj.solid_geometry
|
||||
|
||||
c_geo, r_geo = cutout_handler(geom=geom_struct)
|
||||
solid_geo += c_geo
|
||||
if kind == 'single':
|
||||
object_geo = unary_union(object_geo)
|
||||
|
||||
# for geo in object_geo:
|
||||
if cutout_obj.kind == 'gerber':
|
||||
if isinstance(object_geo, MultiPolygon):
|
||||
x0, y0, x1, y1 = object_geo.bounds
|
||||
object_geo = box(x0, y0, x1, y1)
|
||||
if margin >= 0:
|
||||
geo_buf = object_geo.buffer(margin + abs(dia / 2))
|
||||
else:
|
||||
geo_buf = object_geo.buffer(margin - abs(dia / 2))
|
||||
|
||||
geo = geo_buf.exterior
|
||||
else:
|
||||
geo = object_geo
|
||||
|
||||
solid_geo, rest_geo = cutout_handler(geom=geo, gapsize=gapsize)
|
||||
if self.ui.gaptype_radio.get_value() == 'bt' and self.ui.thin_depth_entry.get_value() > 0:
|
||||
gaps_solid_geo += r_geo
|
||||
gaps_solid_geo = rest_geo
|
||||
if self.ui.gaptype_radio.get_value() == 'mb':
|
||||
mouse_bites_geo = rest_geo
|
||||
else:
|
||||
try:
|
||||
__ = iter(object_geo)
|
||||
except TypeError:
|
||||
object_geo = [object_geo]
|
||||
|
||||
if not solid_geo:
|
||||
app_obj.inform.emit('[ERROR_NOTCL] %s' % _("Failed."))
|
||||
return "fail"
|
||||
for geom_struct in object_geo:
|
||||
if cutout_obj.kind == 'gerber':
|
||||
if margin >= 0:
|
||||
geom_struct = (geom_struct.buffer(margin + abs(dia / 2))).exterior
|
||||
else:
|
||||
geom_struct_buff = geom_struct.buffer(-margin + abs(dia / 2))
|
||||
geom_struct = geom_struct_buff.interiors
|
||||
|
||||
solid_geo = linemerge(solid_geo)
|
||||
geo_obj.solid_geometry = deepcopy(solid_geo)
|
||||
c_geo, r_geo = cutout_handler(geom=geom_struct, gapsize=gapsize)
|
||||
solid_geo += c_geo
|
||||
if self.ui.gaptype_radio.get_value() == 'bt' and self.ui.thin_depth_entry.get_value() > 0:
|
||||
gaps_solid_geo += r_geo
|
||||
if self.ui.gaptype_radio.get_value() == 'mb':
|
||||
mouse_bites_geo += r_geo
|
||||
if not solid_geo:
|
||||
self.app.inform.emit('[ERROR_NOTCL] %s' % _("Failed."))
|
||||
return "fail"
|
||||
|
||||
xmin, ymin, xmax, ymax = CutOut.recursive_bounds(geo_obj.solid_geometry)
|
||||
geo_obj.options['xmin'] = xmin
|
||||
geo_obj.options['ymin'] = ymin
|
||||
geo_obj.options['xmax'] = xmax
|
||||
geo_obj.options['ymax'] = ymax
|
||||
geo_obj.options['cnctooldia'] = str(dia)
|
||||
geo_obj.options['cutz'] = self.ui.cutz_entry.get_value()
|
||||
geo_obj.options['multidepth'] = self.ui.mpass_cb.get_value()
|
||||
geo_obj.options['depthperpass'] = self.ui.maxdepth_entry.get_value()
|
||||
solid_geo = linemerge(solid_geo)
|
||||
|
||||
geo_obj.multigeo = True
|
||||
# list of Shapely Points to mark the drill points centers
|
||||
holes = []
|
||||
print(mouse_bites_geo)
|
||||
|
||||
geo_obj.tools.update({
|
||||
1: self.cut_tool_dict
|
||||
})
|
||||
geo_obj.tools[1]['tooldia'] = str(dia)
|
||||
geo_obj.tools[1]['solid_geometry'] = geo_obj.solid_geometry
|
||||
def geo_init(geo_obj, app_object):
|
||||
geo_obj.solid_geometry = deepcopy(solid_geo)
|
||||
|
||||
geo_obj.tools[1]['data']['name'] = outname
|
||||
geo_obj.tools[1]['data']['cutz'] = self.ui.cutz_entry.get_value()
|
||||
geo_obj.tools[1]['data']['multidepth'] = self.ui.mpass_cb.get_value()
|
||||
geo_obj.tools[1]['data']['depthperpass'] = self.ui.maxdepth_entry.get_value()
|
||||
xmin, ymin, xmax, ymax = CutOut.recursive_bounds(geo_obj.solid_geometry)
|
||||
geo_obj.options['xmin'] = xmin
|
||||
geo_obj.options['ymin'] = ymin
|
||||
geo_obj.options['xmax'] = xmax
|
||||
geo_obj.options['ymax'] = ymax
|
||||
geo_obj.options['cnctooldia'] = str(dia)
|
||||
geo_obj.options['cutz'] = self.ui.cutz_entry.get_value()
|
||||
geo_obj.options['multidepth'] = self.ui.mpass_cb.get_value()
|
||||
geo_obj.options['depthperpass'] = self.ui.maxdepth_entry.get_value()
|
||||
|
||||
if gaps_solid_geo is not None:
|
||||
geo_obj.tools.update({
|
||||
9999: self.cut_tool_dict
|
||||
})
|
||||
geo_obj.tools[9999]['tooldia'] = str(dia)
|
||||
geo_obj.tools[9999]['solid_geometry'] = gaps_solid_geo
|
||||
geo_obj.multigeo = True
|
||||
|
||||
geo_obj.tools[9999]['data']['name'] = outname
|
||||
geo_obj.tools[9999]['data']['cutz'] = self.ui.thin_depth_entry.get_value()
|
||||
geo_obj.tools[9999]['data']['multidepth'] = self.ui.mpass_cb.get_value()
|
||||
geo_obj.tools[9999]['data']['depthperpass'] = self.ui.maxdepth_entry.get_value()
|
||||
# plot this tool in a different color
|
||||
geo_obj.tools[9999]['data']['override_color'] = "#29a3a3fa"
|
||||
geo_obj.tools.update({
|
||||
1: self.cut_tool_dict
|
||||
})
|
||||
geo_obj.tools[1]['tooldia'] = str(dia)
|
||||
geo_obj.tools[1]['solid_geometry'] = geo_obj.solid_geometry
|
||||
|
||||
outname = cutout_obj.options["name"] + "_cutout"
|
||||
ret = self.app.app_obj.new_object('geometry', outname, geo_init)
|
||||
geo_obj.tools[1]['data']['name'] = outname
|
||||
geo_obj.tools[1]['data']['cutz'] = self.ui.cutz_entry.get_value()
|
||||
geo_obj.tools[1]['data']['multidepth'] = self.ui.mpass_cb.get_value()
|
||||
geo_obj.tools[1]['data']['depthperpass'] = self.ui.maxdepth_entry.get_value()
|
||||
|
||||
if ret == 'fail':
|
||||
self.app.inform.emit('[ERROR_NOTCL] %s' % _("Failed."))
|
||||
return
|
||||
if gaps_solid_geo:
|
||||
geo_obj.tools.update({
|
||||
9999: self.cut_tool_dict
|
||||
})
|
||||
geo_obj.tools[9999]['tooldia'] = str(dia)
|
||||
geo_obj.tools[9999]['solid_geometry'] = gaps_solid_geo
|
||||
|
||||
# cutout_obj.plot(plot_tool=1)
|
||||
self.app.inform.emit('[success] %s' % _("Any form CutOut operation finished."))
|
||||
# self.app.ui.notebook.setCurrentWidget(self.app.ui.project_tab)
|
||||
self.app.should_we_save = True
|
||||
geo_obj.tools[9999]['data']['name'] = outname
|
||||
geo_obj.tools[9999]['data']['cutz'] = self.ui.thin_depth_entry.get_value()
|
||||
geo_obj.tools[9999]['data']['multidepth'] = self.ui.mpass_cb.get_value()
|
||||
geo_obj.tools[9999]['data']['depthperpass'] = self.ui.maxdepth_entry.get_value()
|
||||
# plot this tool in a different color
|
||||
geo_obj.tools[9999]['data']['override_color'] = "#29a3a3fa"
|
||||
|
||||
def excellon_init(exc_obj, app_o):
|
||||
if not holes:
|
||||
return 'fail'
|
||||
mb_dia = self.ui.mb_dia_entry.get_value()
|
||||
|
||||
tools = {}
|
||||
tools[1] = {}
|
||||
tools[1]["tooldia"] = mb_dia
|
||||
tools[1]['drills'] = holes
|
||||
tools[1]['solid_geometry'] = []
|
||||
|
||||
exc_obj.tools = tools
|
||||
exc_obj.create_geometry()
|
||||
exc_obj.source_file = app_o.export_excellon(obj_name=exc_obj.options['name'], local_use=exc_obj,
|
||||
filename=None, use_thread=False)
|
||||
# calculate the bounds
|
||||
xmin, ymin, xmax, ymax = CutOut.recursive_bounds(exc_obj.solid_geometry)
|
||||
exc_obj.options['xmin'] = xmin
|
||||
exc_obj.options['ymin'] = ymin
|
||||
exc_obj.options['xmax'] = xmax
|
||||
exc_obj.options['ymax'] = ymax
|
||||
|
||||
try:
|
||||
ret = app_obj.app_obj.new_object('geometry', outname, geo_init)
|
||||
if ret == 'fail':
|
||||
app_obj.inform.emit('[ERROR_NOTCL] %s' % _("Failed."))
|
||||
return
|
||||
|
||||
if self.ui.gaptype_radio.get_value() == 'mb':
|
||||
ret = app_obj.app_obj.new_object('excellon', outname_exc, excellon_init)
|
||||
if ret == 'fail':
|
||||
app_obj.inform.emit('[ERROR_NOTCL] %s' % _("Mouse bites failed."))
|
||||
return
|
||||
|
||||
# cutout_obj.plot(plot_tool=1)
|
||||
app_obj.inform.emit('[success] %s' % _("Any form CutOut operation finished."))
|
||||
# self.app.ui.notebook.setCurrentWidget(self.app.ui.project_tab)
|
||||
app_obj.should_we_save = True
|
||||
except Exception as ee:
|
||||
log.debug(str(ee))
|
||||
|
||||
self.app.worker_task.emit({'fcn': job_thread, 'params': [self.app]})
|
||||
|
||||
def on_rectangular_cutout(self):
|
||||
log.debug("Cutout.on_rectangular_cutout() was launched ...")
|
||||
|
@ -875,7 +925,7 @@ class CutOut(AppTool):
|
|||
xmin - gapsize, # botleft_x
|
||||
py - gapsize + leny / 4, # botleft_y
|
||||
xmax + gapsize, # topright_x
|
||||
py + gapsize + leny / 4 # topright_y
|
||||
py + gapsize + leny / 4 # topright_y
|
||||
)
|
||||
geom = self.subtract_poly_from_geo(geom, points)
|
||||
points = (
|
||||
|
@ -1660,14 +1710,13 @@ class CutOut(AppTool):
|
|||
if second_geo.intersects(geo):
|
||||
results.append(second_geo.intersection(geo))
|
||||
|
||||
return CutOut.flatten(results)
|
||||
return CutOut.flatten(results)
|
||||
|
||||
def reset_fields(self):
|
||||
self.ui.obj_combo.setRootModelIndex(self.app.collection.index(0, 0, QtCore.QModelIndex()))
|
||||
|
||||
|
||||
class CutoutUI:
|
||||
|
||||
toolName = _("Cutout PCB")
|
||||
|
||||
def __init__(self, layout, app):
|
||||
|
@ -1898,9 +1947,9 @@ class CutoutUI:
|
|||
|
||||
self.gaptype_radio = RadioSet(
|
||||
[
|
||||
{'label': _('Bridge'), 'value': 'b'},
|
||||
{'label': _('Thin'), 'value': 'bt'},
|
||||
{'label': "M-Bites", 'value': 'mb'}
|
||||
{'label': _('Bridge'), 'value': 'b'},
|
||||
{'label': _('Thin'), 'value': 'bt'},
|
||||
{'label': "M-Bites", 'value': 'mb'}
|
||||
],
|
||||
stretch=True
|
||||
)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
from PyQt5 import QtWidgets, QtCore, QtGui
|
||||
|
||||
from appTool import AppTool
|
||||
from appGUI.GUIElements import RadioSet, FCDoubleSpinner, EvalEntry, FCEntry, FCButton, FCComboBox, FCCheckBox
|
||||
from appGUI.GUIElements import RadioSet, FCDoubleSpinner, FCButton, FCComboBox, NumericalEvalTupleEntry
|
||||
|
||||
from numpy import Inf
|
||||
|
||||
|
@ -156,27 +156,19 @@ class DblSidedTool(AppTool):
|
|||
try:
|
||||
px, py = self.ui.point_entry.get_value()
|
||||
except TypeError:
|
||||
self.app.inform.emit('[WARNING_NOTCL] %s' % _("'Point' reference is selected and 'Point' coordinates "
|
||||
"are missing. Add them and retry."))
|
||||
msg = '[WARNING_NOTCL] %s' % \
|
||||
_("'Point' reference is selected and 'Point' coordinates are missing. Add them and retry.")
|
||||
self.app.inform.emit(msg)
|
||||
return
|
||||
else:
|
||||
selection_index = self.ui.box_combo.currentIndex()
|
||||
model_index = self.app.collection.index(selection_index, 0, self.ui.gerber_object_combo.rootModelIndex())
|
||||
model_index = self.app.collection.index(selection_index, 0, self.ui.object_combo.rootModelIndex())
|
||||
try:
|
||||
bb_obj = model_index.internalPointer().obj
|
||||
except AttributeError:
|
||||
model_index = self.app.collection.index(selection_index, 0, self.ui.exc_object_combo.rootModelIndex())
|
||||
try:
|
||||
bb_obj = model_index.internalPointer().obj
|
||||
except AttributeError:
|
||||
model_index = self.app.collection.index(selection_index, 0,
|
||||
self.ui.geo_object_combo.rootModelIndex())
|
||||
try:
|
||||
bb_obj = model_index.internalPointer().obj
|
||||
except AttributeError:
|
||||
self.app.inform.emit(
|
||||
'[WARNING_NOTCL] %s' % _("There is no Box reference object loaded. Load one and retry."))
|
||||
return
|
||||
msg = '[WARNING_NOTCL] %s' % _("There is no Box reference object loaded. Load one and retry.")
|
||||
self.app.inform.emit(msg)
|
||||
return
|
||||
|
||||
xmin, ymin, xmax, ymax = bb_obj.bounds()
|
||||
px = 0.5 * (xmin + xmax)
|
||||
|
@ -184,10 +176,10 @@ class DblSidedTool(AppTool):
|
|||
|
||||
xscale, yscale = {"X": (1.0, -1.0), "Y": (-1.0, 1.0)}[axis]
|
||||
|
||||
dia = float(self.drill_dia.get_value())
|
||||
dia = self.ui.drill_dia.get_value()
|
||||
if dia == '':
|
||||
self.app.inform.emit('[WARNING_NOTCL] %s' %
|
||||
_("No value or wrong format in Drill Dia entry. Add it and retry."))
|
||||
msg = '[WARNING_NOTCL] %s' % _("No value or wrong format in Drill Dia entry. Add it and retry.")
|
||||
self.app.inform.emit(msg)
|
||||
return
|
||||
|
||||
tools = {}
|
||||
|
@ -198,8 +190,8 @@ class DblSidedTool(AppTool):
|
|||
# holes = self.alignment_holes.get_value()
|
||||
holes = eval('[{}]'.format(self.ui.alignment_holes.text()))
|
||||
if not holes:
|
||||
self.app.inform.emit('[WARNING_NOTCL] %s' % _("There are no Alignment Drill Coordinates to use. "
|
||||
"Add them and retry."))
|
||||
msg = '[WARNING_NOTCL] %s' % _("There are no Alignment Drill Coordinates to use. Add them and retry.")
|
||||
self.app.inform.emit(msg)
|
||||
return
|
||||
|
||||
for hole in holes:
|
||||
|
@ -629,7 +621,7 @@ class DsidedUI:
|
|||
grid0.addWidget(self.ymax_entry, 10, 1)
|
||||
|
||||
# Center point value
|
||||
self.center_entry = FCEntry()
|
||||
self.center_entry = NumericalEvalTupleEntry(border_color='#0069A9')
|
||||
self.center_entry.setPlaceholderText(_("Center point coordinates"))
|
||||
|
||||
self.center_btn = FCButton('%s:' % _("Centroid"))
|
||||
|
@ -714,7 +706,7 @@ class DsidedUI:
|
|||
grid1.addWidget(self.axis_location, 4, 1, 1, 2)
|
||||
|
||||
# ## Point/Box
|
||||
self.point_entry = EvalEntry()
|
||||
self.point_entry = NumericalEvalTupleEntry(border_color='#0069A9')
|
||||
self.point_entry.setPlaceholderText(_("Point coordinates"))
|
||||
|
||||
# Add a reference
|
||||
|
@ -876,7 +868,7 @@ class DsidedUI:
|
|||
"It can be modified in the Mirror Parameters -> Reference section")
|
||||
)
|
||||
|
||||
self.align_ref_label_val = EvalEntry()
|
||||
self.align_ref_label_val = NumericalEvalTupleEntry(border_color='#0069A9')
|
||||
self.align_ref_label_val.setToolTip(
|
||||
_("The reference point used to create the second alignment drill\n"
|
||||
"from the first alignment drill, by doing mirror.\n"
|
||||
|
@ -900,7 +892,7 @@ class DsidedUI:
|
|||
"- one drill in mirror position over the axis selected above in the 'Align Axis'.")
|
||||
)
|
||||
|
||||
self.alignment_holes = EvalEntry()
|
||||
self.alignment_holes = NumericalEvalTupleEntry(border_color='#0069A9')
|
||||
self.alignment_holes.setPlaceholderText(_("Drill coordinates"))
|
||||
|
||||
grid5.addWidget(self.ah_label, 0, 0, 1, 2)
|
||||
|
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue