- fixed a bug in Tools Database: due of not disconnecting the signals it created a race that was concluded into a RuntimeError exception (an dict changed size during iteration)
- Drilling Tool - working in adding tools auto-load from Tools DB - some updates to the Excellon Object options - Drilling Tool - manual add from Tools DB is working
This commit is contained in:
parent
f9e7c90407
commit
22d05935e8
|
@ -7,6 +7,13 @@ CHANGELOG for FlatCAM beta
|
|||
|
||||
=================================================
|
||||
|
||||
13.07.2020
|
||||
|
||||
- fixed a bug in Tools Database: due of not disconnecting the signals it created a race that was concluded into a RuntimeError exception (an dict changed size during iteration)
|
||||
- Drilling Tool - working in adding tools auto-load from Tools DB
|
||||
- some updates to the Excellon Object options
|
||||
- Drilling Tool - manual add from Tools DB is working
|
||||
|
||||
12.07.2020
|
||||
|
||||
- when creating a new FlatCAM object, the options will be updated with FlatCAM tools properties that relate to them
|
||||
|
|
|
@ -1146,6 +1146,43 @@ class ToolsDB2UI:
|
|||
self.grid_tool.addWidget(self.tool_object_label, 2, 0)
|
||||
self.grid_tool.addWidget(self.object_type_combo, 2, 1)
|
||||
|
||||
# Tool Tolerance
|
||||
self.tol_label = QtWidgets.QLabel("<b>%s:</b>" % _("Tolerance"))
|
||||
self.tol_label.setToolTip(
|
||||
_("Tool tolerance. If there is a tool in the Excellon object with\n"
|
||||
"the value within the limits then this tool from DB will be used.\n"
|
||||
"This behavior is enabled in the Drilling Tool.")
|
||||
)
|
||||
self.grid_tool.addWidget(self.tol_label, 4, 0, 1, 2)
|
||||
|
||||
# Tolerance Min Limit
|
||||
self.min_limit_label = QtWidgets.QLabel('%s:' % _("Min"))
|
||||
self.min_limit_label.setToolTip(
|
||||
_("Set the tool tolerance minimum.")
|
||||
)
|
||||
self.tol_min_entry = FCDoubleSpinner(callback=self.confirmation_message)
|
||||
self.tol_min_entry.set_precision(self.decimals)
|
||||
self.tol_min_entry.set_range(0, 9999.9999)
|
||||
self.tol_min_entry.setSingleStep(0.1)
|
||||
self.tol_min_entry.setObjectName("gdb_tol_min")
|
||||
|
||||
self.grid_tool.addWidget(self.min_limit_label, 6, 0)
|
||||
self.grid_tool.addWidget(self.tol_min_entry, 6, 1)
|
||||
|
||||
# Tolerance Min Limit
|
||||
self.max_limit_label = QtWidgets.QLabel('%s:' % _("Max"))
|
||||
self.max_limit_label.setToolTip(
|
||||
_("Set the tool tolerance maximum.")
|
||||
)
|
||||
self.tol_max_entry = FCDoubleSpinner(callback=self.confirmation_message)
|
||||
self.tol_max_entry.set_precision(self.decimals)
|
||||
self.tol_max_entry.set_range(0, 9999.9999)
|
||||
self.tol_max_entry.setSingleStep(0.1)
|
||||
self.tol_max_entry.setObjectName("gdb_tol_max")
|
||||
|
||||
self.grid_tool.addWidget(self.max_limit_label, 7, 0)
|
||||
self.grid_tool.addWidget(self.tol_max_entry, 7, 1)
|
||||
|
||||
# ###########################################################################
|
||||
# ############### BASIC GEOMETRY UI form ####################################
|
||||
# ###########################################################################
|
||||
|
@ -1872,10 +1909,6 @@ class ToolsDB2UI:
|
|||
self.grid5.addWidget(self.feedrate_rapid_label, 16, 0)
|
||||
self.grid5.addWidget(self.feedrate_rapid_entry, 16, 1)
|
||||
|
||||
# default values is to hide
|
||||
self.feedrate_rapid_label.hide()
|
||||
self.feedrate_rapid_entry.hide()
|
||||
|
||||
# Spindlespeed
|
||||
self.spindle_label = QtWidgets.QLabel('%s:' % _('Spindle speed'))
|
||||
self.spindle_label.setToolTip(
|
||||
|
@ -2117,6 +2150,8 @@ class ToolsDB2(QtWidgets.QWidget):
|
|||
|
||||
self.form_fields = {
|
||||
"object_type": self.ui.object_type_combo,
|
||||
"tol_min": self.ui.tol_min_entry,
|
||||
"tol_max": self.ui.tol_max_entry,
|
||||
# Basic
|
||||
"name": self.ui.name_entry,
|
||||
"tooldia": self.ui.dia_entry,
|
||||
|
@ -2187,6 +2222,8 @@ class ToolsDB2(QtWidgets.QWidget):
|
|||
|
||||
self.name2option = {
|
||||
"gdb_object_type": "object_type",
|
||||
"gdb_tol_min": "tol_min",
|
||||
"gdb_tol_max": "tol_max",
|
||||
|
||||
# Basic
|
||||
"gdb_name": "name",
|
||||
|
@ -2319,8 +2356,10 @@ class ToolsDB2(QtWidgets.QWidget):
|
|||
self.on_tool_requested_from_app()
|
||||
|
||||
def on_list_selection_change(self, current, previous):
|
||||
self.ui_disconnect()
|
||||
self.current_toolid = int(current.text(0))
|
||||
self.storage_to_form(self.db_tool_dict[current.text(0)])
|
||||
self.ui_connect()
|
||||
|
||||
def on_list_item_edited(self, item, column):
|
||||
if column == 0:
|
||||
|
@ -2504,6 +2543,8 @@ class ToolsDB2(QtWidgets.QWidget):
|
|||
"endz": float(self.app.defaults["geometry_endz"]),
|
||||
|
||||
"object_type": _("General"),
|
||||
"tol_min": 0.0,
|
||||
"tol_max": 0.0,
|
||||
|
||||
# NCC
|
||||
"tools_nccoperation": self.app.defaults["tools_nccoperation"],
|
||||
|
@ -2750,7 +2791,7 @@ class ToolsDB2(QtWidgets.QWidget):
|
|||
for idx in range(self.app_ui.plot_tab_area.count()):
|
||||
if self.app_ui.plot_tab_area.tabText(idx) == _("Tools Database"):
|
||||
self.app_ui.plot_tab_area.tabBar.setTabTextColor(idx, QtGui.QColor('black'))
|
||||
self.save_db_btn.setStyleSheet("")
|
||||
self.ui.save_db_btn.setStyleSheet("")
|
||||
|
||||
# Save Tools DB in a file
|
||||
try:
|
||||
|
@ -2927,6 +2968,11 @@ class ToolsDB2(QtWidgets.QWidget):
|
|||
else:
|
||||
if wdg_name == "gdb_object_type":
|
||||
self.db_tool_dict[tool_id]['data']['object_type'] = val
|
||||
elif wdg_name == "gdb_tol_min":
|
||||
self.db_tool_dict[tool_id]['data']['tol_min'] = val
|
||||
elif wdg_name == "gdb_tol_max":
|
||||
self.db_tool_dict[tool_id]['data']['tol_max'] = val
|
||||
|
||||
elif wdg_name == "gdb_cutz":
|
||||
self.db_tool_dict[tool_id]['data']['cutz'] = val
|
||||
elif wdg_name == "gdb_multidepth":
|
||||
|
@ -3002,6 +3048,36 @@ class ToolsDB2(QtWidgets.QWidget):
|
|||
elif wdg_name == "gdb_i_iso_type":
|
||||
self.db_tool_dict[tool_id]['data']['tools_iso_isotype'] = val
|
||||
|
||||
# Drilling Tool
|
||||
elif wdg_name == "gdb_e_cutz":
|
||||
self.db_tool_dict[tool_id]['data']['tools_drill_cutz'] = val
|
||||
elif wdg_name == "gdb_e_multidepth":
|
||||
self.db_tool_dict[tool_id]['data']['tools_drill_multidepth'] = val
|
||||
elif wdg_name == "gdb_e_depthperpass":
|
||||
self.db_tool_dict[tool_id]['data']['tools_drill_depthperpass'] = val
|
||||
elif wdg_name == "gdb_e_travelz":
|
||||
self.db_tool_dict[tool_id]['data']['tools_drill_travelz'] = val
|
||||
|
||||
elif wdg_name == "gdb_e_feedratez":
|
||||
self.db_tool_dict[tool_id]['data']['tools_drill_feedrate_z'] = val
|
||||
elif wdg_name == "gdb_e_fr_rapid":
|
||||
self.db_tool_dict[tool_id]['data']['tools_drill_feedrate_rapid'] = val
|
||||
elif wdg_name == "gdb_e_spindlespeed":
|
||||
self.db_tool_dict[tool_id]['data']['tools_drill_spindlespeed'] = val
|
||||
elif wdg_name == "gdb_e_dwell":
|
||||
self.db_tool_dict[tool_id]['data']['tools_drill_dwell'] = val
|
||||
elif wdg_name == "gdb_e_dwelltime":
|
||||
self.db_tool_dict[tool_id]['data']['tools_drill_dwelltime'] = val
|
||||
|
||||
elif wdg_name == "gdb_e_offset":
|
||||
self.db_tool_dict[tool_id]['data']['tools_drill_offset'] = val
|
||||
elif wdg_name == "gdb_e_drill_slots":
|
||||
self.db_tool_dict[tool_id]['data']['tools_drill_drill_slots'] = val
|
||||
elif wdg_name == "gdb_e_drill_slots_over":
|
||||
self.db_tool_dict[tool_id]['data']['tools_drill_drill_overlap'] = val
|
||||
elif wdg_name == "gdb_e_drill_last_drill":
|
||||
self.db_tool_dict[tool_id]['data']['tools_drill_last_drill'] = val
|
||||
|
||||
self.callback_app()
|
||||
|
||||
def on_tool_requested_from_app(self):
|
||||
|
|
|
@ -98,12 +98,26 @@ class GeneralAppSettingsGroupUI(OptionsGroupUI2):
|
|||
self.workspace_type_label = self.option_dict()["global_workspaceT"].label_widget
|
||||
self.workspace_orientation_field = self.option_dict()["global_workspace_orientation"].get_field()
|
||||
self.workspace_orientation_label = self.option_dict()["global_workspace_orientation"].label_widget
|
||||
self.wks = OptionalInputSection(self.workspace_enabled_field, [self.workspace_type_label, self.workspace_type_field, self.workspace_orientation_label, self.workspace_orientation_field])
|
||||
self.wks = OptionalInputSection(
|
||||
self.workspace_enabled_field,
|
||||
[
|
||||
self.workspace_type_label,
|
||||
self.workspace_type_field,
|
||||
self.workspace_orientation_label,
|
||||
self.workspace_orientation_field
|
||||
]
|
||||
)
|
||||
|
||||
self.mouse_cursor_color_enabled_field = self.option_dict()["global_cursor_color_enabled"].get_field()
|
||||
self.mouse_cursor_color_field = self.option_dict()["global_cursor_color"].get_field()
|
||||
self.mouse_cursor_color_label = self.option_dict()["global_cursor_color"].label_widget
|
||||
self.mois = OptionalInputSection(self.mouse_cursor_color_enabled_field, [self.mouse_cursor_color_label, self.mouse_cursor_color_field])
|
||||
self.mois = OptionalInputSection(
|
||||
self.mouse_cursor_color_enabled_field,
|
||||
[
|
||||
self.mouse_cursor_color_label,
|
||||
self.mouse_cursor_color_field
|
||||
]
|
||||
)
|
||||
self.mouse_cursor_color_enabled_field.stateChanged.connect(self.on_mouse_cursor_color_enable)
|
||||
self.mouse_cursor_color_field.entry.editingFinished.connect(self.on_mouse_cursor_entry)
|
||||
|
||||
|
|
|
@ -53,39 +53,22 @@ class ExcellonObject(FlatCAMObj, Excellon):
|
|||
"plot": True,
|
||||
"solid": False,
|
||||
"multicolored": False,
|
||||
"merge_fuse_tools": True,
|
||||
|
||||
"operation": "drill",
|
||||
"milling_type": "drills",
|
||||
|
||||
"milling_dia": 0.04,
|
||||
|
||||
"cutz": -0.1,
|
||||
"multidepth": False,
|
||||
"depthperpass": 0.7,
|
||||
"travelz": 0.1,
|
||||
"feedrate": self.app.defaults["geometry_feedrate"],
|
||||
"feedrate_z": 5.0,
|
||||
"feedrate_rapid": 5.0,
|
||||
"tooldia": 0.1,
|
||||
"milling_dia": 0.04,
|
||||
"slot_tooldia": 0.1,
|
||||
"toolchange": False,
|
||||
"toolchangez": 1.0,
|
||||
"toolchangexy": "0.0, 0.0",
|
||||
"extracut": self.app.defaults["geometry_extracut"],
|
||||
"extracut_length": self.app.defaults["geometry_extracut_length"],
|
||||
"endz": 2.0,
|
||||
"endxy": '',
|
||||
|
||||
"startz": None,
|
||||
"offset": 0.0,
|
||||
"spindlespeed": 0,
|
||||
"dwell": True,
|
||||
"dwelltime": 1000,
|
||||
"ppname_e": 'default',
|
||||
"ppname_g": self.app.defaults["geometry_ppname_g"],
|
||||
"z_pdepth": -0.02,
|
||||
"feedrate_probe": 3.0,
|
||||
"format_upper_in": 2,
|
||||
"format_lower_in": 4,
|
||||
"format_upper_mm": 3,
|
||||
"lower_mm": 3,
|
||||
"zeros": "T",
|
||||
"units": "INCH",
|
||||
"update": True,
|
||||
|
||||
"optimization_type": "B",
|
||||
"search_time": 3
|
||||
})
|
||||
|
||||
# TODO: Document this.
|
||||
|
@ -99,14 +82,6 @@ class ExcellonObject(FlatCAMObj, Excellon):
|
|||
# default set of data to be added to each tool in self.tools as self.tools[tool]['data'] = self.default_data
|
||||
self.default_data = {}
|
||||
|
||||
# fill in self.default_data values from self.options
|
||||
for opt_key, opt_val in self.app.options.items():
|
||||
if opt_key.find('excellon_') == 0:
|
||||
self.default_data[opt_key] = deepcopy(opt_val)
|
||||
for opt_key, opt_val in self.app.options.items():
|
||||
if opt_key.find('geometry_') == 0:
|
||||
self.default_data[opt_key] = deepcopy(opt_val)
|
||||
|
||||
# variable to store the total amount of drills per job
|
||||
self.tot_drill_cnt = 0
|
||||
self.tool_row = 0
|
||||
|
@ -133,99 +108,6 @@ class ExcellonObject(FlatCAMObj, Excellon):
|
|||
# from predecessors.
|
||||
self.ser_attrs += ['options', 'kind', 'fill_color', 'outline_color', 'alpha_level']
|
||||
|
||||
@staticmethod
|
||||
def merge(exc_list, exc_final, decimals=None, fuse_tools=True):
|
||||
"""
|
||||
Merge Excellon objects found in exc_list parameter into exc_final object.
|
||||
Options are always copied from source .
|
||||
|
||||
Tools are disregarded, what is taken in consideration is the unique drill diameters found as values in the
|
||||
exc_list tools dict's. In the reconstruction section for each unique tool diameter it will be created a
|
||||
tool_name to be used in the final Excellon object, exc_final.
|
||||
|
||||
If only one object is in exc_list parameter then this function will copy that object in the exc_final
|
||||
|
||||
:param exc_list: List or one object of ExcellonObject Objects to join.
|
||||
:type exc_list: list
|
||||
:param exc_final: Destination ExcellonObject object.
|
||||
:type exc_final: class
|
||||
:param decimals: The number of decimals to be used for diameters
|
||||
:type decimals: int
|
||||
:param fuse_tools: If True will try to fuse tools of the same diameter for the Excellon objects
|
||||
:type fuse_tools: bool
|
||||
:return: None
|
||||
"""
|
||||
|
||||
if exc_final.tools is None:
|
||||
exc_final.tools = {}
|
||||
|
||||
if decimals is None:
|
||||
decimals = 4
|
||||
decimals_exc = decimals
|
||||
|
||||
try:
|
||||
flattened_list = list(itertools.chain(*exc_list))
|
||||
except TypeError:
|
||||
flattened_list = exc_list
|
||||
|
||||
new_tools = {}
|
||||
total_geo = []
|
||||
toolid = 0
|
||||
for exc in flattened_list:
|
||||
# copy options of the current excellon obj to the final excellon obj
|
||||
# only the last object options will survive
|
||||
for option in exc.options:
|
||||
if option != 'name':
|
||||
try:
|
||||
exc_final.options[option] = exc.options[option]
|
||||
except Exception:
|
||||
exc.app.log.warning("Failed to copy option.", option)
|
||||
|
||||
for tool in exc.tools:
|
||||
toolid += 1
|
||||
new_tools[toolid] = exc.tools[tool]
|
||||
|
||||
exc_final.tools = deepcopy(new_tools)
|
||||
# add the zeros and units to the exc_final object
|
||||
exc_final.zeros = exc.zeros
|
||||
exc_final.units = exc.units
|
||||
total_geo += exc.solid_geometry
|
||||
|
||||
exc_final.solid_geometry = total_geo
|
||||
|
||||
fused_tools_dict = {}
|
||||
if exc_final.tools and fuse_tools:
|
||||
toolid = 0
|
||||
for tool, tool_dict in exc_final.tools.items():
|
||||
current_tooldia = float('%.*f' % (decimals_exc, tool_dict['tooldia']))
|
||||
toolid += 1
|
||||
|
||||
# calculate all diameters in fused_tools_dict
|
||||
all_dia = []
|
||||
if fused_tools_dict:
|
||||
for f_tool in fused_tools_dict:
|
||||
all_dia.append(float('%.*f' % (decimals_exc, fused_tools_dict[f_tool]['tooldia'])))
|
||||
|
||||
if current_tooldia in all_dia:
|
||||
# find tool for current_tooldia in fuse_tools
|
||||
t = None
|
||||
for f_tool in fused_tools_dict:
|
||||
if fused_tools_dict[f_tool]['tooldia'] == current_tooldia:
|
||||
t = f_tool
|
||||
break
|
||||
if t:
|
||||
fused_tools_dict[t]['drills'] += tool_dict['drills']
|
||||
fused_tools_dict[t]['slots'] += tool_dict['slots']
|
||||
fused_tools_dict[t]['solid_geometry'] += tool_dict['solid_geometry']
|
||||
else:
|
||||
fused_tools_dict[toolid] = tool_dict
|
||||
fused_tools_dict[toolid]['tooldia'] = current_tooldia
|
||||
|
||||
exc_final.tools = fused_tools_dict
|
||||
|
||||
# create the geometry for the exc_final object
|
||||
exc_final.create_geometry()
|
||||
|
||||
def set_ui(self, ui):
|
||||
"""
|
||||
Configures the user interface for this object.
|
||||
|
@ -246,6 +128,11 @@ class ExcellonObject(FlatCAMObj, Excellon):
|
|||
if opt_key.find('tools_drill_') == 0:
|
||||
self.options[opt_key] = deepcopy(opt_val)
|
||||
|
||||
# fill in self.default_data values from self.options
|
||||
for opt_key, opt_val in self.app.options.items():
|
||||
if opt_key.find('excellon_') == 0 or opt_key.find('tools_drill_') == 0:
|
||||
self.default_data[opt_key] = deepcopy(opt_val)
|
||||
|
||||
self.form_fields.update({
|
||||
"plot": self.ui.plot_cb,
|
||||
"solid": self.ui.solid_cb,
|
||||
|
@ -1310,3 +1197,96 @@ class ExcellonObject(FlatCAMObj, Excellon):
|
|||
self.shapes.redraw()
|
||||
except (ObjectDeleted, AttributeError):
|
||||
self.shapes.clear(update=True)
|
||||
|
||||
@staticmethod
|
||||
def merge(exc_list, exc_final, decimals=None, fuse_tools=True):
|
||||
"""
|
||||
Merge Excellon objects found in exc_list parameter into exc_final object.
|
||||
Options are always copied from source .
|
||||
|
||||
Tools are disregarded, what is taken in consideration is the unique drill diameters found as values in the
|
||||
exc_list tools dict's. In the reconstruction section for each unique tool diameter it will be created a
|
||||
tool_name to be used in the final Excellon object, exc_final.
|
||||
|
||||
If only one object is in exc_list parameter then this function will copy that object in the exc_final
|
||||
|
||||
:param exc_list: List or one object of ExcellonObject Objects to join.
|
||||
:type exc_list: list
|
||||
:param exc_final: Destination ExcellonObject object.
|
||||
:type exc_final: class
|
||||
:param decimals: The number of decimals to be used for diameters
|
||||
:type decimals: int
|
||||
:param fuse_tools: If True will try to fuse tools of the same diameter for the Excellon objects
|
||||
:type fuse_tools: bool
|
||||
:return: None
|
||||
"""
|
||||
|
||||
if exc_final.tools is None:
|
||||
exc_final.tools = {}
|
||||
|
||||
if decimals is None:
|
||||
decimals = 4
|
||||
decimals_exc = decimals
|
||||
|
||||
try:
|
||||
flattened_list = list(itertools.chain(*exc_list))
|
||||
except TypeError:
|
||||
flattened_list = exc_list
|
||||
|
||||
new_tools = {}
|
||||
total_geo = []
|
||||
toolid = 0
|
||||
for exc in flattened_list:
|
||||
# copy options of the current excellon obj to the final excellon obj
|
||||
# only the last object options will survive
|
||||
for option in exc.options:
|
||||
if option != 'name':
|
||||
try:
|
||||
exc_final.options[option] = exc.options[option]
|
||||
except Exception:
|
||||
exc.app.log.warning("Failed to copy option.", option)
|
||||
|
||||
for tool in exc.tools:
|
||||
toolid += 1
|
||||
new_tools[toolid] = exc.tools[tool]
|
||||
|
||||
exc_final.tools = deepcopy(new_tools)
|
||||
# add the zeros and units to the exc_final object
|
||||
exc_final.zeros = exc.zeros
|
||||
exc_final.units = exc.units
|
||||
total_geo += exc.solid_geometry
|
||||
|
||||
exc_final.solid_geometry = total_geo
|
||||
|
||||
fused_tools_dict = {}
|
||||
if exc_final.tools and fuse_tools:
|
||||
toolid = 0
|
||||
for tool, tool_dict in exc_final.tools.items():
|
||||
current_tooldia = float('%.*f' % (decimals_exc, tool_dict['tooldia']))
|
||||
toolid += 1
|
||||
|
||||
# calculate all diameters in fused_tools_dict
|
||||
all_dia = []
|
||||
if fused_tools_dict:
|
||||
for f_tool in fused_tools_dict:
|
||||
all_dia.append(float('%.*f' % (decimals_exc, fused_tools_dict[f_tool]['tooldia'])))
|
||||
|
||||
if current_tooldia in all_dia:
|
||||
# find tool for current_tooldia in fuse_tools
|
||||
t = None
|
||||
for f_tool in fused_tools_dict:
|
||||
if fused_tools_dict[f_tool]['tooldia'] == current_tooldia:
|
||||
t = f_tool
|
||||
break
|
||||
if t:
|
||||
fused_tools_dict[t]['drills'] += tool_dict['drills']
|
||||
fused_tools_dict[t]['slots'] += tool_dict['slots']
|
||||
fused_tools_dict[t]['solid_geometry'] += tool_dict['solid_geometry']
|
||||
else:
|
||||
fused_tools_dict[toolid] = tool_dict
|
||||
fused_tools_dict[toolid]['tooldia'] = current_tooldia
|
||||
|
||||
exc_final.tools = fused_tools_dict
|
||||
|
||||
# create the geometry for the exc_final object
|
||||
exc_final.create_geometry()
|
||||
|
|
|
@ -16,7 +16,10 @@ from copy import deepcopy
|
|||
|
||||
import numpy as np
|
||||
|
||||
from shapely.geometry import Point, LineString
|
||||
from shapely.geometry import LineString
|
||||
|
||||
import json
|
||||
import sys
|
||||
|
||||
from matplotlib.backend_bases import KeyEvent as mpl_key_event
|
||||
|
||||
|
@ -122,42 +125,45 @@ class ToolDrilling(AppTool, Excellon):
|
|||
self.area_sel_disconnect_flag = False
|
||||
self.poly_sel_disconnect_flag = False
|
||||
|
||||
# Tools Database
|
||||
self.tools_db_dict = None
|
||||
|
||||
self.form_fields = {
|
||||
"cutz": self.t_ui.cutz_entry,
|
||||
"multidepth": self.t_ui.mpass_cb,
|
||||
"depthperpass": self.t_ui.maxdepth_entry,
|
||||
"travelz": self.t_ui.travelz_entry,
|
||||
"feedrate_z": self.t_ui.feedrate_z_entry,
|
||||
"feedrate_rapid": self.t_ui.feedrate_rapid_entry,
|
||||
"tools_drill_cutz": self.t_ui.cutz_entry,
|
||||
"tools_drill_multidepth": self.t_ui.mpass_cb,
|
||||
"tools_drill_depthperpass": self.t_ui.maxdepth_entry,
|
||||
"tools_drill_travelz": self.t_ui.travelz_entry,
|
||||
"tools_drill_feedrate_z": self.t_ui.feedrate_z_entry,
|
||||
"tools_drill_feedrate_rapid": self.t_ui.feedrate_rapid_entry,
|
||||
|
||||
"spindlespeed": self.t_ui.spindlespeed_entry,
|
||||
"dwell": self.t_ui.dwell_cb,
|
||||
"dwelltime": self.t_ui.dwelltime_entry,
|
||||
"tools_drill_spindlespeed": self.t_ui.spindlespeed_entry,
|
||||
"tools_drill_dwell": self.t_ui.dwell_cb,
|
||||
"tools_drill_dwelltime": self.t_ui.dwelltime_entry,
|
||||
|
||||
"offset": self.t_ui.offset_entry,
|
||||
"tools_drill_offset": self.t_ui.offset_entry,
|
||||
|
||||
"drill_slots": self.t_ui.drill_slots_cb,
|
||||
"drill_overlap": self.t_ui.drill_overlap_entry,
|
||||
"last_drill": self.t_ui.last_drill_cb
|
||||
"tools_drill_drill_slots": self.t_ui.drill_slots_cb,
|
||||
"tools_drill_drill_overlap": self.t_ui.drill_overlap_entry,
|
||||
"tools_drill_last_drill": self.t_ui.last_drill_cb
|
||||
}
|
||||
|
||||
self.name2option = {
|
||||
"e_cutz": "cutz",
|
||||
"e_multidepth": "multidepth",
|
||||
"e_depthperpass": "depthperpass",
|
||||
"e_travelz": "travelz",
|
||||
"e_feedratez": "feedrate_z",
|
||||
"e_fr_rapid": "feedrate_rapid",
|
||||
"e_cutz": "tools_drill_cutz",
|
||||
"e_multidepth": "tools_drill_multidepth",
|
||||
"e_depthperpass": "tools_drill_depthperpass",
|
||||
"e_travelz": "tools_drill_travelz",
|
||||
"e_feedratez": "tools_drill_feedrate_z",
|
||||
"e_fr_rapid": "tools_drill_feedrate_rapid",
|
||||
|
||||
"e_spindlespeed": "spindlespeed",
|
||||
"e_dwell": "dwell",
|
||||
"e_dwelltime": "dwelltime",
|
||||
"e_spindlespeed": "tools_drill_spindlespeed",
|
||||
"e_dwell": "tools_drill_dwell",
|
||||
"e_dwelltime": "tools_drill_dwelltime",
|
||||
|
||||
"e_offset": "offset",
|
||||
"e_offset": "tools_drill_offset",
|
||||
|
||||
"e_drill_slots": "drill_slots",
|
||||
"e_drill_slots_overlap": "drill_overlap",
|
||||
"e_drill_last_drill": "last_drill",
|
||||
"e_drill_slots": "tools_drill_drill_slots",
|
||||
"e_drill_slots_overlap": "tools_drill_drill_overlap",
|
||||
"e_drill_last_drill": "tools_drill_last_drill",
|
||||
}
|
||||
|
||||
self.poly_drawn = False
|
||||
|
@ -205,6 +211,8 @@ class ToolDrilling(AppTool, Excellon):
|
|||
# ############################ SIGNALS ########################################
|
||||
# #############################################################################
|
||||
|
||||
self.t_ui.manual_load_db_btn.clicked.connect(self.on_tool_db_load)
|
||||
|
||||
self.t_ui.apply_param_to_all.clicked.connect(self.on_apply_param_to_all_clicked)
|
||||
self.t_ui.generate_cnc_button.clicked.connect(self.on_cnc_button_click)
|
||||
self.t_ui.tools_table.drag_drop_sig.connect(self.rebuild_ui)
|
||||
|
@ -344,7 +352,7 @@ class ToolDrilling(AppTool, Excellon):
|
|||
|
||||
# fill in self.default_data values from self.options
|
||||
for opt_key, opt_val in self.app.options.items():
|
||||
if opt_key.find('excellon_') == 0:
|
||||
if opt_key.find('excellon_') == 0 or opt_key.find('tools_drill_') == 0:
|
||||
self.default_data[opt_key] = deepcopy(opt_val)
|
||||
|
||||
self.first_click = False
|
||||
|
@ -403,6 +411,7 @@ class ToolDrilling(AppTool, Excellon):
|
|||
self.t_ui.drill_overlap_label.hide()
|
||||
self.t_ui.drill_overlap_entry.hide()
|
||||
self.t_ui.last_drill_cb.hide()
|
||||
|
||||
# if the app mode is Basic then disable this feature
|
||||
if app_mode == 'b':
|
||||
self.t_ui.drill_slots_cb.set_value(False)
|
||||
|
@ -697,12 +706,16 @@ class ToolDrilling(AppTool, Excellon):
|
|||
self.t_ui.exc_param_frame.setDisabled(True)
|
||||
self.set_tool_ui()
|
||||
else:
|
||||
self.excellon_tools = self.excellon_obj.tools
|
||||
self.app.collection.set_active(self.obj_name)
|
||||
self.t_ui.exc_param_frame.setDisabled(False)
|
||||
self.excellon_tools = self.excellon_obj.tools
|
||||
|
||||
self.build_tool_ui()
|
||||
if self.t_ui.autoload_db_cb.get_value():
|
||||
self.excellon_tools = self.excellon_obj.tools
|
||||
self.on_tool_db_load()
|
||||
else:
|
||||
# self.on_tool_db_load() already build once the tool UI, no need to do it twice
|
||||
self.excellon_tools = self.excellon_obj.tools
|
||||
self.build_tool_ui()
|
||||
|
||||
sel_rows = set()
|
||||
table_items = self.t_ui.tools_table.selectedItems()
|
||||
|
@ -795,6 +808,71 @@ class ToolDrilling(AppTool, Excellon):
|
|||
except (TypeError, ValueError):
|
||||
pass
|
||||
|
||||
def on_tool_db_load(self):
|
||||
|
||||
filename = self.app.data_path + '\\geo_tools_db.FlatDB'
|
||||
|
||||
# load the database tools from the file
|
||||
try:
|
||||
with open(filename) as f:
|
||||
tools = f.read()
|
||||
except IOError:
|
||||
self.app.log.error("Could not load tools DB file.")
|
||||
self.app.inform.emit('[ERROR] %s' % _("Could not load Tools DB file."))
|
||||
return
|
||||
|
||||
try:
|
||||
self.tools_db_dict = json.loads(tools)
|
||||
except Exception:
|
||||
e = sys.exc_info()[0]
|
||||
self.app.log.error(str(e))
|
||||
self.app.inform.emit('[ERROR] %s' % _("Failed to parse Tools DB file."))
|
||||
return
|
||||
|
||||
self.replace_tools()
|
||||
|
||||
def replace_tools(self):
|
||||
log.debug("ToolDrilling.replace_tools()")
|
||||
|
||||
if self.excellon_obj:
|
||||
new_tools_dict = deepcopy(self.excellon_tools)
|
||||
|
||||
for orig_tool, orig_tool_val in self.excellon_tools.items():
|
||||
orig_tooldia = orig_tool_val['tooldia']
|
||||
|
||||
# look in database tools
|
||||
for db_tool, db_tool_val in self.tools_db_dict.items():
|
||||
db_tooldia = db_tool_val['tooldia']
|
||||
low_limit = float(db_tool_val['data']['tol_min'])
|
||||
high_limit = float(db_tool_val['data']['tol_max'])
|
||||
|
||||
# if we find a tool with the same diameter in the Tools DB just update it's data
|
||||
if orig_tooldia == db_tooldia:
|
||||
for d in db_tool_val['data']:
|
||||
if d.find('tools_drill') == 0:
|
||||
new_tools_dict[orig_tool]['data'][d] = db_tool_val['data'][d]
|
||||
elif d.find('tools_') == 0:
|
||||
# don't need data for other App Tools; this tests after 'tools_drill_'
|
||||
continue
|
||||
else:
|
||||
new_tools_dict[orig_tool]['data'][d] = db_tool_val['data'][d]
|
||||
# search for a tool that has a tolerance that the tool fits in
|
||||
elif high_limit >= orig_tooldia >= low_limit:
|
||||
new_tools_dict[orig_tool]['tooldia'] = db_tooldia
|
||||
for d in db_tool_val['data']:
|
||||
if d.find('tools_drill') == 0:
|
||||
new_tools_dict[orig_tool]['data'][d] = db_tool_val['data'][d]
|
||||
elif d.find('tools_') == 0:
|
||||
# don't need data for other App Tools; this tests after 'tools_drill_'
|
||||
continue
|
||||
else:
|
||||
new_tools_dict[orig_tool]['data'][d] = db_tool_val['data'][d]
|
||||
|
||||
self.excellon_tools = new_tools_dict
|
||||
for td in self.excellon_tools:
|
||||
print(td, self.excellon_tools[td])
|
||||
self.build_tool_ui()
|
||||
|
||||
def on_toggle_all_rows(self):
|
||||
"""
|
||||
will toggle the selection of all rows in Tools table
|
||||
|
|
10
app_Main.py
10
app_Main.py
|
@ -8935,22 +8935,18 @@ class App(QtCore.QObject):
|
|||
|
||||
# How the object should be initialized
|
||||
def obj_init(excellon_obj, app_obj):
|
||||
|
||||
try:
|
||||
ret = excellon_obj.parse_file(filename=filename)
|
||||
if ret == "fail":
|
||||
log.debug("Excellon parsing failed.")
|
||||
self.inform.emit('[ERROR_NOTCL] %s' %
|
||||
_("This is not Excellon file."))
|
||||
self.inform.emit('[ERROR_NOTCL] %s' % _("This is not Excellon file."))
|
||||
return "fail"
|
||||
except IOError:
|
||||
app_obj.inform.emit('[ERROR_NOTCL] %s: %s' %
|
||||
(_("Cannot open file"), filename))
|
||||
app_obj.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Cannot open file"), filename))
|
||||
log.debug("Could not open Excellon object.")
|
||||
return "fail"
|
||||
except Exception:
|
||||
msg = '[ERROR_NOTCL] %s' % \
|
||||
_("An internal error has occurred. See shell.\n")
|
||||
msg = '[ERROR_NOTCL] %s' % _("An internal error has occurred. See shell.\n")
|
||||
msg += traceback.format_exc()
|
||||
app_obj.inform.emit(msg)
|
||||
return "fail"
|
||||
|
|
Loading…
Reference in New Issue