From 755aa48490003b2c509ebc59fe43668a0a771a42 Mon Sep 17 00:00:00 2001 From: Marius Stanciu Date: Thu, 18 Jun 2020 20:24:02 +0300 Subject: [PATCH] - Panelize Tool - fixed to work for panelizing Excellon objects with the new data structure storing drills and tools in the obj.tools dictionary --- CHANGELOG.md | 7 +-- appParsers/ParseExcellon.py | 9 ++++ appTools/ToolPanelize.py | 104 +++++++++++++++++++----------------- 3 files changed, 68 insertions(+), 52 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e3a739ca..76cff061 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,12 +10,13 @@ CHANGELOG for FlatCAM beta 18.06.2020 - fixed bug in the Cutout Tool that did not allowed the manual cutous to be added on a Geometry created in the Tool -- fixed bug that made the selection box show in the stage of adding manual gaps +- fixed bug in Cutout Tool that made the selection box show in the stage of adding manual gaps - updated Cutout Tool UI - Cutout Tool - in manual gap adding there is now an option to automatically turn on the big cursor which could help - Cutout Tool - fixed errors when trying to add a manual gap without having a geometry object selected in the combobox -- Cutout Tool - made sure that all the paths generated by this tool are contiguous which means that two lines that meet at one end will become onle line therefore reducing unnecessary Z moves -- Panelize Tool - add a new option for the panels of type Geometry named Path Optimiztion. If the checkbox is checked then all the LineStrings that are overlapped in the resulting multigeo Geometry panel object will keep only one of the paths thus minimizing the tool cuts. +- Cutout Tool - made sure that all the paths generated by this tool are contiguous which means that two lines that meet at one end will become only one line therefore reducing unnecessary Z moves +- Panelize Tool - added a new option for the panels of type Geometry named Path Optimization. If the checkbox is checked then all the LineStrings that are overlapped in the resulting multigeo Geometry panel object will keep only one of the paths thus minimizing the tool cuts. +- Panelize Tool - fixed to work for panelizing Excellon objects with the new data structure storing drills and tools in the obj.tools dictionary 17.06.2020 diff --git a/appParsers/ParseExcellon.py b/appParsers/ParseExcellon.py index a9a7cefb..31cf8486 100644 --- a/appParsers/ParseExcellon.py +++ b/appParsers/ParseExcellon.py @@ -957,6 +957,15 @@ class Excellon(Geometry): # is finished since the tools definitions are spread in the Excellon body. We use as units the value # from self.defaults['excellon_units'] + # the data structure of the Excellon object has to include bot the 'drills' and the 'slots' keys otherwise + # I will need to test for them everywhere. + # Even if there are not drills or slots I just add the storage there with an empty list + for tool in self.tools: + if 'drills' not in self.tools[tool]: + self.tools[tool]['drills'] = [] + if 'slots' not in self.tools[tool]: + self.tools[tool]['slots'] = [] + log.info("Zeros: %s, Units %s." % (self.zeros, self.units)) except Exception: log.error("Excellon PARSING FAILED. Line %d: %s" % (line_num, eline)) diff --git a/appTools/ToolPanelize.py b/appTools/ToolPanelize.py index 9358aa43..0221f22b 100644 --- a/appTools/ToolPanelize.py +++ b/appTools/ToolPanelize.py @@ -273,9 +273,11 @@ class Panelize(AppTool): def job_init_excellon(obj_fin, app_obj): currenty = 0.0 + # init the storage for drills and for slots + for tool in copied_tools: + copied_tools[tool]['drills'] = [] + copied_tools[tool]['slots'] = [] obj_fin.tools = copied_tools - obj_fin.drills = [] - obj_fin.slots = [] obj_fin.solid_geometry = [] for option in panel_source_obj.options: @@ -285,9 +287,14 @@ class Panelize(AppTool): except KeyError: log.warning("Failed to copy option. %s" % str(option)) - geo_len_drills = len(panel_source_obj.drills) if panel_source_obj.drills else 0 - geo_len_slots = len(panel_source_obj.slots) if panel_source_obj.slots else 0 + # calculate the total number of drills and slots + geo_len_drills = 0 + geo_len_slots = 0 + for tool in copied_tools: + geo_len_drills += len(copied_tools[tool]['drills']) + geo_len_slots += len(copied_tools[tool]['slots']) + # panelization element = 0 for row in range(rows): currentx = 0.0 @@ -295,57 +302,53 @@ class Panelize(AppTool): element += 1 old_disp_number = 0 - if panel_source_obj.drills: - drill_nr = 0 - for tool_dict in panel_source_obj.drills: - if self.app.abort_flag: + for tool in panel_source_obj.tools: + if panel_source_obj.tools[tool]['drills']: + drill_nr = 0 + for drill in panel_source_obj.tools[tool]['drills']: # graceful abort requested by the user - raise grace + if self.app.abort_flag: + raise grace - point_offseted = affinity.translate(tool_dict['point'], currentx, currenty) - obj_fin.drills.append( - { - "point": point_offseted, - "tool": tool_dict['tool'] - } - ) + # offset / panelization + point_offseted = affinity.translate(drill, currentx, currenty) + obj_fin.tools[tool]['drills'].append(point_offseted) - drill_nr += 1 - disp_number = int(np.interp(drill_nr, [0, geo_len_drills], [0, 100])) + # update progress + drill_nr += 1 + disp_number = int(np.interp(drill_nr, [0, geo_len_drills], [0, 100])) + if old_disp_number < disp_number <= 100: + self.app.proc_container.update_view_text(' %s: %d D:%d%%' % + (_("Copy"), + int(element), + disp_number)) + old_disp_number = disp_number - if old_disp_number < disp_number <= 100: - self.app.proc_container.update_view_text(' %s: %d D:%d%%' % - (_("Copy"), - int(element), - disp_number)) - old_disp_number = disp_number - - if panel_source_obj.slots: - slot_nr = 0 - for tool_dict in panel_source_obj.slots: - if self.app.abort_flag: + if panel_source_obj.tools[tool]['slots']: + slot_nr = 0 + for slot in panel_source_obj.tools[tool]['slots']: # graceful abort requested by the user - raise grace + if self.app.abort_flag: + raise grace - start_offseted = affinity.translate(tool_dict['start'], currentx, currenty) - stop_offseted = affinity.translate(tool_dict['stop'], currentx, currenty) - obj_fin.slots.append( - { - "start": start_offseted, - "stop": stop_offseted, - "tool": tool_dict['tool'] - } - ) + # offset / panelization + start_offseted = affinity.translate(slot[0], currentx, currenty) + stop_offseted = affinity.translate(slot[1], currentx, currenty) + offseted_slot = ( + start_offseted, + stop_offseted + ) + obj_fin.tools[tool]['slots'].append(offseted_slot) - slot_nr += 1 - disp_number = int(np.interp(slot_nr, [0, geo_len_slots], [0, 100])) - - if old_disp_number < disp_number <= 100: - self.app.proc_container.update_view_text(' %s: %d S:%d%%' % - (_("Copy"), - int(element), - disp_number)) - old_disp_number = disp_number + # update progress + slot_nr += 1 + disp_number = int(np.interp(slot_nr, [0, geo_len_slots], [0, 100])) + if old_disp_number < disp_number <= 100: + self.app.proc_container.update_view_text(' %s: %d S:%d%%' % + (_("Copy"), + int(element), + disp_number)) + old_disp_number = disp_number currentx += lenghtx currenty += lenghty @@ -420,7 +423,10 @@ class Panelize(AppTool): raise grace # calculate the number of polygons - geo_len = len(panel_source_obj.tools[tool]['solid_geometry']) + try: + geo_len = len(panel_source_obj.tools[tool]['solid_geometry']) + except TypeError: + geo_len = 1 # panelization pol_nr = 0