- changed the data structure for the Excellon object; modified the Excellon parser and the Excellon object class
- fixed partially the Excellon Editor to work with the new data structure - fixed Excellon export to work with the new data structure - fixed all transformations in the Excellon object attributes; still need to fix the App Tools that creates or use Exellon objects
This commit is contained in:
parent
bb24a45f5a
commit
949c265378
|
@ -7,6 +7,13 @@ CHANGELOG for FlatCAM beta
|
|||
|
||||
=================================================
|
||||
|
||||
16.06.2020
|
||||
|
||||
- changed the data structure for the Excellon object; modified the Excellon parser and the Excellon object class
|
||||
- fixed partially the Excellon Editor to work with the new data structure
|
||||
- fixed Excellon export to work with the new data structure
|
||||
- fixed all transformations in the Excellon object attributes; still need to fix the App Tools that creates or use Exellon objects
|
||||
|
||||
15.06.2020
|
||||
|
||||
- in Paint Tool and NCC Tool updated the way the selected tools were processed and made sure that the Tools Table rows are counted only once in the processing
|
||||
|
|
|
@ -390,8 +390,7 @@ class FCSlot(FCShapeTool):
|
|||
item = self.draw_app.tools_table_exc.item((self.draw_app.last_tool_selected - 1), 1)
|
||||
self.draw_app.tools_table_exc.setCurrentItem(item)
|
||||
except KeyError:
|
||||
self.draw_app.app.inform.emit('[WARNING_NOTCL] %s' %
|
||||
_("To add a slot first select a tool"))
|
||||
self.draw_app.app.inform.emit('[WARNING_NOTCL] %s' % _("To add a slot first select a tool"))
|
||||
self.draw_app.select_tool("drill_select")
|
||||
return
|
||||
|
||||
|
@ -2059,9 +2058,7 @@ class AppExcEditor(QtCore.QObject):
|
|||
|
||||
self.sorted_diameters = []
|
||||
|
||||
self.new_drills = []
|
||||
self.new_tools = {}
|
||||
self.new_slots = []
|
||||
|
||||
# dictionary to store the tool_row and diameters in Tool_table
|
||||
# it will be updated everytime self.build_ui() is called
|
||||
|
@ -2261,31 +2258,34 @@ class AppExcEditor(QtCore.QObject):
|
|||
self.tool2tooldia.clear()
|
||||
|
||||
# build the self.points_edit dict {dimaters: [point_list]}
|
||||
for drill in self.exc_obj.drills:
|
||||
if drill['tool'] in self.exc_obj.tools:
|
||||
tool_dia = float('%.*f' % (self.decimals, self.exc_obj.tools[drill['tool']]['C']))
|
||||
for tool, tool_dict in self.exc_obj.tools.items():
|
||||
tool_dia = float('%.*f' % (self.decimals, self.exc_obj.tools[tool]['tooldia']))
|
||||
|
||||
if 'drills' in tool_dict and tool_dict['drills']:
|
||||
for drill in tool_dict['drills']:
|
||||
try:
|
||||
self.points_edit[tool_dia].append(drill['point'])
|
||||
self.points_edit[tool_dia].append(drill)
|
||||
except KeyError:
|
||||
self.points_edit[tool_dia] = [drill['point']]
|
||||
self.points_edit[tool_dia] = [drill]
|
||||
|
||||
# build the self.slot_points_edit dict {dimaters: {"start": Point, "stop": Point}}
|
||||
for slot in self.exc_obj.slots:
|
||||
if slot['tool'] in self.exc_obj.tools:
|
||||
tool_dia = float('%.*f' % (self.decimals, self.exc_obj.tools[slot['tool']]['C']))
|
||||
for tool, tool_dict in self.exc_obj.tools.items():
|
||||
tool_dia = float('%.*f' % (self.decimals, self.exc_obj.tools[tool]['tooldia']))
|
||||
|
||||
if 'slots' in tool_dict and tool_dict['slots']:
|
||||
for slot in tool_dict['slots']:
|
||||
try:
|
||||
self.slot_points_edit[tool_dia].append({
|
||||
"start": slot["start"],
|
||||
"stop": slot["stop"]
|
||||
"start": slot[0],
|
||||
"stop": slot[1]
|
||||
})
|
||||
except KeyError:
|
||||
self.slot_points_edit[tool_dia] = [{
|
||||
"start": slot["start"],
|
||||
"stop": slot["stop"]
|
||||
"start": slot[0],
|
||||
"stop": slot[1]
|
||||
}]
|
||||
|
||||
|
||||
# update the olddia_newdia dict to make sure we have an updated state of the tool_table
|
||||
for key in self.points_edit:
|
||||
self.olddia_newdia[key] = key
|
||||
|
@ -2309,7 +2309,7 @@ class AppExcEditor(QtCore.QObject):
|
|||
# Excellon file has no tool diameter information. In this case do not order the diameter in the table
|
||||
# but use the real order found in the exc_obj.tools
|
||||
for k, v in self.exc_obj.tools.items():
|
||||
tool_dia = float('%.*f' % (self.decimals, v['C']))
|
||||
tool_dia = float('%.*f' % (self.decimals, v['tooldia']))
|
||||
self.tool2tooldia[int(k)] = tool_dia
|
||||
|
||||
# Init appGUI
|
||||
|
@ -2385,16 +2385,22 @@ class AppExcEditor(QtCore.QObject):
|
|||
|
||||
self.tot_drill_cnt += drill_cnt
|
||||
|
||||
try:
|
||||
# Find no of slots for the current tool
|
||||
for slot in self.slot_points_edit:
|
||||
if slot['tool'] == tool_no:
|
||||
slot_cnt += 1
|
||||
# try:
|
||||
# # Find no of slots for the current tool
|
||||
# for slot in self.slot_points_edit:
|
||||
# if float(slot) == tool_no:
|
||||
# slot_cnt += 1
|
||||
#
|
||||
# self.tot_slot_cnt += slot_cnt
|
||||
# except AttributeError:
|
||||
# # log.debug("No slots in the Excellon file")
|
||||
# # Find no of slots for the current tool
|
||||
# for tool_dia in self.slot_points_edit:
|
||||
# if float(tool_dia) == tool_no:
|
||||
# slot_cnt = len(self.slot_points_edit[tool_dia])
|
||||
#
|
||||
# self.tot_slot_cnt += slot_cnt
|
||||
|
||||
self.tot_slot_cnt += slot_cnt
|
||||
except AttributeError:
|
||||
# log.debug("No slots in the Excellon file")
|
||||
# Find no of slots for the current tool
|
||||
for tool_dia in self.slot_points_edit:
|
||||
if float(tool_dia) == tool_no:
|
||||
slot_cnt = len(self.slot_points_edit[tool_dia])
|
||||
|
@ -3141,6 +3147,10 @@ class AppExcEditor(QtCore.QObject):
|
|||
poly = x.geo
|
||||
poly = poly.buffer(-radius)
|
||||
|
||||
if not poly.is_valid or poly.is_empty:
|
||||
print("Polygon not valid: %s" % str(poly.wkt))
|
||||
continue
|
||||
|
||||
xmin, ymin, xmax, ymax = poly.bounds
|
||||
line_one = LineString([(xmin, ymin), (xmax, ymax)]).intersection(poly).length
|
||||
line_two = LineString([(xmin, ymax), (xmax, ymin)]).intersection(poly).length
|
||||
|
@ -3197,59 +3207,61 @@ class AppExcEditor(QtCore.QObject):
|
|||
current_tool += 1
|
||||
|
||||
# create the self.tools for the new Excellon object (the one with edited content)
|
||||
name = str(current_tool)
|
||||
spec = {"C": float(tool_dia[0])}
|
||||
self.new_tools[name] = spec
|
||||
if current_tool not in self.new_tools:
|
||||
self.new_tools[current_tool] = {}
|
||||
self.new_tools[current_tool]['tooldia'] = float(tool_dia[0])
|
||||
|
||||
# add in self.tools the 'solid_geometry' key, the value (a list) is populated below
|
||||
self.new_tools[name]['solid_geometry'] = []
|
||||
self.new_tools[current_tool]['solid_geometry'] = []
|
||||
|
||||
# create the self.drills for the new Excellon object (the one with edited content)
|
||||
for point in tool_dia[1]:
|
||||
self.new_drills.append(
|
||||
{
|
||||
'point': Point(point),
|
||||
'tool': str(current_tool)
|
||||
}
|
||||
)
|
||||
try:
|
||||
self.new_tools[current_tool]['drills'].append(Point(point))
|
||||
except KeyError:
|
||||
self.new_tools[current_tool]['drills'] = [Point(point)]
|
||||
|
||||
# repopulate the 'solid_geometry' for each tool
|
||||
poly = Point(point).buffer(float(tool_dia[0]) / 2.0, int(int(exc_obj.geo_steps_per_circle) / 4))
|
||||
self.new_tools[name]['solid_geometry'].append(poly)
|
||||
self.new_tools[current_tool]['solid_geometry'].append(poly)
|
||||
|
||||
ordered_edited_slot_points = sorted(zip(edited_slot_points.keys(), edited_slot_points.values()))
|
||||
for tool_dia in ordered_edited_slot_points:
|
||||
|
||||
tool_exist_flag = False
|
||||
for tool in self.new_tools:
|
||||
if tool_dia[0] == self.new_tools[tool]["C"]:
|
||||
if tool_dia[0] == self.new_tools[tool]["tooldia"]:
|
||||
current_tool = tool
|
||||
tool_exist_flag = True
|
||||
break
|
||||
|
||||
if tool_exist_flag is False:
|
||||
current_tool += 1
|
||||
|
||||
# create the self.tools for the new Excellon object (the one with edited content)
|
||||
name = str(current_tool)
|
||||
spec = {"C": float(tool_dia[0])}
|
||||
self.new_tools[name] = spec
|
||||
if current_tool not in self.new_tools:
|
||||
self.new_tools[current_tool] = {}
|
||||
self.new_tools[current_tool]['tooldia'] = float(tool_dia[0])
|
||||
|
||||
# add in self.tools the 'solid_geometry' key, the value (a list) is populated below
|
||||
self.new_tools[name]['solid_geometry'] = []
|
||||
self.new_tools[current_tool]['solid_geometry'] = []
|
||||
|
||||
# create the self.slots for the new Excellon object (the one with edited content)
|
||||
for coord_dict in tool_dia[1]:
|
||||
self.new_slots.append(
|
||||
{
|
||||
'start': Point(coord_dict['start']),
|
||||
'stop': Point(coord_dict['stop']),
|
||||
'tool': str(current_tool)
|
||||
}
|
||||
slot = (
|
||||
Point(coord_dict['start']),
|
||||
Point(coord_dict['stop'])
|
||||
)
|
||||
try:
|
||||
self.new_tools[current_tool]['slots'].append(slot)
|
||||
except KeyError:
|
||||
self.new_tools[current_tool]['slots'] = [slot]
|
||||
|
||||
# repopulate the 'solid_geometry' for each tool
|
||||
poly = LineString([coord_dict['start'], coord_dict['stop']]).buffer(
|
||||
float(tool_dia[0]) / 2.0, int(int(exc_obj.geo_steps_per_circle) / 4)
|
||||
)
|
||||
self.new_tools[str(current_tool)]['solid_geometry'].append(poly)
|
||||
self.new_tools[current_tool]['solid_geometry'].append(poly)
|
||||
|
||||
if self.is_modified is True:
|
||||
if "_edit" in self.edited_obj_name:
|
||||
|
|
|
@ -682,7 +682,7 @@ class NumericalEvalEntry(EvalEntry):
|
|||
return evaled
|
||||
|
||||
|
||||
class NumericalEvalTupleEntry(FCEntry):
|
||||
class NumericalEvalTupleEntry(EvalEntry):
|
||||
"""
|
||||
Will return a text value. Accepts only float numbers and formulas using the operators: /,*,+,-,%
|
||||
"""
|
||||
|
|
|
@ -138,7 +138,7 @@ class ExcellonObject(FlatCAMObj, Excellon):
|
|||
self.ser_attrs += ['options', 'kind']
|
||||
|
||||
@staticmethod
|
||||
def merge(exc_list, exc_final, decimals=None):
|
||||
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 .
|
||||
|
@ -153,31 +153,31 @@ class ExcellonObject(FlatCAMObj, Excellon):
|
|||
: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
|
||||
|
||||
# flag to signal that we need to reorder the tools dictionary and drills and slots lists
|
||||
flag_order = False
|
||||
|
||||
try:
|
||||
flattened_list = list(itertools.chain(*exc_list))
|
||||
except TypeError:
|
||||
flattened_list = exc_list
|
||||
|
||||
# this dict will hold the unique tool diameters found in the exc_list objects as the dict keys and the dict
|
||||
# values will be list of Shapely Points; for drills
|
||||
custom_dict_drills = defaultdict(list)
|
||||
|
||||
# this dict will hold the unique tool diameters found in the exc_list objects as the dict keys and the dict
|
||||
# values will be list of Shapely Points; for slots
|
||||
custom_dict_slots = defaultdict(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:
|
||||
|
@ -185,129 +185,47 @@ class ExcellonObject(FlatCAMObj, Excellon):
|
|||
except Exception:
|
||||
exc.app.log.warning("Failed to copy option.", option)
|
||||
|
||||
for drill in exc.drills:
|
||||
exc_tool_dia = float('%.*f' % (decimals_exc, exc.tools[drill['tool']]['C']))
|
||||
custom_dict_drills[exc_tool_dia].append(drill['point'])
|
||||
|
||||
for slot in exc.slots:
|
||||
exc_tool_dia = float('%.*f' % (decimals_exc, exc.tools[slot['tool']]['C']))
|
||||
custom_dict_slots[exc_tool_dia].append([slot['start'], slot['stop']])
|
||||
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
|
||||
|
||||
# ##########################################
|
||||
# Here we add data to the exc_final object #
|
||||
# ##########################################
|
||||
exc_final.solid_geometry = total_geo
|
||||
|
||||
# variable to make tool_name for the tools
|
||||
current_tool = 0
|
||||
# The tools diameter are now the keys in the drill_dia dict and the values are the Shapely Points in case of
|
||||
# drills
|
||||
for tool_dia in custom_dict_drills:
|
||||
# we create a tool name for each key in the drill_dia dict (the key is a unique drill diameter)
|
||||
current_tool += 1
|
||||
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
|
||||
|
||||
tool_name = str(current_tool)
|
||||
spec = {"C": float(tool_dia)}
|
||||
exc_final.tools[tool_name] = spec
|
||||
# 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'])))
|
||||
|
||||
# rebuild the drills list of dict's that belong to the exc_final object
|
||||
for point in custom_dict_drills[tool_dia]:
|
||||
exc_final.drills.append(
|
||||
{
|
||||
"point": point,
|
||||
"tool": str(current_tool)
|
||||
}
|
||||
)
|
||||
|
||||
# The tools diameter are now the keys in the drill_dia dict and the values are a list ([start, stop])
|
||||
# of two Shapely Points in case of slots
|
||||
for tool_dia in custom_dict_slots:
|
||||
# we create a tool name for each key in the slot_dia dict (the key is a unique slot diameter)
|
||||
# but only if there are no drills
|
||||
if not exc_final.tools:
|
||||
current_tool += 1
|
||||
tool_name = str(current_tool)
|
||||
spec = {"C": float(tool_dia)}
|
||||
exc_final.tools[tool_name] = spec
|
||||
else:
|
||||
dia_list = []
|
||||
for v in exc_final.tools.values():
|
||||
dia_list.append(float(v["C"]))
|
||||
|
||||
if tool_dia not in dia_list:
|
||||
flag_order = True
|
||||
|
||||
current_tool = len(dia_list) + 1
|
||||
tool_name = str(current_tool)
|
||||
spec = {"C": float(tool_dia)}
|
||||
exc_final.tools[tool_name] = spec
|
||||
|
||||
else:
|
||||
for k, v in exc_final.tools.items():
|
||||
if v["C"] == tool_dia:
|
||||
current_tool = int(k)
|
||||
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
|
||||
|
||||
# rebuild the slots list of dict's that belong to the exc_final object
|
||||
for point in custom_dict_slots[tool_dia]:
|
||||
exc_final.slots.append(
|
||||
{
|
||||
"start": point[0],
|
||||
"stop": point[1],
|
||||
"tool": str(current_tool)
|
||||
}
|
||||
)
|
||||
|
||||
# flag_order == True means that there was an slot diameter not in the tools and we also have drills
|
||||
# and the new tool was added to self.tools therefore we need to reorder the tools and drills and slots
|
||||
current_tool = 0
|
||||
if flag_order is True:
|
||||
dia_list = []
|
||||
temp_drills = []
|
||||
temp_slots = []
|
||||
temp_tools = {}
|
||||
for v in exc_final.tools.values():
|
||||
dia_list.append(float(v["C"]))
|
||||
dia_list.sort()
|
||||
for ordered_dia in dia_list:
|
||||
current_tool += 1
|
||||
tool_name_temp = str(current_tool)
|
||||
spec_temp = {"C": float(ordered_dia)}
|
||||
temp_tools[tool_name_temp] = spec_temp
|
||||
|
||||
for drill in exc_final.drills:
|
||||
exc_tool_dia = float('%.*f' % (decimals_exc, exc_final.tools[drill['tool']]['C']))
|
||||
if exc_tool_dia == ordered_dia:
|
||||
temp_drills.append(
|
||||
{
|
||||
"point": drill["point"],
|
||||
"tool": str(current_tool)
|
||||
}
|
||||
)
|
||||
|
||||
for slot in exc_final.slots:
|
||||
slot_tool_dia = float('%.*f' % (decimals_exc, exc_final.tools[slot['tool']]['C']))
|
||||
if slot_tool_dia == ordered_dia:
|
||||
temp_slots.append(
|
||||
{
|
||||
"start": slot["start"],
|
||||
"stop": slot["stop"],
|
||||
"tool": str(current_tool)
|
||||
}
|
||||
)
|
||||
|
||||
# delete the exc_final tools, drills and slots
|
||||
exc_final.tools = {}
|
||||
exc_final.drills[:] = []
|
||||
exc_final.slots[:] = []
|
||||
|
||||
# update the exc_final tools, drills and slots with the ordered values
|
||||
exc_final.tools = temp_tools
|
||||
exc_final.drills[:] = temp_drills
|
||||
exc_final.slots[:] = temp_slots
|
||||
exc_final.tools = fused_tools_dict
|
||||
|
||||
# create the geometry for the exc_final object
|
||||
exc_final.create_geometry()
|
||||
|
@ -351,7 +269,7 @@ class ExcellonObject(FlatCAMObj, Excellon):
|
|||
|
||||
sort = []
|
||||
for k, v in list(self.tools.items()):
|
||||
sort.append((k, v.get('C')))
|
||||
sort.append((k, v['tooldia']))
|
||||
sorted_tools = sorted(sort, key=lambda t1: t1[1])
|
||||
tools = [i[0] for i in sorted_tools]
|
||||
|
||||
|
@ -370,23 +288,23 @@ class ExcellonObject(FlatCAMObj, Excellon):
|
|||
slot_cnt = 0 # variable to store the nr of slots per tool
|
||||
|
||||
# Find no of drills for the current tool
|
||||
for drill in self.drills:
|
||||
if drill['tool'] == tool_no:
|
||||
drill_cnt += 1
|
||||
|
||||
try:
|
||||
drill_cnt = len(self.tools[tool_no]['drills'])
|
||||
except KeyError:
|
||||
drill_cnt = 0
|
||||
self.tot_drill_cnt += drill_cnt
|
||||
|
||||
# Find no of slots for the current tool
|
||||
for slot in self.slots:
|
||||
if slot['tool'] == tool_no:
|
||||
slot_cnt += 1
|
||||
|
||||
try:
|
||||
slot_cnt = len(self.tools[tool_no]['slots'])
|
||||
except KeyError:
|
||||
slot_cnt = 0
|
||||
self.tot_slot_cnt += slot_cnt
|
||||
|
||||
exc_id_item = QtWidgets.QTableWidgetItem('%d' % int(tool_no))
|
||||
exc_id_item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
|
||||
|
||||
dia_item = QtWidgets.QTableWidgetItem('%.*f' % (self.decimals, self.tools[tool_no]['C']))
|
||||
dia_item = QtWidgets.QTableWidgetItem('%.*f' % (self.decimals, self.tools[tool_no]['tooldia']))
|
||||
dia_item.setFlags(QtCore.Qt.ItemIsEnabled)
|
||||
|
||||
drill_count_item = QtWidgets.QTableWidgetItem('%d' % drill_cnt)
|
||||
|
@ -508,14 +426,26 @@ class ExcellonObject(FlatCAMObj, Excellon):
|
|||
self.ui.tools_table.setMinimumHeight(self.ui.tools_table.getHeight())
|
||||
self.ui.tools_table.setMaximumHeight(self.ui.tools_table.getHeight())
|
||||
|
||||
if not self.drills:
|
||||
# find if we have drills:
|
||||
has_drills = None
|
||||
for tt in self.tools:
|
||||
if 'drills' in self.tools[tt] and self.tools[tt]['drills']:
|
||||
has_drills = True
|
||||
break
|
||||
if has_drills is None:
|
||||
self.ui.tooldia_entry.hide()
|
||||
self.ui.generate_milling_button.hide()
|
||||
else:
|
||||
self.ui.tooldia_entry.show()
|
||||
self.ui.generate_milling_button.show()
|
||||
|
||||
if not self.slots:
|
||||
# find if we have slots
|
||||
has_slots = None
|
||||
for tt in self.tools:
|
||||
if 'slots' in self.tools[tt] and self.tools[tt]['slots']:
|
||||
has_slots = True
|
||||
break
|
||||
if has_slots is None:
|
||||
self.ui.slot_tooldia_entry.hide()
|
||||
self.ui.generate_milling_slots_button.hide()
|
||||
else:
|
||||
|
@ -962,7 +892,7 @@ class ExcellonObject(FlatCAMObj, Excellon):
|
|||
:rtype: list
|
||||
"""
|
||||
|
||||
return [str(x.text()) for x in self.ui.tools_table.selectedItems()]
|
||||
return [x.text() for x in self.ui.tools_table.selectedItems()]
|
||||
|
||||
def get_selected_tools_table_items(self):
|
||||
"""
|
||||
|
@ -1017,23 +947,37 @@ class ExcellonObject(FlatCAMObj, Excellon):
|
|||
excellon_code = ''
|
||||
|
||||
# store here if the file has slots, return 1 if any slots, 0 if only drills
|
||||
has_slots = 0
|
||||
slots_in_file = 0
|
||||
|
||||
# find if we have drills:
|
||||
has_drills = None
|
||||
for tt in self.tools:
|
||||
if 'drills' in self.tools[tt] and self.tools[tt]['drills']:
|
||||
has_drills = True
|
||||
break
|
||||
# find if we have slots:
|
||||
has_slots = None
|
||||
for tt in self.tools:
|
||||
if 'slots' in self.tools[tt] and self.tools[tt]['slots']:
|
||||
has_slots = True
|
||||
slots_in_file = 1
|
||||
break
|
||||
|
||||
# drills processing
|
||||
try:
|
||||
if self.drills:
|
||||
if has_drills:
|
||||
length = whole + fract
|
||||
for tool in self.tools:
|
||||
excellon_code += 'T0%s\n' % str(tool) if int(tool) < 10 else 'T%s\n' % str(tool)
|
||||
|
||||
for drill in self.drills:
|
||||
if form == 'dec' and tool == drill['tool']:
|
||||
drill_x = drill['point'].x * factor
|
||||
drill_y = drill['point'].y * factor
|
||||
for drill in self.tools[tool]['drills']:
|
||||
if form == 'dec':
|
||||
drill_x = drill.x * factor
|
||||
drill_y = drill.y * factor
|
||||
excellon_code += "X{:.{dec}f}Y{:.{dec}f}\n".format(drill_x, drill_y, dec=fract)
|
||||
elif e_zeros == 'LZ' and tool == drill['tool']:
|
||||
drill_x = drill['point'].x * factor
|
||||
drill_y = drill['point'].y * factor
|
||||
elif e_zeros == 'LZ':
|
||||
drill_x = drill.x * factor
|
||||
drill_y = drill.y * factor
|
||||
|
||||
exc_x_formatted = "{:.{dec}f}".format(drill_x, dec=fract)
|
||||
exc_y_formatted = "{:.{dec}f}".format(drill_y, dec=fract)
|
||||
|
@ -1053,9 +997,9 @@ class ExcellonObject(FlatCAMObj, Excellon):
|
|||
|
||||
excellon_code += "X{xform}Y{yform}\n".format(xform=exc_x_formatted,
|
||||
yform=exc_y_formatted)
|
||||
elif tool == drill['tool']:
|
||||
drill_x = drill['point'].x * factor
|
||||
drill_y = drill['point'].y * factor
|
||||
else:
|
||||
drill_x = drill.x * factor
|
||||
drill_y = drill.y * factor
|
||||
|
||||
exc_x_formatted = "{:.{dec}f}".format(drill_x, dec=fract).replace('.', '')
|
||||
exc_y_formatted = "{:.{dec}f}".format(drill_y, dec=fract).replace('.', '')
|
||||
|
@ -1071,8 +1015,7 @@ class ExcellonObject(FlatCAMObj, Excellon):
|
|||
|
||||
# slots processing
|
||||
try:
|
||||
if self.slots:
|
||||
has_slots = 1
|
||||
if has_slots:
|
||||
for tool in self.tools:
|
||||
excellon_code += 'G05\n'
|
||||
|
||||
|
@ -1081,12 +1024,12 @@ class ExcellonObject(FlatCAMObj, Excellon):
|
|||
else:
|
||||
excellon_code += 'T' + str(tool) + '\n'
|
||||
|
||||
for slot in self.slots:
|
||||
if form == 'dec' and tool == slot['tool']:
|
||||
start_slot_x = slot['start'].x * factor
|
||||
start_slot_y = slot['start'].y * factor
|
||||
stop_slot_x = slot['stop'].x * factor
|
||||
stop_slot_y = slot['stop'].y * factor
|
||||
for slot in self.tools[tool]['slots']:
|
||||
if form == 'dec':
|
||||
start_slot_x = slot.x * factor
|
||||
start_slot_y = slot.y * factor
|
||||
stop_slot_x = slot.x * factor
|
||||
stop_slot_y = slot.y * factor
|
||||
if slot_type == 'routing':
|
||||
excellon_code += "G00X{:.{dec}f}Y{:.{dec}f}\nM15\n".format(start_slot_x,
|
||||
start_slot_y,
|
||||
|
@ -1099,11 +1042,11 @@ class ExcellonObject(FlatCAMObj, Excellon):
|
|||
start_slot_x, start_slot_y, stop_slot_x, stop_slot_y, dec=fract
|
||||
)
|
||||
|
||||
elif e_zeros == 'LZ' and tool == slot['tool']:
|
||||
start_slot_x = slot['start'].x * factor
|
||||
start_slot_y = slot['start'].y * factor
|
||||
stop_slot_x = slot['stop'].x * factor
|
||||
stop_slot_y = slot['stop'].y * factor
|
||||
elif e_zeros == 'LZ':
|
||||
start_slot_x = slot.x * factor
|
||||
start_slot_y = slot.y * factor
|
||||
stop_slot_x = slot.x * factor
|
||||
stop_slot_y = slot.y * factor
|
||||
|
||||
start_slot_x_formatted = "{:.{dec}f}".format(start_slot_x, dec=fract).replace('.', '')
|
||||
start_slot_y_formatted = "{:.{dec}f}".format(start_slot_y, dec=fract).replace('.', '')
|
||||
|
@ -1139,11 +1082,11 @@ class ExcellonObject(FlatCAMObj, Excellon):
|
|||
xstart=start_slot_x_formatted, ystart=start_slot_y_formatted,
|
||||
xstop=stop_slot_x_formatted, ystop=stop_slot_y_formatted
|
||||
)
|
||||
elif tool == slot['tool']:
|
||||
start_slot_x = slot['start'].x * factor
|
||||
start_slot_y = slot['start'].y * factor
|
||||
stop_slot_x = slot['stop'].x * factor
|
||||
stop_slot_y = slot['stop'].y * factor
|
||||
else:
|
||||
start_slot_x = slot.x * factor
|
||||
start_slot_y = slot.y * factor
|
||||
stop_slot_x = slot.x * factor
|
||||
stop_slot_y = slot.y * factor
|
||||
length = whole + fract
|
||||
|
||||
start_slot_x_formatted = "{:.{dec}f}".format(start_slot_x, dec=fract).replace('.', '')
|
||||
|
@ -1170,11 +1113,11 @@ class ExcellonObject(FlatCAMObj, Excellon):
|
|||
except Exception as e:
|
||||
log.debug(str(e))
|
||||
|
||||
if not self.drills and not self.slots:
|
||||
if not has_drills and not has_slots:
|
||||
log.debug("FlatCAMObj.ExcellonObject.export_excellon() --> Excellon Object is empty: no drills, no slots.")
|
||||
return 'fail'
|
||||
|
||||
return has_slots, excellon_code
|
||||
return slots_in_file, excellon_code
|
||||
|
||||
def generate_milling_drills(self, tools=None, outname=None, tooldia=None, plot=False, use_thread=False):
|
||||
"""
|
||||
|
@ -1215,7 +1158,7 @@ class ExcellonObject(FlatCAMObj, Excellon):
|
|||
|
||||
sort = []
|
||||
for k, v in self.tools.items():
|
||||
sort.append((k, v.get('C')))
|
||||
sort.append((k, v['tooldia']))
|
||||
sorted_tools = sorted(sort, key=lambda t1: t1[1])
|
||||
|
||||
if tools == "all":
|
||||
|
@ -1223,19 +1166,15 @@ class ExcellonObject(FlatCAMObj, Excellon):
|
|||
log.debug("Tools 'all' and sorted are: %s" % str(tools))
|
||||
|
||||
if len(tools) == 0:
|
||||
self.app.inform.emit('[ERROR_NOTCL] %s' %
|
||||
_("Please select one or more tools from the list and try again."))
|
||||
self.app.inform.emit('[ERROR_NOTCL] %s' % _("Please select one or more tools from the list and try again."))
|
||||
return False, "Error: No tools."
|
||||
|
||||
for tool in tools:
|
||||
if tooldia > self.tools[tool]["C"]:
|
||||
self.app.inform.emit(
|
||||
'[ERROR_NOTCL] %s %s: %s' % (
|
||||
_("Milling tool for DRILLS is larger than hole size. Cancelled."),
|
||||
if tooldia > self.tools[tool]["tooldia"]:
|
||||
mseg = '[ERROR_NOTCL] %s %s: %s' % (_("Milling tool for DRILLS is larger than hole size. Cancelled."),
|
||||
_("Tool"),
|
||||
str(tool)
|
||||
)
|
||||
)
|
||||
str(tool))
|
||||
self.app.inform.emit(mseg)
|
||||
return False, "Error: Milling tool is larger than hole."
|
||||
|
||||
def geo_init(geo_obj, app_obj):
|
||||
|
@ -1266,15 +1205,13 @@ class ExcellonObject(FlatCAMObj, Excellon):
|
|||
# in case that the tool used has the same diameter with the hole, and since the maximum resolution
|
||||
# for FlatCAM is 6 decimals,
|
||||
# we add a tenth of the minimum value, meaning 0.0000001, which from our point of view is "almost zero"
|
||||
for hole in self.drills:
|
||||
if hole['tool'] in tools:
|
||||
buffer_value = self.tools[hole['tool']]["C"] / 2 - tooldia / 2
|
||||
for tool in tools:
|
||||
for drill in self.tools[tool]['drills']:
|
||||
buffer_value = self.tools[tool]['tooldia'] / 2 - tooldia / 2
|
||||
if buffer_value == 0:
|
||||
geo_obj.solid_geometry.append(
|
||||
Point(hole['point']).buffer(0.0000001).exterior)
|
||||
geo_obj.solid_geometry.append(drill.buffer(0.0000001).exterior)
|
||||
else:
|
||||
geo_obj.solid_geometry.append(
|
||||
Point(hole['point']).buffer(buffer_value).exterior)
|
||||
geo_obj.solid_geometry.append(drill.buffer(buffer_value).exterior)
|
||||
|
||||
if use_thread:
|
||||
def geo_thread(a_obj):
|
||||
|
@ -1329,7 +1266,7 @@ class ExcellonObject(FlatCAMObj, Excellon):
|
|||
|
||||
sort = []
|
||||
for k, v in self.tools.items():
|
||||
sort.append((k, v.get('C')))
|
||||
sort.append((k, v['tooldia']))
|
||||
sorted_tools = sorted(sort, key=lambda t1: t1[1])
|
||||
|
||||
if tools == "all":
|
||||
|
@ -1337,14 +1274,13 @@ class ExcellonObject(FlatCAMObj, Excellon):
|
|||
log.debug("Tools 'all' and sorted are: %s" % str(tools))
|
||||
|
||||
if len(tools) == 0:
|
||||
self.app.inform.emit('[ERROR_NOTCL] %s' %
|
||||
_("Please select one or more tools from the list and try again."))
|
||||
self.app.inform.emit('[ERROR_NOTCL] %s' % _("Please select one or more tools from the list and try again."))
|
||||
return False, "Error: No tools."
|
||||
|
||||
for tool in tools:
|
||||
# I add the 0.0001 value to account for the rounding error in converting from IN to MM and reverse
|
||||
adj_toolstable_tooldia = float('%.*f' % (self.decimals, float(tooldia)))
|
||||
adj_file_tooldia = float('%.*f' % (self.decimals, float(self.tools[tool]["C"])))
|
||||
adj_file_tooldia = float('%.*f' % (self.decimals, float(self.tools[tool]["tooldia"])))
|
||||
if adj_toolstable_tooldia > adj_file_tooldia + 0.0001:
|
||||
self.app.inform.emit('[ERROR_NOTCL] %s' %
|
||||
_("Milling tool for SLOTS is larger than hole size. Cancelled."))
|
||||
|
@ -1369,24 +1305,24 @@ class ExcellonObject(FlatCAMObj, Excellon):
|
|||
# in case that the tool used has the same diameter with the hole, and since the maximum resolution
|
||||
# for FlatCAM is 6 decimals,
|
||||
# we add a tenth of the minimum value, meaning 0.0000001, which from our point of view is "almost zero"
|
||||
for slot in self.slots:
|
||||
if slot['tool'] in tools:
|
||||
for tool in tools:
|
||||
for slot in self.tools[tool]['slots']:
|
||||
toolstable_tool = float('%.*f' % (self.decimals, float(tooldia)))
|
||||
file_tool = float('%.*f' % (self.decimals, float(self.tools[tool]["C"])))
|
||||
file_tool = float('%.*f' % (self.decimals, float(self.tools[tool]["tooldia"])))
|
||||
|
||||
# I add the 0.0001 value to account for the rounding error in converting from IN to MM and reverse
|
||||
# for the file_tool (tooldia actually)
|
||||
buffer_value = float(file_tool / 2) - float(toolstable_tool / 2) + 0.0001
|
||||
if buffer_value == 0:
|
||||
start = slot['start']
|
||||
stop = slot['stop']
|
||||
start = slot[0]
|
||||
stop = slot[1]
|
||||
|
||||
lines_string = LineString([start, stop])
|
||||
poly = lines_string.buffer(0.0000001, int(self.geo_steps_per_circle)).exterior
|
||||
geo_obj.solid_geometry.append(poly)
|
||||
else:
|
||||
start = slot['start']
|
||||
stop = slot['stop']
|
||||
start = slot[0]
|
||||
stop = slot[1]
|
||||
|
||||
lines_string = LineString([start, stop])
|
||||
poly = lines_string.buffer(buffer_value, int(self.geo_steps_per_circle)).exterior
|
||||
|
@ -1522,7 +1458,7 @@ class ExcellonObject(FlatCAMObj, Excellon):
|
|||
# tool number) it means that there are 3 rows (1 tool and 2 totals).
|
||||
# in this case regardless of the selection status of that tool, use it.
|
||||
if self.ui.tools_table.rowCount() == 3:
|
||||
tools.append(self.ui.tools_table.item(0, 0).text())
|
||||
tools.append(int(self.ui.tools_table.item(0, 0).text()))
|
||||
else:
|
||||
self.app.inform.emit('[ERROR_NOTCL] %s' %
|
||||
_("Please select one or more tools from the list and try again."))
|
||||
|
|
|
@ -40,30 +40,13 @@ class Excellon(Geometry):
|
|||
================ ====================================
|
||||
Key Value
|
||||
================ ====================================
|
||||
C Diameter of the tool
|
||||
solid_geometry Geometry list for each tool
|
||||
tooldia Diameter of the tool
|
||||
drills List that store the Shapely Points for drill points
|
||||
slots List that store the Shapely Points for slots. Each is a tuple: (start_point, stop_point
|
||||
data dictionary which holds the options for each tool
|
||||
Others Not supported (Ignored).
|
||||
solid_geometry Geometry list for each tool
|
||||
================ ====================================
|
||||
|
||||
* ``drills`` (list): Each is a dictionary:
|
||||
|
||||
================ ====================================
|
||||
Key Value
|
||||
================ ====================================
|
||||
point (Shapely.Point) Where to drill
|
||||
tool (str) A key in ``tools``
|
||||
================ ====================================
|
||||
|
||||
* ``slots`` (list): Each is a dictionary
|
||||
|
||||
================ ====================================
|
||||
Key Value
|
||||
================ ====================================
|
||||
start (Shapely.Point) Start point of the slot
|
||||
stop (Shapely.Point) Stop point of the slot
|
||||
tool (str) A key in ``tools``
|
||||
================ ====================================
|
||||
"""
|
||||
|
||||
defaults = {
|
||||
|
@ -96,10 +79,6 @@ class Excellon(Geometry):
|
|||
|
||||
# dictionary to store tools, see above for description
|
||||
self.tools = {}
|
||||
# list to store the drills, see above for description
|
||||
self.drills = []
|
||||
# self.slots (list) to store the slots; each is a dictionary
|
||||
self.slots = []
|
||||
|
||||
self.source_file = ''
|
||||
|
||||
|
@ -110,9 +89,6 @@ class Excellon(Geometry):
|
|||
self.match_routing_start = None
|
||||
self.match_routing_stop = None
|
||||
|
||||
self.num_tools = [] # List for keeping the tools sorted
|
||||
self.index_per_tool = {} # Dictionary to store the indexed points for each tool
|
||||
|
||||
# ## IN|MM -> Units are inherited from Geometry
|
||||
self.units = self.app.defaults['units']
|
||||
self.units_found = self.app.defaults['units']
|
||||
|
@ -142,9 +118,8 @@ class Excellon(Geometry):
|
|||
# Attributes to be included in serialization
|
||||
# Always append to it because it carries contents
|
||||
# from Geometry.
|
||||
self.ser_attrs += ['tools', 'drills', 'zeros', 'excellon_format_upper_mm', 'excellon_format_lower_mm',
|
||||
'excellon_format_upper_in', 'excellon_format_lower_in', 'excellon_units', 'slots',
|
||||
'source_file']
|
||||
self.ser_attrs += ['tools', 'zeros', 'excellon_format_upper_mm', 'excellon_format_lower_mm',
|
||||
'excellon_format_upper_in', 'excellon_format_lower_in', 'excellon_units', 'source_file']
|
||||
|
||||
# ### Patterns ####
|
||||
# Regex basics:
|
||||
|
@ -346,14 +321,22 @@ class Excellon(Geometry):
|
|||
|
||||
if match.group(2):
|
||||
name_tool += 1
|
||||
|
||||
# ---------- add a TOOL ------------ #
|
||||
if name_tool not in self.tools:
|
||||
self.tools[name_tool] = {}
|
||||
if line_units == 'MILS':
|
||||
spec = {"C": (float(match.group(2)) / 1000)}
|
||||
self.tools[str(name_tool)] = spec
|
||||
log.debug("Tool definition: %s %s" % (name_tool, spec))
|
||||
spec = {
|
||||
'tooldia': (float(match.group(2)) / 1000)
|
||||
}
|
||||
self.tools[name_tool]['tooldia'] = (float(match.group(2)) / 1000)
|
||||
log.debug("Tool definition: %d %s" % (name_tool, spec))
|
||||
else:
|
||||
spec = {"C": float(match.group(2))}
|
||||
self.tools[str(name_tool)] = spec
|
||||
log.debug("Tool definition: %s %s" % (name_tool, spec))
|
||||
spec = {
|
||||
'tooldia': float(match.group(2))
|
||||
}
|
||||
self.tools[name_tool]['tooldia'] = float(match.group(2))
|
||||
log.debug("Tool definition: %d %s" % (name_tool, spec))
|
||||
spec['solid_geometry'] = []
|
||||
continue
|
||||
# search for Altium Excellon Format / Sprint Layout who is included as a comment
|
||||
|
@ -400,7 +383,7 @@ class Excellon(Geometry):
|
|||
lower_tools = set()
|
||||
if not self.excellon_units_found and self.tools:
|
||||
for tool in self.tools:
|
||||
tool_dia = float(self.tools[tool]['C'])
|
||||
tool_dia = float(self.tools[tool]['tooldia'])
|
||||
lower_tools.add(tool_dia) if tool_dia <= 0.1 else greater_tools.add(tool_dia)
|
||||
|
||||
assumed_units = "IN" if len(lower_tools) > len(greater_tools) else "MM"
|
||||
|
@ -434,12 +417,12 @@ class Excellon(Geometry):
|
|||
# ## Tool change ###
|
||||
match = self.toolsel_re.search(eline)
|
||||
if match:
|
||||
current_tool = str(int(match.group(1)))
|
||||
current_tool = int(match.group(1))
|
||||
log.debug("Tool change: %s" % current_tool)
|
||||
if bool(headerless):
|
||||
match = self.toolset_hl_re.search(eline)
|
||||
if match:
|
||||
name = str(int(match.group(1)))
|
||||
name = int(match.group(1))
|
||||
try:
|
||||
diam = float(match.group(2))
|
||||
except Exception:
|
||||
|
@ -467,8 +450,13 @@ class Excellon(Geometry):
|
|||
else:
|
||||
diam = (self.toolless_diam + (int(current_tool) - 1) / 100) / 25.4
|
||||
|
||||
spec = {"C": diam, 'solid_geometry': []}
|
||||
self.tools[name] = spec
|
||||
# ---------- add a TOOL ------------ #
|
||||
spec = {"tooldia": diam, 'solid_geometry': []}
|
||||
if name not in self.tools:
|
||||
self.tools[name] = {}
|
||||
self.tools[name]['tooldia'] = diam
|
||||
self.tools[name]['solid_geometry'] = []
|
||||
|
||||
log.debug("Tool definition out of header: %s %s" % (name, spec))
|
||||
|
||||
continue
|
||||
|
@ -479,8 +467,8 @@ class Excellon(Geometry):
|
|||
match1 = self.stop_re.search(eline)
|
||||
if match or match1:
|
||||
name_tool += 1
|
||||
current_tool = str(name_tool)
|
||||
log.debug("Tool change for Allegro type of Excellon: %s" % current_tool)
|
||||
current_tool = name_tool
|
||||
log.debug("Tool change for Allegro type of Excellon: %d" % current_tool)
|
||||
continue
|
||||
|
||||
# ## Slots parsing for drilled slots (contain G85)
|
||||
|
@ -546,7 +534,7 @@ class Excellon(Geometry):
|
|||
# store current tool diameter as slot diameter
|
||||
slot_dia = 0.05
|
||||
try:
|
||||
slot_dia = float(self.tools[current_tool]['C'])
|
||||
slot_dia = float(self.tools[current_tool]['tooldia'])
|
||||
except Exception:
|
||||
pass
|
||||
log.debug(
|
||||
|
@ -556,13 +544,17 @@ class Excellon(Geometry):
|
|||
)
|
||||
)
|
||||
|
||||
self.slots.append(
|
||||
{
|
||||
'start': Point(slot_start_x, slot_start_y),
|
||||
'stop': Point(slot_stop_x, slot_stop_y),
|
||||
'tool': current_tool
|
||||
}
|
||||
# ---------- add a slot ------------ #
|
||||
slot = (
|
||||
Point(slot_start_x, slot_start_y),
|
||||
Point(slot_stop_x, slot_stop_y)
|
||||
)
|
||||
if current_tool not in self.tools:
|
||||
self.tools[current_tool] = {}
|
||||
if 'slots' in self.tools[current_tool]:
|
||||
self.tools[current_tool]['slots'].apend(slot)
|
||||
else:
|
||||
self.tools[current_tool]['slots'] = [slot]
|
||||
continue
|
||||
|
||||
# Slot coordinates with period: Use literally. ###
|
||||
|
@ -616,7 +608,7 @@ class Excellon(Geometry):
|
|||
# store current tool diameter as slot diameter
|
||||
slot_dia = 0.05
|
||||
try:
|
||||
slot_dia = float(self.tools[current_tool]['C'])
|
||||
slot_dia = float(self.tools[current_tool]['tooldia'])
|
||||
except Exception:
|
||||
pass
|
||||
log.debug(
|
||||
|
@ -626,13 +618,17 @@ class Excellon(Geometry):
|
|||
)
|
||||
)
|
||||
|
||||
self.slots.append(
|
||||
{
|
||||
'start': Point(slot_start_x, slot_start_y),
|
||||
'stop': Point(slot_stop_x, slot_stop_y),
|
||||
'tool': current_tool
|
||||
}
|
||||
# ---------- add a Slot ------------ #
|
||||
slot = (
|
||||
Point(slot_start_x, slot_start_y),
|
||||
Point(slot_stop_x, slot_stop_y)
|
||||
)
|
||||
if current_tool not in self.tools:
|
||||
self.tools[current_tool] = {}
|
||||
if 'slots' in self.tools[current_tool]:
|
||||
self.tools[current_tool]['slots'].apend(slot)
|
||||
else:
|
||||
self.tools[current_tool]['slots'] = [slot]
|
||||
continue
|
||||
|
||||
# ## Coordinates without period # ##
|
||||
|
@ -660,7 +656,14 @@ class Excellon(Geometry):
|
|||
coordx += repeating_x
|
||||
if repeating_y:
|
||||
coordy += repeating_y
|
||||
self.drills.append({'point': Point((coordx, coordy)), 'tool': current_tool})
|
||||
|
||||
# ---------- add a Drill ------------ #
|
||||
if current_tool not in self.tools:
|
||||
self.tools[current_tool] = {}
|
||||
if 'drills' in self.tools[current_tool]:
|
||||
self.tools[current_tool]['drills'].append(Point((coordx, coordy)))
|
||||
else:
|
||||
self.tools[current_tool]['drills'] = [Point((coordx, coordy))]
|
||||
|
||||
repeat -= 1
|
||||
current_x = coordx
|
||||
|
@ -710,19 +713,31 @@ class Excellon(Geometry):
|
|||
self.routing_flag = 1
|
||||
slot_stop_x = x
|
||||
slot_stop_y = y
|
||||
self.slots.append(
|
||||
{
|
||||
'start': Point(slot_start_x, slot_start_y),
|
||||
'stop': Point(slot_stop_x, slot_stop_y),
|
||||
'tool': current_tool
|
||||
}
|
||||
|
||||
# ---------- add a Slot ------------ #
|
||||
slot = (
|
||||
Point(slot_start_x, slot_start_y),
|
||||
Point(slot_stop_x, slot_stop_y)
|
||||
)
|
||||
if current_tool not in self.tools:
|
||||
self.tools[current_tool] = {}
|
||||
if 'slots' in self.tools[current_tool]:
|
||||
self.tools[current_tool]['slots'].apend(slot)
|
||||
else:
|
||||
self.tools[current_tool]['slots'] = [slot]
|
||||
continue
|
||||
|
||||
if self.match_routing_start is None and self.match_routing_stop is None:
|
||||
# signal that there are drill operations
|
||||
self.defaults['excellon_drills'] = True
|
||||
self.drills.append({'point': Point((x, y)), 'tool': current_tool})
|
||||
|
||||
# ---------- add a Drill ------------ #
|
||||
if current_tool not in self.tools:
|
||||
self.tools[current_tool] = {}
|
||||
if 'drills' in self.tools[current_tool]:
|
||||
self.tools[current_tool]['drills'].append(Point((x, y)))
|
||||
else:
|
||||
self.tools[current_tool]['drills'] = [Point((x, y))]
|
||||
# log.debug("{:15} {:8} {:8}".format(eline, x, y))
|
||||
continue
|
||||
|
||||
|
@ -778,13 +793,18 @@ class Excellon(Geometry):
|
|||
self.routing_flag = 1
|
||||
slot_stop_x = x
|
||||
slot_stop_y = y
|
||||
self.slots.append(
|
||||
{
|
||||
'start': Point(slot_start_x, slot_start_y),
|
||||
'stop': Point(slot_stop_x, slot_stop_y),
|
||||
'tool': current_tool
|
||||
}
|
||||
|
||||
# ---------- add a Slot ------------ #
|
||||
slot = (
|
||||
Point(slot_start_x, slot_start_y),
|
||||
Point(slot_stop_x, slot_stop_y)
|
||||
)
|
||||
if current_tool not in self.tools:
|
||||
self.tools[current_tool] = {}
|
||||
if 'slots' in self.tools[current_tool]:
|
||||
self.tools[current_tool]['slots'].apend(slot)
|
||||
else:
|
||||
self.tools[current_tool]['slots'] = [slot]
|
||||
continue
|
||||
|
||||
if self.match_routing_start is None and self.match_routing_stop is None:
|
||||
|
@ -792,7 +812,14 @@ class Excellon(Geometry):
|
|||
if repeat == 0:
|
||||
# signal that there are drill operations
|
||||
self.defaults['excellon_drills'] = True
|
||||
self.drills.append({'point': Point((x, y)), 'tool': current_tool})
|
||||
|
||||
# ---------- add a Drill ------------ #
|
||||
if current_tool not in self.tools:
|
||||
self.tools[current_tool] = {}
|
||||
if 'drills' in self.tools[current_tool]:
|
||||
self.tools[current_tool]['drills'].append(Point((x, y)))
|
||||
else:
|
||||
self.tools[current_tool]['drills'] = [Point((x, y))]
|
||||
else:
|
||||
coordx = x
|
||||
coordy = y
|
||||
|
@ -801,7 +828,15 @@ class Excellon(Geometry):
|
|||
coordx = (repeat * x) + repeating_x
|
||||
if repeating_y:
|
||||
coordy = (repeat * y) + repeating_y
|
||||
self.drills.append({'point': Point((coordx, coordy)), 'tool': current_tool})
|
||||
|
||||
# ---------- add a Drill ------------ #
|
||||
if current_tool not in self.tools:
|
||||
self.tools[current_tool] = {}
|
||||
if 'drills' in self.tools[current_tool]:
|
||||
self.tools[current_tool]['drills'].append(Point((coordx, coordy)))
|
||||
else:
|
||||
self.tools[current_tool]['drills'] = [Point((coordx, coordy))]
|
||||
|
||||
repeat -= 1
|
||||
repeating_x = repeating_y = 0
|
||||
# log.debug("{:15} {:8} {:8}".format(eline, x, y))
|
||||
|
@ -813,9 +848,14 @@ class Excellon(Geometry):
|
|||
# ## Tool definitions # ##
|
||||
match = self.toolset_re.search(eline)
|
||||
if match:
|
||||
name = str(int(match.group(1)))
|
||||
# ---------- add a TOOL ------------ #
|
||||
name = int(match.group(1))
|
||||
spec = {"C": float(match.group(2)), 'solid_geometry': []}
|
||||
self.tools[name] = spec
|
||||
if name not in self.tools:
|
||||
self.tools[name] = {}
|
||||
self.tools[name]['tooldia'] = float(match.group(2))
|
||||
self.tools[name]['solid_geometry'] = []
|
||||
|
||||
log.debug("Tool definition: %s %s" % (name, spec))
|
||||
continue
|
||||
|
||||
|
@ -977,8 +1017,9 @@ class Excellon(Geometry):
|
|||
def create_geometry(self):
|
||||
"""
|
||||
Creates circles of the tool diameter at every point
|
||||
specified in ``self.drills``. Also creates geometries (polygons)
|
||||
for the slots as specified in ``self.slots``
|
||||
specified in self.tools[tool]['drills'].
|
||||
Also creates geometries (polygons)
|
||||
for the slots as specified in self.tools[tool]['slots']
|
||||
All the resulting geometry is stored into self.solid_geometry list.
|
||||
The list self.solid_geometry has 2 elements: first is a dict with the drills geometry,
|
||||
and second element is another similar dict that contain the slots geometry.
|
||||
|
@ -1001,36 +1042,35 @@ class Excellon(Geometry):
|
|||
self.tools[tool]['solid_geometry'] = []
|
||||
self.tools[tool]['data'] = {}
|
||||
|
||||
for drill in self.drills:
|
||||
# poly = drill['point'].buffer(self.tools[drill['tool']]["C"]/2.0)
|
||||
if drill['tool'] == '':
|
||||
self.app.inform.emit('[WARNING] %s' %
|
||||
_("Excellon.create_geometry() -> a drill location was skipped "
|
||||
"due of not having a tool associated.\n"
|
||||
"Check the resulting GCode."))
|
||||
log.debug("appParsers.ParseExcellon.Excellon.create_geometry() -> a drill location was skipped "
|
||||
"due of not having a tool associated")
|
||||
continue
|
||||
tooldia = self.tools[drill['tool']]['C']
|
||||
poly = drill['point'].buffer(tooldia / 2.0, int(int(self.geo_steps_per_circle) / 4))
|
||||
for tool in self.tools:
|
||||
tooldia = self.tools[tool]['tooldia']
|
||||
|
||||
if 'drills' in self.tools[tool]:
|
||||
for drill in self.tools[tool]['drills']:
|
||||
poly = drill.buffer(tooldia / 2.0, int(int(self.geo_steps_per_circle) / 4))
|
||||
|
||||
# add poly in the tools geometry
|
||||
self.tools[tool]['solid_geometry'].append(poly)
|
||||
self.tools[tool]['data'] = deepcopy(self.default_data)
|
||||
|
||||
# add poly to the total solid geometry
|
||||
self.solid_geometry.append(poly)
|
||||
|
||||
tool_in_drills = drill['tool']
|
||||
self.tools[tool_in_drills]['solid_geometry'].append(poly)
|
||||
self.tools[tool_in_drills]['data'] = deepcopy(self.default_data)
|
||||
|
||||
for slot in self.slots:
|
||||
slot_tooldia = self.tools[slot['tool']]['C']
|
||||
start = slot['start']
|
||||
stop = slot['stop']
|
||||
if 'slots' in self.tools[tool]:
|
||||
for slot in self.tools[tool]['slots']:
|
||||
start = slot[0]
|
||||
stop = slot[1]
|
||||
|
||||
lines_string = LineString([start, stop])
|
||||
poly = lines_string.buffer(slot_tooldia / 2.0, int(int(self.geo_steps_per_circle) / 4))
|
||||
poly = lines_string.buffer(tooldia / 2.0, int(int(self.geo_steps_per_circle) / 4))
|
||||
|
||||
# add poly in the tools geometry
|
||||
self.tools[tool]['solid_geometry'].append(poly)
|
||||
self.tools[tool]['data'] = deepcopy(self.default_data)
|
||||
|
||||
# add poly to the total solid geometry
|
||||
self.solid_geometry.append(poly)
|
||||
|
||||
tool_in_slots = slot['tool']
|
||||
self.tools[tool_in_slots]['solid_geometry'].append(poly)
|
||||
self.tools[tool_in_slots]['data'] = deepcopy(self.default_data)
|
||||
except Exception as e:
|
||||
log.debug("appParsers.ParseExcellon.Excellon.create_geometry() -> "
|
||||
"Excellon geometry creation failed due of ERROR: %s" % str(e))
|
||||
|
@ -1126,7 +1166,7 @@ class Excellon(Geometry):
|
|||
|
||||
# Tools
|
||||
for tname in self.tools:
|
||||
self.tools[tname]["C"] *= factor
|
||||
self.tools[tname]["tooldia"] *= factor
|
||||
|
||||
self.create_geometry()
|
||||
return factor
|
||||
|
@ -1173,31 +1213,39 @@ class Excellon(Geometry):
|
|||
# variables to display the percentage of work done
|
||||
self.geo_len = 0
|
||||
try:
|
||||
self.geo_len = len(self.drills)
|
||||
self.geo_len = len(self.tools)
|
||||
except TypeError:
|
||||
self.geo_len = 1
|
||||
self.old_disp_number = 0
|
||||
self.el_count = 0
|
||||
|
||||
# Drills
|
||||
for drill in self.drills:
|
||||
drill['point'] = affinity.scale(drill['point'], xfactor, yfactor, origin=(px, py))
|
||||
for tool in self.tools:
|
||||
# Scale Drills
|
||||
if 'drills' in self.tools[tool]:
|
||||
new_drills = []
|
||||
for drill in self.tools[tool]['drills']:
|
||||
new_drills.append(affinity.scale(drill, xfactor, yfactor, origin=(px, py)))
|
||||
self.tools[tool]['drills'] = new_drills
|
||||
|
||||
# Scale Slots
|
||||
if 'slots' in self.tools[tool]:
|
||||
new_slots = []
|
||||
for slot in self.tools[tool]['slots']:
|
||||
new_start = affinity.scale(slot[0], xfactor, yfactor, origin=(px, py))
|
||||
new_stop = affinity.scale(slot[1], xfactor, yfactor, origin=(px, py))
|
||||
new_slot = (new_start, new_stop)
|
||||
new_slots.append(new_slot)
|
||||
|
||||
# Scale solid_geometry
|
||||
self.tools[tool]['solid_geometry'] = scale_geom(self.tools[tool]['solid_geometry'])
|
||||
|
||||
# update status display
|
||||
self.el_count += 1
|
||||
disp_number = int(np.interp(self.el_count, [0, self.geo_len], [0, 100]))
|
||||
if self.old_disp_number < disp_number <= 100:
|
||||
self.app.proc_container.update_view_text(' %d%%' % disp_number)
|
||||
self.old_disp_number = disp_number
|
||||
|
||||
# scale solid_geometry
|
||||
for tool in self.tools:
|
||||
self.tools[tool]['solid_geometry'] = scale_geom(self.tools[tool]['solid_geometry'])
|
||||
|
||||
# Slots
|
||||
for slot in self.slots:
|
||||
slot['stop'] = affinity.scale(slot['stop'], xfactor, yfactor, origin=(px, py))
|
||||
slot['start'] = affinity.scale(slot['start'], xfactor, yfactor, origin=(px, py))
|
||||
|
||||
self.create_geometry()
|
||||
self.app.proc_container.new_text = ''
|
||||
|
||||
|
@ -1231,31 +1279,39 @@ class Excellon(Geometry):
|
|||
# variables to display the percentage of work done
|
||||
self.geo_len = 0
|
||||
try:
|
||||
self.geo_len = len(self.drills)
|
||||
self.geo_len = len(self.tools)
|
||||
except TypeError:
|
||||
self.geo_len = 1
|
||||
self.old_disp_number = 0
|
||||
self.el_count = 0
|
||||
|
||||
# Drills
|
||||
for drill in self.drills:
|
||||
drill['point'] = affinity.translate(drill['point'], xoff=dx, yoff=dy)
|
||||
for tool in self.tools:
|
||||
# Offset Drills
|
||||
if 'drills' in self.tools[tool]:
|
||||
new_drills = []
|
||||
for drill in self.tools[tool]['drills']:
|
||||
new_drills.append(affinity.translate(drill, xoff=dx, yoff=dy))
|
||||
self.tools[tool]['drills'] = new_drills
|
||||
|
||||
# Offset Slots
|
||||
if 'slots' in self.tools[tool]:
|
||||
new_slots = []
|
||||
for slot in self.tools[tool]['slots']:
|
||||
new_start = affinity.translate(slot[0], xoff=dx, yoff=dy)
|
||||
new_stop = affinity.translate(slot[1], xoff=dx, yoff=dy)
|
||||
new_slot = (new_start, new_stop)
|
||||
new_slots.append(new_slot)
|
||||
|
||||
# Offset solid_geometry
|
||||
self.tools[tool]['solid_geometry'] = offset_geom(self.tools[tool]['solid_geometry'])
|
||||
|
||||
# update status display
|
||||
self.el_count += 1
|
||||
disp_number = int(np.interp(self.el_count, [0, self.geo_len], [0, 100]))
|
||||
if self.old_disp_number < disp_number <= 100:
|
||||
self.app.proc_container.update_view_text(' %d%%' % disp_number)
|
||||
self.old_disp_number = disp_number
|
||||
|
||||
# offset solid_geometry
|
||||
for tool in self.tools:
|
||||
self.tools[tool]['solid_geometry'] = offset_geom(self.tools[tool]['solid_geometry'])
|
||||
|
||||
# Slots
|
||||
for slot in self.slots:
|
||||
slot['stop'] = affinity.translate(slot['stop'], xoff=dx, yoff=dy)
|
||||
slot['start'] = affinity.translate(slot['start'], xoff=dx, yoff=dy)
|
||||
|
||||
# Recreate geometry
|
||||
self.create_geometry()
|
||||
self.app.proc_container.new_text = ''
|
||||
|
@ -1291,31 +1347,39 @@ class Excellon(Geometry):
|
|||
# variables to display the percentage of work done
|
||||
self.geo_len = 0
|
||||
try:
|
||||
self.geo_len = len(self.drills)
|
||||
self.geo_len = len(self.tools)
|
||||
except TypeError:
|
||||
self.geo_len = 1
|
||||
self.old_disp_number = 0
|
||||
self.el_count = 0
|
||||
|
||||
# Drills
|
||||
for drill in self.drills:
|
||||
drill['point'] = affinity.scale(drill['point'], xscale, yscale, origin=(px, py))
|
||||
for tool in self.tools:
|
||||
# Offset Drills
|
||||
if 'drills' in self.tools[tool]:
|
||||
new_drills = []
|
||||
for drill in self.tools[tool]['drills']:
|
||||
new_drills.append(affinity.scale(drill, xscale, yscale, origin=(px, py)))
|
||||
self.tools[tool]['drills'] = new_drills
|
||||
|
||||
# Offset Slots
|
||||
if 'slots' in self.tools[tool]:
|
||||
new_slots = []
|
||||
for slot in self.tools[tool]['slots']:
|
||||
new_start = affinity.scale(slot[0], xscale, yscale, origin=(px, py))
|
||||
new_stop = affinity.scale(slot[1], xscale, yscale, origin=(px, py))
|
||||
new_slot = (new_start, new_stop)
|
||||
new_slots.append(new_slot)
|
||||
|
||||
# Offset solid_geometry
|
||||
self.tools[tool]['solid_geometry'] = mirror_geom(self.tools[tool]['solid_geometry'])
|
||||
|
||||
# update status display
|
||||
self.el_count += 1
|
||||
disp_number = int(np.interp(self.el_count, [0, self.geo_len], [0, 100]))
|
||||
if self.old_disp_number < disp_number <= 100:
|
||||
self.app.proc_container.update_view_text(' %d%%' % disp_number)
|
||||
self.old_disp_number = disp_number
|
||||
|
||||
# mirror solid_geometry
|
||||
for tool in self.tools:
|
||||
self.tools[tool]['solid_geometry'] = mirror_geom(self.tools[tool]['solid_geometry'])
|
||||
|
||||
# Slots
|
||||
for slot in self.slots:
|
||||
slot['stop'] = affinity.scale(slot['stop'], xscale, yscale, origin=(px, py))
|
||||
slot['start'] = affinity.scale(slot['start'], xscale, yscale, origin=(px, py))
|
||||
|
||||
# Recreate geometry
|
||||
self.create_geometry()
|
||||
self.app.proc_container.new_text = ''
|
||||
|
@ -1361,7 +1425,7 @@ class Excellon(Geometry):
|
|||
# variables to display the percentage of work done
|
||||
self.geo_len = 0
|
||||
try:
|
||||
self.geo_len = len(self.drills)
|
||||
self.geo_len = len(self.tools)
|
||||
except TypeError:
|
||||
self.geo_len = 1
|
||||
self.old_disp_number = 0
|
||||
|
@ -1369,48 +1433,36 @@ class Excellon(Geometry):
|
|||
|
||||
if point is None:
|
||||
px, py = 0, 0
|
||||
|
||||
# Drills
|
||||
for drill in self.drills:
|
||||
drill['point'] = affinity.skew(drill['point'], angle_x, angle_y,
|
||||
origin=(px, py))
|
||||
|
||||
self.el_count += 1
|
||||
disp_number = int(np.interp(self.el_count, [0, self.geo_len], [0, 100]))
|
||||
if self.old_disp_number < disp_number <= 100:
|
||||
self.app.proc_container.update_view_text(' %d%%' % disp_number)
|
||||
self.old_disp_number = disp_number
|
||||
|
||||
# skew solid_geometry
|
||||
for tool in self.tools:
|
||||
self.tools[tool]['solid_geometry'] = skew_geom(self.tools[tool]['solid_geometry'])
|
||||
|
||||
# Slots
|
||||
for slot in self.slots:
|
||||
slot['stop'] = affinity.skew(slot['stop'], angle_x, angle_y, origin=(px, py))
|
||||
slot['start'] = affinity.skew(slot['start'], angle_x, angle_y, origin=(px, py))
|
||||
else:
|
||||
px, py = point
|
||||
# Drills
|
||||
for drill in self.drills:
|
||||
drill['point'] = affinity.skew(drill['point'], angle_x, angle_y,
|
||||
origin=(px, py))
|
||||
|
||||
for tool in self.tools:
|
||||
# Offset Drills
|
||||
if 'drills' in self.tools[tool]:
|
||||
new_drills = []
|
||||
for drill in self.tools[tool]['drills']:
|
||||
new_drills.append(affinity.skew(drill, angle_x, angle_y, origin=(px, py)))
|
||||
self.tools[tool]['drills'] = new_drills
|
||||
|
||||
# Offset Slots
|
||||
if 'slots' in self.tools[tool]:
|
||||
new_slots = []
|
||||
for slot in self.tools[tool]['slots']:
|
||||
new_start = affinity.skew(slot[0], angle_x, angle_y, origin=(px, py))
|
||||
new_stop = affinity.skew(slot[1], angle_x, angle_y, origin=(px, py))
|
||||
new_slot = (new_start, new_stop)
|
||||
new_slots.append(new_slot)
|
||||
|
||||
# Offset solid_geometry
|
||||
self.tools[tool]['solid_geometry'] = skew_geom(self.tools[tool]['solid_geometry'])
|
||||
|
||||
# update status display
|
||||
self.el_count += 1
|
||||
disp_number = int(np.interp(self.el_count, [0, self.geo_len], [0, 100]))
|
||||
if self.old_disp_number < disp_number <= 100:
|
||||
self.app.proc_container.update_view_text(' %d%%' % disp_number)
|
||||
self.old_disp_number = disp_number
|
||||
|
||||
# skew solid_geometry
|
||||
for tool in self.tools:
|
||||
self.tools[tool]['solid_geometry'] = skew_geom(self.tools[tool]['solid_geometry'])
|
||||
|
||||
# Slots
|
||||
for slot in self.slots:
|
||||
slot['stop'] = affinity.skew(slot['stop'], angle_x, angle_y, origin=(px, py))
|
||||
slot['start'] = affinity.skew(slot['start'], angle_x, angle_y, origin=(px, py))
|
||||
|
||||
self.create_geometry()
|
||||
self.app.proc_container.new_text = ''
|
||||
|
||||
|
@ -1441,59 +1493,51 @@ class Excellon(Geometry):
|
|||
return obj
|
||||
else:
|
||||
try:
|
||||
return affinity.rotate(obj, angle, origin=(px, py))
|
||||
return affinity.rotate(obj, angle, origin=orig)
|
||||
except AttributeError:
|
||||
return obj
|
||||
|
||||
# variables to display the percentage of work done
|
||||
self.geo_len = 0
|
||||
try:
|
||||
self.geo_len = len(self.drills)
|
||||
self.geo_len = len(self.tools)
|
||||
except TypeError:
|
||||
self.geo_len = 1
|
||||
self.old_disp_number = 0
|
||||
self.el_count = 0
|
||||
|
||||
if point is None:
|
||||
# Drills
|
||||
for drill in self.drills:
|
||||
drill['point'] = affinity.rotate(drill['point'], angle, origin='center')
|
||||
|
||||
# rotate solid_geometry
|
||||
for tool in self.tools:
|
||||
self.tools[tool]['solid_geometry'] = rotate_geom(self.tools[tool]['solid_geometry'], origin='center')
|
||||
|
||||
self.el_count += 1
|
||||
disp_number = int(np.interp(self.el_count, [0, self.geo_len], [0, 100]))
|
||||
if self.old_disp_number < disp_number <= 100:
|
||||
self.app.proc_container.update_view_text(' %d%%' % disp_number)
|
||||
self.old_disp_number = disp_number
|
||||
|
||||
# Slots
|
||||
for slot in self.slots:
|
||||
slot['stop'] = affinity.rotate(slot['stop'], angle, origin='center')
|
||||
slot['start'] = affinity.rotate(slot['start'], angle, origin='center')
|
||||
orig = 'center'
|
||||
else:
|
||||
px, py = point
|
||||
# Drills
|
||||
for drill in self.drills:
|
||||
drill['point'] = affinity.rotate(drill['point'], angle, origin=(px, py))
|
||||
orig = point
|
||||
|
||||
for tool in self.tools:
|
||||
# Offset Drills
|
||||
if 'drills' in self.tools[tool]:
|
||||
new_drills = []
|
||||
for drill in self.tools[tool]['drills']:
|
||||
new_drills.append(affinity.rotate(drill, angle, origin=orig))
|
||||
self.tools[tool]['drills'] = new_drills
|
||||
|
||||
# Offset Slots
|
||||
if 'slots' in self.tools[tool]:
|
||||
new_slots = []
|
||||
for slot in self.tools[tool]['slots']:
|
||||
new_start = affinity.rotate(slot[0], angle, origin=orig)
|
||||
new_stop = affinity.rotate(slot[1], angle, origin=orig)
|
||||
new_slot = (new_start, new_stop)
|
||||
new_slots.append(new_slot)
|
||||
|
||||
# Offset solid_geometry
|
||||
self.tools[tool]['solid_geometry'] = rotate_geom(self.tools[tool]['solid_geometry'], origin=orig)
|
||||
|
||||
# update status display
|
||||
self.el_count += 1
|
||||
disp_number = int(np.interp(self.el_count, [0, self.geo_len], [0, 100]))
|
||||
if self.old_disp_number < disp_number <= 100:
|
||||
self.app.proc_container.update_view_text(' %d%%' % disp_number)
|
||||
self.old_disp_number = disp_number
|
||||
|
||||
# rotate solid_geometry
|
||||
for tool in self.tools:
|
||||
self.tools[tool]['solid_geometry'] = rotate_geom(self.tools[tool]['solid_geometry'])
|
||||
|
||||
# Slots
|
||||
for slot in self.slots:
|
||||
slot['stop'] = affinity.rotate(slot['stop'], angle, origin=(px, py))
|
||||
slot['start'] = affinity.rotate(slot['start'], angle, origin=(px, py))
|
||||
|
||||
self.create_geometry()
|
||||
self.app.proc_container.new_text = ''
|
||||
|
||||
|
@ -1534,8 +1578,8 @@ class Excellon(Geometry):
|
|||
except TypeError:
|
||||
self.tools[tool]['solid_geometry'] = [res]
|
||||
if factor is None:
|
||||
self.tools[tool]['C'] += distance
|
||||
self.tools[tool]['tooldia'] += distance
|
||||
else:
|
||||
self.tools[tool]['C'] *= distance
|
||||
self.tools[tool]['tooldia'] *= distance
|
||||
|
||||
self.create_geometry()
|
||||
|
|
|
@ -613,9 +613,9 @@ class DblSidedTool(AppTool):
|
|||
return
|
||||
|
||||
tools = {}
|
||||
tools["1"] = {}
|
||||
tools["1"]["C"] = dia
|
||||
tools["1"]['solid_geometry'] = []
|
||||
tools[1] = {}
|
||||
tools[1]["tooldia"] = dia
|
||||
tools[1]['solid_geometry'] = []
|
||||
|
||||
# holes = self.alignment_holes.get_value()
|
||||
holes = eval('[{}]'.format(self.alignment_holes.text()))
|
||||
|
@ -624,21 +624,16 @@ class DblSidedTool(AppTool):
|
|||
"Add them and retry."))
|
||||
return
|
||||
|
||||
drills = []
|
||||
|
||||
for hole in holes:
|
||||
point = Point(hole)
|
||||
point_mirror = affinity.scale(point, xscale, yscale, origin=(px, py))
|
||||
|
||||
drills.append({"point": point, "tool": "1"})
|
||||
drills.append({"point": point_mirror, "tool": "1"})
|
||||
|
||||
tools["1"]['solid_geometry'].append(point)
|
||||
tools["1"]['solid_geometry'].append(point_mirror)
|
||||
tools[1]['drills'] = [point, point_mirror]
|
||||
tools[1]['solid_geometry'].append(point)
|
||||
tools[1]['solid_geometry'].append(point_mirror)
|
||||
|
||||
def obj_init(obj_inst, app_inst):
|
||||
obj_inst.tools = tools
|
||||
obj_inst.drills = drills
|
||||
obj_inst.create_geometry()
|
||||
obj_inst.source_file = app_inst.export_excellon(obj_name=obj_inst.options['name'], local_use=obj_inst,
|
||||
filename=None, use_thread=False)
|
||||
|
|
|
@ -172,7 +172,6 @@ class ToolDrilling(AppTool, Excellon):
|
|||
# ############################ SIGNALS ########################################
|
||||
# #############################################################################
|
||||
|
||||
self.ui.object_combo.currentIndexChanged.connect(self.on_object_changed)
|
||||
self.ui.apply_param_to_all.clicked.connect(self.on_apply_param_to_all_clicked)
|
||||
self.ui.generate_cnc_button.clicked.connect(self.on_cnc_button_click)
|
||||
self.ui.tools_table.drag_drop_sig.connect(self.rebuild_ui)
|
||||
|
@ -365,8 +364,6 @@ class ToolDrilling(AppTool, Excellon):
|
|||
if opt_key.find('geometry_') == 0:
|
||||
self.default_data[opt_key] = deepcopy(opt_val)
|
||||
|
||||
self.on_object_changed()
|
||||
|
||||
self.obj_name = ""
|
||||
self.excellon_obj = None
|
||||
|
||||
|
@ -382,6 +379,16 @@ class ToolDrilling(AppTool, Excellon):
|
|||
self.ui.operation_radio.set_value("drill")
|
||||
self.ui.operation_radio.setEnabled(False)
|
||||
|
||||
self.on_object_changed()
|
||||
if self.excellon_obj:
|
||||
self.build_ui()
|
||||
|
||||
try:
|
||||
self.ui.object_combo.currentIndexChanged.disconnect()
|
||||
except (AttributeError, TypeError):
|
||||
pass
|
||||
self.ui.object_combo.currentIndexChanged.connect(self.on_object_changed)
|
||||
|
||||
def rebuild_ui(self):
|
||||
# read the table tools uid
|
||||
current_uid_list = []
|
||||
|
@ -419,17 +426,8 @@ class ToolDrilling(AppTool, Excellon):
|
|||
if self.excellon_obj:
|
||||
self.ui.exc_param_frame.setDisabled(False)
|
||||
|
||||
sort = []
|
||||
for k, v in list(self.excellon_obj.tools.items()):
|
||||
sort.append((k, float('%.*f' % (self.decimals, float(v.get('C'))))))
|
||||
order = self.ui.order_radio.get_value()
|
||||
if order == 'fwd':
|
||||
sorted_tools = sorted(sort, key=lambda t1: t1[1])
|
||||
elif order == 'rev':
|
||||
sorted_tools = sorted(sort, key=lambda t1: t1[1], reverse=True)
|
||||
else:
|
||||
sorted_tools = sort
|
||||
tools = [i[0] for i in sorted_tools]
|
||||
tools = [k for k in self.excellon_tools]
|
||||
|
||||
else:
|
||||
tools = []
|
||||
|
||||
|
@ -438,30 +436,23 @@ class ToolDrilling(AppTool, Excellon):
|
|||
self.ui.tools_table.setRowCount(n + 2)
|
||||
self.tool_row = 0
|
||||
|
||||
new_options = {}
|
||||
if self.excellon_obj:
|
||||
for opt in self.excellon_obj.options:
|
||||
new_options[opt] = self.excellon_obj.options[opt]
|
||||
|
||||
for tool_no in tools:
|
||||
# add the data dictionary for each tool with the default values
|
||||
self.tools[tool_no]['data'] = deepcopy(new_options)
|
||||
|
||||
drill_cnt = 0 # variable to store the nr of drills per tool
|
||||
slot_cnt = 0 # variable to store the nr of slots per tool
|
||||
|
||||
# Find no of drills for the current tool
|
||||
for drill in self.drills:
|
||||
if drill['tool'] == tool_no:
|
||||
drill_cnt += 1
|
||||
|
||||
try:
|
||||
drill_cnt = len(self.excellon_tools[tool_no]["drills"])
|
||||
except KeyError:
|
||||
drill_cnt = 0
|
||||
self.tot_drill_cnt += drill_cnt
|
||||
|
||||
# Find no of slots for the current tool
|
||||
for slot in self.slots:
|
||||
if slot['tool'] == tool_no:
|
||||
slot_cnt += 1
|
||||
|
||||
try:
|
||||
slot_cnt = len(self.excellon_tools[tool_no]["slots"])
|
||||
except KeyError:
|
||||
slot_cnt = 0
|
||||
self.tot_slot_cnt += slot_cnt
|
||||
|
||||
# Tool name/id
|
||||
|
@ -470,7 +461,7 @@ class ToolDrilling(AppTool, Excellon):
|
|||
self.ui.tools_table.setItem(self.tool_row, 0, exc_id_item)
|
||||
|
||||
# Tool Diameter
|
||||
dia_item = QtWidgets.QTableWidgetItem('%.*f' % (self.decimals, self.tools[tool_no]['C']))
|
||||
dia_item = QtWidgets.QTableWidgetItem('%.*f' % (self.decimals, self.excellon_tools[tool_no]['tooldia']))
|
||||
dia_item.setFlags(QtCore.Qt.ItemIsEnabled)
|
||||
self.ui.tools_table.setItem(self.tool_row, 1, dia_item)
|
||||
|
||||
|
@ -496,6 +487,8 @@ class ToolDrilling(AppTool, Excellon):
|
|||
# add a last row with the Total number of drills
|
||||
empty_1 = QtWidgets.QTableWidgetItem('')
|
||||
empty_1.setFlags(~QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
|
||||
empty_1_1 = QtWidgets.QTableWidgetItem('')
|
||||
empty_1_1.setFlags(~QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
|
||||
|
||||
label_tot_drill_count = QtWidgets.QTableWidgetItem(_('Total Drills'))
|
||||
label_tot_drill_count.setFlags(QtCore.Qt.ItemIsEnabled)
|
||||
|
@ -506,6 +499,7 @@ class ToolDrilling(AppTool, Excellon):
|
|||
self.ui.tools_table.setItem(self.tool_row, 0, empty_1)
|
||||
self.ui.tools_table.setItem(self.tool_row, 1, label_tot_drill_count)
|
||||
self.ui.tools_table.setItem(self.tool_row, 2, tot_drill_count) # Total number of drills
|
||||
self.ui.tools_table.setItem(self.tool_row, 4, empty_1_1)
|
||||
|
||||
font = QtGui.QFont()
|
||||
font.setBold(True)
|
||||
|
@ -642,34 +636,14 @@ class ToolDrilling(AppTool, Excellon):
|
|||
self.excellon_obj = self.app.collection.get_by_name(self.obj_name)
|
||||
except Exception as e:
|
||||
self.app.inform.emit('[ERROR_NOTCL] %s: %s' % (_("Could not retrieve object"), str(self.obj_name)))
|
||||
return "Could not retrieve object: %s with error: %s" % (self.obj_name, str(e))
|
||||
return
|
||||
|
||||
if self.excellon_obj is None:
|
||||
self.ui.exc_param_frame.setDisabled(True)
|
||||
else:
|
||||
self.ui.exc_param_frame.setDisabled(False)
|
||||
sort = []
|
||||
for k, v in list(self.excellon_obj.tools.items()):
|
||||
sort.append((k, float('%.*f' % (self.decimals, float(v.get('C'))))))
|
||||
dias = [i[0] for i in sort]
|
||||
self.excellon_tools = self.excellon_obj.tools
|
||||
|
||||
if not dias:
|
||||
log.error("At least one tool diameter needed. Excellon object might be empty.")
|
||||
return
|
||||
|
||||
tooluid = 0
|
||||
|
||||
self.excellon_tools.clear()
|
||||
for tool_dia in dias:
|
||||
tooluid += 1
|
||||
self.excellon_tools.update({
|
||||
int(tooluid): {
|
||||
'tooldia': float('%.*f' % (self.decimals, tool_dia)),
|
||||
|
||||
'data': deepcopy(self.default_data),
|
||||
'solid_geometry': []
|
||||
}
|
||||
})
|
||||
self.build_ui()
|
||||
|
||||
def ui_connect(self):
|
||||
|
@ -809,7 +783,7 @@ class ToolDrilling(AppTool, Excellon):
|
|||
item = self.ui.tools_table.item(c_row, 3)
|
||||
if type(item) is not None:
|
||||
tooluid = item.text()
|
||||
self.storage_to_form(self.drilling_tools[str(tooluid)]['data'])
|
||||
self.storage_to_form(self.excellon_tools[str(tooluid)]['data'])
|
||||
else:
|
||||
self.blockSignals(False)
|
||||
return
|
||||
|
@ -845,8 +819,9 @@ class ToolDrilling(AppTool, Excellon):
|
|||
:return: None
|
||||
:rtype:
|
||||
"""
|
||||
if self.ui.tools_table.rowCount() == 0:
|
||||
if self.ui.tools_table.rowCount() == 2:
|
||||
# there is no tool in tool table so we can't save the GUI elements values to storage
|
||||
# Excellon Tool Table has 2 rows by default
|
||||
return
|
||||
|
||||
self.blockSignals(True)
|
||||
|
@ -862,7 +837,7 @@ class ToolDrilling(AppTool, Excellon):
|
|||
row = 0
|
||||
tooluid_item = int(self.ui.tools_table.item(row, 3).text())
|
||||
|
||||
for tooluid_key, tooluid_val in self.iso_tools.items():
|
||||
for tooluid_key, tooluid_val in self.excellon_tools.items():
|
||||
if int(tooluid_key) == tooluid_item:
|
||||
new_option_value = self.form_fields[option_changed].get_value()
|
||||
if option_changed in tooluid_val:
|
||||
|
@ -1034,7 +1009,7 @@ class ToolDrilling(AppTool, Excellon):
|
|||
|
||||
sort = []
|
||||
for k, v in self.tools.items():
|
||||
sort.append((k, v.get('C')))
|
||||
sort.append((k, v.get('tooldia')))
|
||||
sorted_tools = sorted(sort, key=lambda t1: t1[1])
|
||||
|
||||
if tools == "all":
|
||||
|
@ -1150,7 +1125,7 @@ class ToolDrilling(AppTool, Excellon):
|
|||
|
||||
sort = []
|
||||
for k, v in self.tools.items():
|
||||
sort.append((k, v.get('C')))
|
||||
sort.append((k, v.get('tooldia')))
|
||||
sorted_tools = sorted(sort, key=lambda t1: t1[1])
|
||||
|
||||
if tools == "all":
|
||||
|
|
|
@ -530,7 +530,7 @@ class ToolExtractDrills(AppTool):
|
|||
|
||||
tool_in_drills = False
|
||||
for tool, tool_val in tools.items():
|
||||
if abs(float('%.*f' % (self.decimals, tool_val["C"])) - float('%.*f' % (self.decimals, dia))) < \
|
||||
if abs(float('%.*f' % (self.decimals, tool_val["tooldia"])) - float('%.*f' % (self.decimals, dia))) < \
|
||||
(10 ** -self.decimals):
|
||||
tool_in_drills = tool
|
||||
|
||||
|
@ -615,7 +615,7 @@ class ToolExtractDrills(AppTool):
|
|||
|
||||
tool_in_drills = False
|
||||
for tool, tool_val in tools.items():
|
||||
if abs(float('%.*f' % (self.decimals, tool_val["C"])) - float('%.*f' % (self.decimals, dia))) < \
|
||||
if abs(float('%.*f' % (self.decimals, tool_val["tooldia"])) - float('%.*f' % (self.decimals, dia))) < \
|
||||
(10 ** -self.decimals):
|
||||
tool_in_drills = tool
|
||||
|
||||
|
|
|
@ -397,16 +397,14 @@ class Properties(AppTool):
|
|||
slot_cnt = 0 # variable to store the nr of slots per tool
|
||||
|
||||
# Find no of drills for the current tool
|
||||
for drill in obj.drills:
|
||||
if drill['tool'] == tool:
|
||||
drill_cnt += 1
|
||||
if 'drills' in value and value['drills']:
|
||||
drill_cnt = len(value['drills'])
|
||||
|
||||
tot_drill_cnt += drill_cnt
|
||||
|
||||
# Find no of slots for the current tool
|
||||
for slot in obj.slots:
|
||||
if slot['tool'] == tool:
|
||||
slot_cnt += 1
|
||||
if 'slots' in value and value['slots']:
|
||||
slot_cnt = len(value['slots'])
|
||||
|
||||
tot_slot_cnt += slot_cnt
|
||||
|
||||
|
@ -414,7 +412,7 @@ class Properties(AppTool):
|
|||
toolid,
|
||||
[
|
||||
_('Diameter'),
|
||||
'%.*f %s' % (self.decimals, value['C'], self.app.defaults['units'].lower())
|
||||
'%.*f %s' % (self.decimals, value['tooldia'], self.app.defaults['units'].lower())
|
||||
],
|
||||
True
|
||||
)
|
||||
|
|
|
@ -558,7 +558,7 @@ class ToolPunchGerber(AppTool):
|
|||
# make it work only for Gerber Flashes who are Points in 'follow'
|
||||
if 'solid' in elem and isinstance(elem['follow'], Point):
|
||||
for drill in exc_obj.drills:
|
||||
clear_apid_size = exc_obj.tools[drill['tool']]['C']
|
||||
clear_apid_size = exc_obj.tools[drill['tool']]['tooldia']
|
||||
|
||||
# since there may be drills that do not drill into a pad we test only for drills in a pad
|
||||
if drill['point'].within(elem['solid']):
|
||||
|
|
31
app_Main.py
31
app_Main.py
|
@ -2314,7 +2314,20 @@ class App(QtCore.QObject):
|
|||
self.ui.tool_scroll_area.takeWidget()
|
||||
|
||||
# delete the old object (the source object) if it was an empty one
|
||||
if len(edited_obj.drills) == 0 and len(edited_obj.slots) == 0:
|
||||
# find if we have drills:
|
||||
has_drills = None
|
||||
for tt in edited_obj.tools:
|
||||
if 'drills' in edited_obj.tools[tt] and edited_obj.tools[tt]['drills']:
|
||||
has_drills = True
|
||||
break
|
||||
# find if we have slots:
|
||||
has_slots = None
|
||||
for tt in edited_obj.tools:
|
||||
if 'slots' in edited_obj.tools[tt] and edited_obj.tools[tt]['slots']:
|
||||
has_slots = True
|
||||
slots_in_file = 1
|
||||
break
|
||||
if has_drills is None and has_slots is None:
|
||||
old_name = edited_obj.options['name']
|
||||
self.collection.delete_by_name(name=old_name)
|
||||
self.inform.emit('[success] %s' % _("Editor exited. Editor content saved."))
|
||||
|
@ -8230,11 +8243,11 @@ class App(QtCore.QObject):
|
|||
|
||||
for tool in obj.tools:
|
||||
if eunits == 'METRIC':
|
||||
header += "T{tool}F00S00C{:.{dec}f}\n".format(float(obj.tools[tool]['C']) * factor,
|
||||
header += "T{tool}F00S00C{:.{dec}f}\n".format(float(obj.tools[tool]['tooldia']) * factor,
|
||||
tool=str(tool),
|
||||
dec=2)
|
||||
else:
|
||||
header += "T{tool}F00S00C{:.{dec}f}\n".format(float(obj.tools[tool]['C']) * factor,
|
||||
header += "T{tool}F00S00C{:.{dec}f}\n".format(float(obj.tools[tool]['tooldia']) * factor,
|
||||
tool=str(tool),
|
||||
dec=4)
|
||||
else:
|
||||
|
@ -8247,11 +8260,13 @@ class App(QtCore.QObject):
|
|||
|
||||
for tool in obj.tools:
|
||||
if eunits == 'METRIC':
|
||||
header += "T{tool}F00S00C{:.{dec}f}\n".format(float(obj.tools[tool]['C']) * factor,
|
||||
header += "T{tool}F00S00C{:.{dec}f}\n".format(
|
||||
float(obj.tools[tool]['tooldia']) * factor,
|
||||
tool=str(tool),
|
||||
dec=2)
|
||||
else:
|
||||
header += "T{tool}F00S00C{:.{dec}f}\n".format(float(obj.tools[tool]['C']) * factor,
|
||||
header += "T{tool}F00S00C{:.{dec}f}\n".format(
|
||||
float(obj.tools[tool]['tooldia']) * factor,
|
||||
tool=str(tool),
|
||||
dec=4)
|
||||
else:
|
||||
|
@ -8263,11 +8278,13 @@ class App(QtCore.QObject):
|
|||
|
||||
for tool in obj.tools:
|
||||
if eunits == 'METRIC':
|
||||
header += "T{tool}F00S00C{:.{dec}f}\n".format(float(obj.tools[tool]['C']) * factor,
|
||||
header += "T{tool}F00S00C{:.{dec}f}\n".format(
|
||||
float(obj.tools[tool]['tooldia']) * factor,
|
||||
tool=str(tool),
|
||||
dec=2)
|
||||
else:
|
||||
header += "T{tool}F00S00C{:.{dec}f}\n".format(float(obj.tools[tool]['C']) * factor,
|
||||
header += "T{tool}F00S00C{:.{dec}f}\n".format(
|
||||
float(obj.tools[tool]['tooldia']) * factor,
|
||||
tool=str(tool),
|
||||
dec=4)
|
||||
header += '%\n'
|
||||
|
|
178
camlib.py
178
camlib.py
|
@ -2555,8 +2555,6 @@ class CNCjob(Geometry):
|
|||
# here store the routing time
|
||||
self.routing_time = 0.0
|
||||
|
||||
# used for creating drill CCode geometry; will be updated in the generate_from_excellon_by_tool()
|
||||
self.exc_drills = None
|
||||
# store here the Excellon source object tools to be accessible locally
|
||||
self.exc_tools = None
|
||||
|
||||
|
@ -2710,8 +2708,7 @@ class CNCjob(Geometry):
|
|||
:rtype: None
|
||||
"""
|
||||
|
||||
# create a local copy of the exobj.drills so it can be used for creating drill CCode geometry
|
||||
self.exc_drills = deepcopy(exobj.drills)
|
||||
# create a local copy of the exobj.tools so it can be used for creating drill CCode geometry
|
||||
self.exc_tools = deepcopy(exobj.tools)
|
||||
|
||||
# the Excellon GCode preprocessor will use this info in the start_code() method
|
||||
|
@ -2774,8 +2771,8 @@ class CNCjob(Geometry):
|
|||
# sorted_tools = sorted(exobj.tools.items(), key=lambda t1: t1['C'])
|
||||
|
||||
sort = []
|
||||
for k, v in list(exobj.tools.items()):
|
||||
sort.append((k, v.get('C')))
|
||||
for k, v in list(self.exc_tools.items()):
|
||||
sort.append((int(k), v['tooldia']))
|
||||
sorted_tools = sorted(sort, key=lambda t1: t1[1])
|
||||
|
||||
if tools == "all":
|
||||
|
@ -2783,7 +2780,7 @@ class CNCjob(Geometry):
|
|||
log.debug("Tools 'all' and sorted are: %s" % str(tools))
|
||||
else:
|
||||
selected_tools = [x.strip() for x in tools.split(",")] # we strip spaces and also separate the tools by ','
|
||||
selected_tools = [t1 for t1 in selected_tools if t1 in selected_tools]
|
||||
selected_tools = [int(t1) for t1 in selected_tools if t1 in selected_tools]
|
||||
|
||||
# Create a sorted list of selected tools from the sorted_tools list
|
||||
tools = [i for i, j in sorted_tools for k in selected_tools if i == k]
|
||||
|
@ -2803,18 +2800,20 @@ class CNCjob(Geometry):
|
|||
for it in sorted_tools:
|
||||
for to_ol in tools:
|
||||
if to_ol == it[0]:
|
||||
drill_no = 0
|
||||
sol_geo = []
|
||||
for dr in exobj.drills:
|
||||
if dr['tool'] == it[0]:
|
||||
drill_no += 1
|
||||
sol_geo.append(dr['point'])
|
||||
|
||||
drill_no = 0
|
||||
if 'drills' in exobj.tools[to_ol]:
|
||||
drill_no = len(exobj.tools[to_ol]['drills'])
|
||||
for drill in exobj.tools[to_ol]['drills']:
|
||||
sol_geo.append(drill.buffer((it[1] / 2.0), resolution=self.geo_steps_per_circle))
|
||||
|
||||
slot_no = 0
|
||||
for dr in exobj.slots:
|
||||
if dr['tool'] == it[0]:
|
||||
slot_no += 1
|
||||
start = (dr['start'].x, dr['start'].y)
|
||||
stop = (dr['stop'].x, dr['stop'].y)
|
||||
if 'slots' in exobj.tools[to_ol]:
|
||||
slot_no = len(exobj.tools[to_ol]['slots'])
|
||||
for slot in exobj.tools[to_ol]['slots']:
|
||||
start = (slot[0].x, slot[0].y)
|
||||
stop = (slot[1].x, slot[1].y)
|
||||
sol_geo.append(
|
||||
LineString([start, stop]).buffer((it[1] / 2.0), resolution=self.geo_steps_per_circle)
|
||||
)
|
||||
|
@ -2850,25 +2849,26 @@ class CNCjob(Geometry):
|
|||
|
||||
# Points (Group by tool): a dictionary of shapely Point geo elements grouped by tool number
|
||||
points = {}
|
||||
for drill in exobj.drills:
|
||||
for tool, tool_dict in self.exc_tools.items():
|
||||
if self.app.abort_flag:
|
||||
# graceful abort requested by the user
|
||||
raise grace
|
||||
|
||||
if drill['tool'] in tools:
|
||||
if 'drills' in tool_dict and tool_dict['drills']:
|
||||
for drill_pt in tool_dict['drills']:
|
||||
try:
|
||||
points[drill['tool']].append(drill['point'])
|
||||
points[tool].append(drill_pt)
|
||||
except KeyError:
|
||||
points[drill['tool']] = [drill['point']]
|
||||
points[tool] = [drill_pt]
|
||||
|
||||
# log.debug("Found %d drills." % len(points))
|
||||
log.debug("Found %d TOOLS." % len(points))
|
||||
|
||||
# check if there are drill points in the exclusion areas.
|
||||
# If we find any within the exclusion areas return 'fail'
|
||||
for tool in points:
|
||||
for pt in points[tool]:
|
||||
for area in self.app.exc_areas.exclusion_areas_storage:
|
||||
pt_buf = pt.buffer(exobj.tools[tool]['C'] / 2.0)
|
||||
pt_buf = pt.buffer(self.exc_tools[tool]['tooldia'] / 2.0)
|
||||
if pt_buf.within(area['shape']) or pt_buf.intersects(area['shape']):
|
||||
self.app.inform.emit("[ERROR_NOTCL] %s" % _("Failed. Drill points inside the exclusion zones."))
|
||||
return 'fail'
|
||||
|
@ -2954,22 +2954,28 @@ class CNCjob(Geometry):
|
|||
used_excellon_optimization_type = self.excellon_optimization_type
|
||||
if used_excellon_optimization_type == 'M':
|
||||
log.debug("Using OR-Tools Metaheuristic Guided Local Search drill path optimization.")
|
||||
if exobj.drills:
|
||||
|
||||
has_drills = None
|
||||
for tool, tool_dict in self.exc_tools.items():
|
||||
if 'drills' in tool_dict and tool_dict['drills']:
|
||||
has_drills = True
|
||||
break
|
||||
if has_drills:
|
||||
for tool in tools:
|
||||
if self.app.abort_flag:
|
||||
# graceful abort requested by the user
|
||||
raise grace
|
||||
|
||||
self.tool = tool
|
||||
self.postdata['toolC'] = exobj.tools[tool]["C"]
|
||||
self.tooldia = exobj.tools[tool]["C"]
|
||||
self.tooldia = self.exc_tools[tool]["tooldia"]
|
||||
self.postdata['toolC'] = self.tooldia
|
||||
|
||||
if self.use_ui:
|
||||
self.z_feedrate = exobj.tools[tool]['data']['feedrate_z']
|
||||
self.feedrate = exobj.tools[tool]['data']['feedrate']
|
||||
self.z_feedrate = self.exc_tools[tool]['data']['feedrate_z']
|
||||
self.feedrate = self.exc_tools[tool]['data']['feedrate']
|
||||
gcode += self.doformat(p.z_feedrate_code)
|
||||
|
||||
self.z_cut = exobj.tools[tool]['data']['cutz']
|
||||
self.z_cut = self.exc_tools[tool]['data']['cutz']
|
||||
|
||||
if self.machinist_setting == 0:
|
||||
if self.z_cut > 0:
|
||||
|
@ -2991,12 +2997,12 @@ class CNCjob(Geometry):
|
|||
|
||||
old_zcut = deepcopy(self.z_cut)
|
||||
|
||||
self.z_move = exobj.tools[tool]['data']['travelz']
|
||||
self.spindlespeed = exobj.tools[tool]['data']['spindlespeed']
|
||||
self.dwell = exobj.tools[tool]['data']['dwell']
|
||||
self.dwelltime = exobj.tools[tool]['data']['dwelltime']
|
||||
self.multidepth = exobj.tools[tool]['data']['multidepth']
|
||||
self.z_depthpercut = exobj.tools[tool]['data']['depthperpass']
|
||||
self.z_move = self.exc_tools[tool]['data']['travelz']
|
||||
self.spindlespeed = self.exc_tools[tool]['data']['spindlespeed']
|
||||
self.dwell = self.exc_tools[tool]['data']['dwell']
|
||||
self.dwelltime = self.exc_tools[tool]['data']['dwelltime']
|
||||
self.multidepth = self.exc_tools[tool]['data']['multidepth']
|
||||
self.z_depthpercut = self.exc_tools[tool]['data']['depthperpass']
|
||||
else:
|
||||
old_zcut = deepcopy(self.z_cut)
|
||||
|
||||
|
@ -3085,7 +3091,7 @@ class CNCjob(Geometry):
|
|||
if self.dwell is True:
|
||||
gcode += self.doformat(p.dwell_code) # Dwell time
|
||||
|
||||
current_tooldia = float('%.*f' % (self.decimals, float(exobj.tools[tool]["C"])))
|
||||
current_tooldia = float('%.*f' % (self.decimals, float(self.exc_tools[tool]["tooldia"])))
|
||||
|
||||
self.app.inform.emit(
|
||||
'%s: %s%s.' % (_("Starting G-Code for tool with diameter"),
|
||||
|
@ -3098,7 +3104,7 @@ class CNCjob(Geometry):
|
|||
# because the values for Z offset are created in build_ui()
|
||||
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
try:
|
||||
z_offset = float(exobj.tools[tool]['data']['offset']) * (-1)
|
||||
z_offset = float(self.exc_tools[tool]['data']['offset']) * (-1)
|
||||
except KeyError:
|
||||
z_offset = 0
|
||||
self.z_cut = z_offset + old_zcut
|
||||
|
@ -3138,7 +3144,7 @@ class CNCjob(Geometry):
|
|||
gcode += self.doformat(p.lift_code, x=locx, y=locy)
|
||||
|
||||
# restore z_move
|
||||
self.z_move = exobj.tools[tool]['data']['travelz']
|
||||
self.z_move = self.exc_tools[tool]['data']['travelz']
|
||||
else:
|
||||
if prev_z is not None:
|
||||
# move to next point
|
||||
|
@ -3146,7 +3152,7 @@ class CNCjob(Geometry):
|
|||
|
||||
# we assume that previously the z_move was altered therefore raise to
|
||||
# the travel_z (z_move)
|
||||
self.z_move = exobj.tools[tool]['data']['travelz']
|
||||
self.z_move = self.exc_tools[tool]['data']['travelz']
|
||||
gcode += self.doformat(p.lift_code, x=locx, y=locy)
|
||||
else:
|
||||
# move to next point
|
||||
|
@ -3218,21 +3224,28 @@ class CNCjob(Geometry):
|
|||
|
||||
if used_excellon_optimization_type == 'B':
|
||||
log.debug("Using OR-Tools Basic drill path optimization.")
|
||||
if exobj.drills:
|
||||
|
||||
has_drills = None
|
||||
for tool, tool_dict in self.exc_tools.items():
|
||||
if 'drills' in tool_dict and tool_dict['drills']:
|
||||
has_drills = True
|
||||
break
|
||||
|
||||
if has_drills:
|
||||
for tool in tools:
|
||||
if self.app.abort_flag:
|
||||
# graceful abort requested by the user
|
||||
raise grace
|
||||
|
||||
self.tool = tool
|
||||
self.postdata['toolC'] = exobj.tools[tool]["C"]
|
||||
self.tooldia = exobj.tools[tool]["C"]
|
||||
self.tooldia = self.exc_tools[tool]["tooldia"]
|
||||
self.postdata['toolC'] = self.tooldia
|
||||
|
||||
if self.use_ui:
|
||||
self.z_feedrate = exobj.tools[tool]['data']['feedrate_z']
|
||||
self.feedrate = exobj.tools[tool]['data']['feedrate']
|
||||
self.z_feedrate = self.exc_tools[tool]['data']['feedrate_z']
|
||||
self.feedrate = self.exc_tools[tool]['data']['feedrate']
|
||||
gcode += self.doformat(p.z_feedrate_code)
|
||||
self.z_cut = exobj.tools[tool]['data']['cutz']
|
||||
self.z_cut = self.exc_tools[tool]['data']['cutz']
|
||||
|
||||
if self.machinist_setting == 0:
|
||||
if self.z_cut > 0:
|
||||
|
@ -3254,13 +3267,13 @@ class CNCjob(Geometry):
|
|||
|
||||
old_zcut = deepcopy(self.z_cut)
|
||||
|
||||
self.z_move = exobj.tools[tool]['data']['travelz']
|
||||
self.z_move = self.exc_tools[tool]['data']['travelz']
|
||||
|
||||
self.spindlespeed = exobj.tools[tool]['data']['spindlespeed']
|
||||
self.dwell = exobj.tools[tool]['data']['dwell']
|
||||
self.dwelltime = exobj.tools[tool]['data']['dwelltime']
|
||||
self.multidepth = exobj.tools[tool]['data']['multidepth']
|
||||
self.z_depthpercut = exobj.tools[tool]['data']['depthperpass']
|
||||
self.spindlespeed = self.exc_tools[tool]['data']['spindlespeed']
|
||||
self.dwell = self.exc_tools[tool]['data']['dwell']
|
||||
self.dwelltime = self.exc_tools[tool]['data']['dwelltime']
|
||||
self.multidepth = self.exc_tools[tool]['data']['multidepth']
|
||||
self.z_depthpercut = self.exc_tools[tool]['data']['depthperpass']
|
||||
else:
|
||||
old_zcut = deepcopy(self.z_cut)
|
||||
|
||||
|
@ -3338,7 +3351,7 @@ class CNCjob(Geometry):
|
|||
if self.dwell is True:
|
||||
gcode += self.doformat(p.dwell_code) # Dwell time
|
||||
|
||||
current_tooldia = float('%.*f' % (self.decimals, float(exobj.tools[tool]["C"])))
|
||||
current_tooldia = float('%.*f' % (self.decimals, float(self.exc_tools[tool]["tooldia"])))
|
||||
|
||||
self.app.inform.emit(
|
||||
'%s: %s%s.' % (_("Starting G-Code for tool with diameter"),
|
||||
|
@ -3351,7 +3364,7 @@ class CNCjob(Geometry):
|
|||
# because the values for Z offset are created in build_ui()
|
||||
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
try:
|
||||
z_offset = float(exobj.tools[tool]['data']['offset']) * (-1)
|
||||
z_offset = float(self.exc_tools[tool]['data']['offset']) * (-1)
|
||||
except KeyError:
|
||||
z_offset = 0
|
||||
self.z_cut = z_offset + old_zcut
|
||||
|
@ -3390,7 +3403,7 @@ class CNCjob(Geometry):
|
|||
gcode += self.doformat(p.lift_code, x=locx, y=locy)
|
||||
|
||||
# restore z_move
|
||||
self.z_move = exobj.tools[tool]['data']['travelz']
|
||||
self.z_move = self.exc_tools[tool]['data']['travelz']
|
||||
else:
|
||||
if prev_z is not None:
|
||||
# move to next point
|
||||
|
@ -3398,7 +3411,7 @@ class CNCjob(Geometry):
|
|||
|
||||
# we assume that previously the z_move was altered therefore raise to
|
||||
# the travel_z (z_move)
|
||||
self.z_move = exobj.tools[tool]['data']['travelz']
|
||||
self.z_move = self.exc_tools[tool]['data']['travelz']
|
||||
gcode += self.doformat(p.lift_code, x=locx, y=locy)
|
||||
else:
|
||||
# move to next point
|
||||
|
@ -3473,22 +3486,29 @@ class CNCjob(Geometry):
|
|||
|
||||
if used_excellon_optimization_type == 'T':
|
||||
log.debug("Using Travelling Salesman drill path optimization.")
|
||||
|
||||
has_drills = None
|
||||
for tool, tool_dict in self.exc_tools.items():
|
||||
if 'drills' in tool_dict and tool_dict['drills']:
|
||||
has_drills = True
|
||||
break
|
||||
|
||||
for tool in tools:
|
||||
if self.app.abort_flag:
|
||||
# graceful abort requested by the user
|
||||
raise grace
|
||||
|
||||
if exobj.drills:
|
||||
if has_drills:
|
||||
self.tool = tool
|
||||
self.postdata['toolC'] = exobj.tools[tool]["C"]
|
||||
self.tooldia = exobj.tools[tool]["C"]
|
||||
self.tooldia = self.exc_tools[tool]["tooldia"]
|
||||
self.postdata['toolC'] = self.tooldia
|
||||
|
||||
if self.use_ui:
|
||||
self.z_feedrate = exobj.tools[tool]['data']['feedrate_z']
|
||||
self.feedrate = exobj.tools[tool]['data']['feedrate']
|
||||
self.z_feedrate = self.exc_tools[tool]['data']['feedrate_z']
|
||||
self.feedrate = self.exc_tools[tool]['data']['feedrate']
|
||||
gcode += self.doformat(p.z_feedrate_code)
|
||||
|
||||
self.z_cut = exobj.tools[tool]['data']['cutz']
|
||||
self.z_cut = self.exc_tools[tool]['data']['cutz']
|
||||
|
||||
if self.machinist_setting == 0:
|
||||
if self.z_cut > 0:
|
||||
|
@ -3510,12 +3530,12 @@ class CNCjob(Geometry):
|
|||
|
||||
old_zcut = deepcopy(self.z_cut)
|
||||
|
||||
self.z_move = exobj.tools[tool]['data']['travelz']
|
||||
self.spindlespeed = exobj.tools[tool]['data']['spindlespeed']
|
||||
self.dwell = exobj.tools[tool]['data']['dwell']
|
||||
self.dwelltime = exobj.tools[tool]['data']['dwelltime']
|
||||
self.multidepth = exobj.tools[tool]['data']['multidepth']
|
||||
self.z_depthpercut = exobj.tools[tool]['data']['depthperpass']
|
||||
self.z_move = self.exc_tools[tool]['data']['travelz']
|
||||
self.spindlespeed = self.exc_tools[tool]['data']['spindlespeed']
|
||||
self.dwell = self.exc_tools[tool]['data']['dwell']
|
||||
self.dwelltime = self.exc_tools[tool]['data']['dwelltime']
|
||||
self.multidepth = self.exc_tools[tool]['data']['multidepth']
|
||||
self.z_depthpercut = self.exc_tools[tool]['data']['depthperpass']
|
||||
else:
|
||||
old_zcut = deepcopy(self.z_cut)
|
||||
|
||||
|
@ -3536,7 +3556,7 @@ class CNCjob(Geometry):
|
|||
if self.dwell is True:
|
||||
gcode += self.doformat(p.dwell_code) # Dwell time
|
||||
|
||||
current_tooldia = float('%.*f' % (self.decimals, float(exobj.tools[tool]["C"])))
|
||||
current_tooldia = float('%.*f' % (self.decimals, float(self.exc_tools[tool]["tooldia"])))
|
||||
|
||||
self.app.inform.emit(
|
||||
'%s: %s%s.' % (_("Starting G-Code for tool with diameter"),
|
||||
|
@ -3549,7 +3569,7 @@ class CNCjob(Geometry):
|
|||
# because the values for Z offset are created in build_ui()
|
||||
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
try:
|
||||
z_offset = float(exobj.tools[tool]['data']['offset']) * (-1)
|
||||
z_offset = float(self.exc_tools[tool]['data']['offset']) * (-1)
|
||||
except KeyError:
|
||||
z_offset = 0
|
||||
self.z_cut = z_offset + old_zcut
|
||||
|
@ -3593,7 +3613,7 @@ class CNCjob(Geometry):
|
|||
gcode += self.doformat(p.lift_code, x=locx, y=locy)
|
||||
|
||||
# restore z_move
|
||||
self.z_move = exobj.tools[tool]['data']['travelz']
|
||||
self.z_move = self.exc_tools[tool]['data']['travelz']
|
||||
else:
|
||||
if prev_z is not None:
|
||||
# move to next point
|
||||
|
@ -3601,7 +3621,7 @@ class CNCjob(Geometry):
|
|||
|
||||
# we assume that previously the z_move was altered therefore raise to
|
||||
# the travel_z (z_move)
|
||||
self.z_move = exobj.tools[tool]['data']['travelz']
|
||||
self.z_move = self.exc_tools[tool]['data']['travelz']
|
||||
gcode += self.doformat(p.lift_code, x=locx, y=locy)
|
||||
else:
|
||||
# move to next point
|
||||
|
@ -3687,6 +3707,7 @@ class CNCjob(Geometry):
|
|||
self.routing_time += lift_time + traveled_time
|
||||
|
||||
self.gcode = gcode
|
||||
|
||||
self.app.inform.emit(_("Finished G-Code generation..."))
|
||||
return 'OK'
|
||||
|
||||
|
@ -4914,14 +4935,16 @@ class CNCjob(Geometry):
|
|||
)
|
||||
|
||||
# find the drill diameter knowing the drill coordinates
|
||||
for pt_dict in self.exc_drills:
|
||||
break_loop = False
|
||||
for tool, tool_dict in self.exc_tools.items():
|
||||
if 'drills' in tool_dict:
|
||||
for drill_pt in tool_dict['drills']:
|
||||
point_in_dict_coords = (
|
||||
float('%.*f' % (self.decimals, pt_dict['point'].x)),
|
||||
float('%.*f' % (self.decimals, pt_dict['point'].y))
|
||||
float('%.*f' % (self.decimals, drill_pt.x)),
|
||||
float('%.*f' % (self.decimals, drill_pt.y))
|
||||
)
|
||||
if point_in_dict_coords == current_drill_point_coords:
|
||||
tool = pt_dict['tool']
|
||||
dia = self.exc_tools[tool]['C']
|
||||
dia = self.exc_tools[tool]['tooldia']
|
||||
kind = ['C', 'F']
|
||||
geometry.append(
|
||||
{
|
||||
|
@ -4929,6 +4952,9 @@ class CNCjob(Geometry):
|
|||
"kind": kind
|
||||
}
|
||||
)
|
||||
break_loop = True
|
||||
break
|
||||
if break_loop:
|
||||
break
|
||||
|
||||
if 'G' in gobj:
|
||||
|
|
|
@ -48,7 +48,7 @@ class Berta_CNC(PreProc):
|
|||
elif str(p['options']['type']) == 'Excellon' and p['use_ui'] is True:
|
||||
gcode += '\n(TOOLS DIAMETER: )\n'
|
||||
for tool, val in p['exc_tools'].items():
|
||||
gcode += '(Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["C"]) + ')\n'
|
||||
gcode += '(Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["tooldia"]) + ')\n'
|
||||
|
||||
gcode += '\n(FEEDRATE Z: )\n'
|
||||
for tool, val in p['exc_tools'].items():
|
||||
|
|
|
@ -38,7 +38,7 @@ class ISEL_CNC(PreProc):
|
|||
elif str(p['options']['type']) == 'Excellon' and p['use_ui'] is True:
|
||||
gcode += '\n(TOOLS DIAMETER: )\n'
|
||||
for tool, val in p['exc_tools'].items():
|
||||
gcode += '(Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["C"]) + ')\n'
|
||||
gcode += '(Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["tooldia"]) + ')\n'
|
||||
|
||||
gcode += '\n(FEEDRATE Z: )\n'
|
||||
for tool, val in p['exc_tools'].items():
|
||||
|
|
|
@ -38,7 +38,7 @@ class ISEL_ICP_CNC(PreProc):
|
|||
elif str(p['options']['type']) == 'Excellon' and p['use_ui'] is True:
|
||||
gcode += '\n;TOOLS DIAMETER: \n'
|
||||
for tool, val in p['exc_tools'].items():
|
||||
gcode += ';Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["C"]) + '\n'
|
||||
gcode += ';Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["tooldia"]) + '\n'
|
||||
|
||||
gcode += '\n;FEEDRATE Z: \n'
|
||||
for tool, val in p['exc_tools'].items():
|
||||
|
|
|
@ -40,7 +40,7 @@ class Marlin(PreProc):
|
|||
elif str(p['options']['type']) == 'Excellon' and p['use_ui'] is True:
|
||||
gcode += '\n;TOOLS DIAMETER: \n'
|
||||
for tool, val in p['exc_tools'].items():
|
||||
gcode += ';Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["C"]) + '\n'
|
||||
gcode += ';Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["tooldia"]) + '\n'
|
||||
|
||||
gcode += '\n;FEEDRATE Z: \n'
|
||||
for tool, val in p['exc_tools'].items():
|
||||
|
|
|
@ -40,7 +40,7 @@ class Repetier(PreProc):
|
|||
elif str(p['options']['type']) == 'Excellon' and p['use_ui'] is True:
|
||||
gcode += '\n;TOOLS DIAMETER: \n'
|
||||
for tool, val in p['exc_tools'].items():
|
||||
gcode += ';Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["C"]) + '\n'
|
||||
gcode += ';Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["tooldia"]) + '\n'
|
||||
|
||||
gcode += '\n;FEEDRATE Z: \n'
|
||||
for tool, val in p['exc_tools'].items():
|
||||
|
|
|
@ -39,7 +39,7 @@ class Toolchange_Custom(PreProc):
|
|||
elif str(p['options']['type']) == 'Excellon' and p['use_ui'] is True:
|
||||
gcode += '\n(TOOLS DIAMETER: )\n'
|
||||
for tool, val in p['exc_tools'].items():
|
||||
gcode += '(Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["C"]) + ')\n'
|
||||
gcode += '(Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["tooldia"]) + ')\n'
|
||||
|
||||
gcode += '\n(FEEDRATE Z: )\n'
|
||||
for tool, val in p['exc_tools'].items():
|
||||
|
|
|
@ -39,7 +39,7 @@ class Toolchange_Manual(PreProc):
|
|||
elif str(p['options']['type']) == 'Excellon' and p['use_ui'] is True:
|
||||
gcode += '\n(TOOLS DIAMETER: )\n'
|
||||
for tool, val in p['exc_tools'].items():
|
||||
gcode += '(Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["C"]) + ')\n'
|
||||
gcode += '(Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["tooldia"]) + ')\n'
|
||||
|
||||
gcode += '\n(FEEDRATE Z: )\n'
|
||||
for tool, val in p['exc_tools'].items():
|
||||
|
|
|
@ -39,7 +39,7 @@ class Toolchange_Probe_MACH3(PreProc):
|
|||
elif str(p['options']['type']) == 'Excellon' and p['use_ui'] is True:
|
||||
gcode += '\n(TOOLS DIAMETER: )\n'
|
||||
for tool, val in p['exc_tools'].items():
|
||||
gcode += '(Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["C"]) + ')\n'
|
||||
gcode += '(Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["tooldia"]) + ')\n'
|
||||
|
||||
gcode += '\n(FEEDRATE Z: )\n'
|
||||
for tool, val in p['exc_tools'].items():
|
||||
|
|
|
@ -40,7 +40,7 @@ class default(PreProc):
|
|||
elif str(p['options']['type']) == 'Excellon' and p['use_ui'] is True:
|
||||
gcode += '\n(TOOLS DIAMETER: )\n'
|
||||
for tool, val in p['exc_tools'].items():
|
||||
gcode += '(Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["C"]) + ')\n'
|
||||
gcode += '(Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["tooldia"]) + ')\n'
|
||||
|
||||
gcode += '\n(FEEDRATE Z: )\n'
|
||||
for tool, val in p['exc_tools'].items():
|
||||
|
|
|
@ -40,7 +40,7 @@ class grbl_11(PreProc):
|
|||
elif str(p['options']['type']) == 'Excellon' and p['use_ui'] is True:
|
||||
gcode += '\n(TOOLS DIAMETER: )\n'
|
||||
for tool, val in p['exc_tools'].items():
|
||||
gcode += '(Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["C"]) + ')\n'
|
||||
gcode += '(Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["tooldia"]) + ')\n'
|
||||
|
||||
gcode += '\n(FEEDRATE Z: )\n'
|
||||
for tool, val in p['exc_tools'].items():
|
||||
|
|
|
@ -39,7 +39,7 @@ class line_xyz(PreProc):
|
|||
elif str(p['options']['type']) == 'Excellon' and p['use_ui'] is True:
|
||||
gcode += '\n(TOOLS DIAMETER: )\n'
|
||||
for tool, val in p['exc_tools'].items():
|
||||
gcode += '(Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["C"]) + ')\n'
|
||||
gcode += '(Tool: %s -> ' % str(tool) + 'Dia: %s' % str(val["tooldia"]) + ')\n'
|
||||
|
||||
gcode += '\n(FEEDRATE Z: )\n'
|
||||
for tool, val in p['exc_tools'].items():
|
||||
|
|
|
@ -198,25 +198,23 @@ class TclCommandDrillcncjob(TclCommandSignaled):
|
|||
if tools == 'all':
|
||||
sort = []
|
||||
for k, v in list(obj.tools.items()):
|
||||
sort.append((k, v.get('C')))
|
||||
sort.append((k, v.get('tooldia')))
|
||||
sorted_tools = sorted(sort, key=lambda t1: t1[1])
|
||||
use_tools = [i[0] for i in sorted_tools]
|
||||
|
||||
for tool_no in use_tools:
|
||||
tool_dia_used = obj.tools[tool_no]['C']
|
||||
tool_dia_used = obj.tools[tool_no]['tooldia']
|
||||
|
||||
drill_cnt = 0 # variable to store the nr of drills per tool
|
||||
slot_cnt = 0 # variable to store the nr of slots per tool
|
||||
|
||||
# Find no of drills for the current tool
|
||||
for drill in obj.drills:
|
||||
if drill['tool'] == tool_no:
|
||||
drill_cnt += 1
|
||||
if 'drills' in obj.tools[tool_no] and obj.tools[tool_no]['drills']:
|
||||
drill_cnt = len(obj.tools[tool_no]['drills'])
|
||||
|
||||
# Find no of slots for the current tool
|
||||
for slot in obj.slots:
|
||||
if slot['tool'] == tool_no:
|
||||
slot_cnt += 1
|
||||
if 'slots' in obj.tools[tool_no] and obj.tools[tool_no]['slots']:
|
||||
slot_cnt = len(obj.tools[tool_no]['slots'])
|
||||
|
||||
used_tools_info.append([str(tool_no), str(tool_dia_used), str(drill_cnt), str(slot_cnt)])
|
||||
|
||||
|
|
Loading…
Reference in New Issue