From 7eb393c13f5b25ea60c4c2a172a91f2fe4212a08 Mon Sep 17 00:00:00 2001 From: Jelle Feringa Date: Fri, 8 Sep 2023 16:24:10 +0200 Subject: [PATCH] topology sorting isn't always that robust, especially when creating paths that have variable layer heights / rely on `InterpolationPrintOrganizer`. this handles the exceptions and informs the user. the resulting output potentially is helpful in debugging the toolpath, hence handling the exceptions makes sense --- .../interpolation_print_organizer.py | 57 +++++++++++++------ .../extruder_toggle.py | 26 ++++++--- .../safety_printpoints.py | 7 ++- 3 files changed, 62 insertions(+), 28 deletions(-) diff --git a/src/compas_slicer/print_organization/interpolation_print_organizer.py b/src/compas_slicer/print_organization/interpolation_print_organizer.py index 93c0b72f..ac8e7885 100644 --- a/src/compas_slicer/print_organization/interpolation_print_organizer.py +++ b/src/compas_slicer/print_organization/interpolation_print_organizer.py @@ -44,7 +44,13 @@ def __init__(self, slicer, parameters, DATA_PATH): # topological sorting of vertical layers depending on their connectivity self.topo_sort_graph = None if len(self.vertical_layers) > 1: - self.topological_sorting() + try: + self.topological_sorting() + except AssertionError as e: + logger.exception("topology sorting failed\n") + logger.critical("integrity of the output data ") + # TODO: perhaps its better to be even more explicit and add a + # FAILED-timestamp.txt file? self.selected_order = None # creation of one base boundary per vertical_layer @@ -67,20 +73,29 @@ def create_base_boundaries(self): root_vs = utils.get_mesh_vertex_coords_with_attribute(self.slicer.mesh, 'boundary', 1) root_boundary = BaseBoundary(self.slicer.mesh, [Point(*v) for v in root_vs]) - if len(self.vertical_layers) > 1: - for i, vertical_layer in enumerate(self.vertical_layers): - parents_of_current_node = self.topo_sort_graph.get_parents_of_node(i) - if len(parents_of_current_node) == 0: - boundary = root_boundary - else: - boundary_pts = [] - for parent_index in parents_of_current_node: - parent = self.vertical_layers[parent_index] - boundary_pts.extend(parent.paths[-1].points) - boundary = BaseBoundary(self.slicer.mesh, boundary_pts) - bs.append(boundary) + if self.topo_sort_graph: + if len(self.vertical_layers) > 1: + for i, vertical_layer in enumerate(self.vertical_layers): + parents_of_current_node = self.topo_sort_graph.get_parents_of_node(i) + if len(parents_of_current_node) == 0: + boundary = root_boundary + else: + boundary_pts = [] + for parent_index in parents_of_current_node: + parent = self.vertical_layers[parent_index] + boundary_pts.extend(parent.paths[-1].points) + boundary = BaseBoundary(self.slicer.mesh, boundary_pts) + bs.append(boundary) + else: + bs.append(root_boundary) else: - bs.append(root_boundary) + logger.critical("""no topology graph was created, no base boundaries created, + output will be degenerated. + + a likely cause for topology sorting to fail is that + non-continuous paths were created. When creating paths with variable + layer heights, it may very well be that the non-continuous paths are + created, while this is not yet a supported feature""") # save intermediary outputs b_data = {i: b.to_data() for i, b in enumerate(bs)} @@ -109,8 +124,13 @@ def create_printpoints(self): # (2) --- Select order of vertical layers if len(self.vertical_layers) > 1: # the you need to select one topological order - all_orders = self.topo_sort_graph.get_all_topological_orders() - self.selected_order = all_orders[0] # TODO: add more elaborate selection strategy + + if not self.topo_sort_graph: + logger.error("no topology graph found, cannnot set the order of vertical layers") + self.selected_order = [0] + else: + all_orders = self.topo_sort_graph.get_all_topological_orders() + self.selected_order = all_orders[0] # TODO: add more elaborate selection strategy else: self.selected_order = [0] # there is only one segment, only this option @@ -118,7 +138,10 @@ def create_printpoints(self): for index, i in enumerate(self.selected_order): layer = self.vertical_layers[i] self.printpoints_dict['layer_%d' % current_layer_index] = {} - self.printpoints_dict['layer_%d' % current_layer_index] = self.get_layer_ppts(layer, self.base_boundaries[i]) + try: + self.printpoints_dict['layer_%d' % current_layer_index] = self.get_layer_ppts(layer, self.base_boundaries[i]) + except IndexError: + logging.exception("no layer print points found for layer %d" % current_layer_index) current_layer_index += 1 def get_layer_ppts(self, layer, base_boundary): diff --git a/src/compas_slicer/print_organization/print_organization_utilities/extruder_toggle.py b/src/compas_slicer/print_organization/print_organization_utilities/extruder_toggle.py index ea091a46..cd089085 100644 --- a/src/compas_slicer/print_organization/print_organization_utilities/extruder_toggle.py +++ b/src/compas_slicer/print_organization/print_organization_utilities/extruder_toggle.py @@ -53,21 +53,29 @@ def set_extruder_toggle(print_organizer, slicer): interrupt_path = True # --- create extruder toggles - path_printpoints = pp_dict[layer_key][path_key] - for k, printpoint in enumerate(path_printpoints): - - if interrupt_path: - if k == len(path_printpoints) - 1: - printpoint.extruder_toggle = False + try: + path_printpoints = pp_dict[layer_key][path_key] + except KeyError: + logger.exception("no path found for layer %s" % layer_key) + else: + for k, printpoint in enumerate(path_printpoints): + + if interrupt_path: + if k == len(path_printpoints) - 1: + printpoint.extruder_toggle = False + else: + printpoint.extruder_toggle = True else: printpoint.extruder_toggle = True - else: - printpoint.extruder_toggle = True # set extruder toggle of last print point to false last_layer_key = 'layer_%d' % (len(pp_dict) - 1) last_path_key = 'path_%d' % (len(pp_dict[last_layer_key]) - 1) - pp_dict[last_layer_key][last_path_key][-1].extruder_toggle = False + try: + pp_dict[last_layer_key][last_path_key][-1].extruder_toggle = False + except KeyError as e: + logger.exception(e) + def override_extruder_toggle(print_organizer, override_value): diff --git a/src/compas_slicer/print_organization/print_organization_utilities/safety_printpoints.py b/src/compas_slicer/print_organization/print_organization_utilities/safety_printpoints.py index cf220e2a..0710da20 100644 --- a/src/compas_slicer/print_organization/print_organization_utilities/safety_printpoints.py +++ b/src/compas_slicer/print_organization/print_organization_utilities/safety_printpoints.py @@ -49,8 +49,11 @@ def add_safety_printpoints(print_organizer, z_hop=10.0): pp_copy_dict[layer_key][path_key].append(create_safety_printpoint(next_ppt, z_hop, False)) # finally, insert a safety print point at the beginning of the entire print - safety_printpoint = create_safety_printpoint(pp_dict['layer_0']['path_0'][0], z_hop, False) - pp_copy_dict['layer_0']['path_0'].insert(0, safety_printpoint) + try: + safety_printpoint = create_safety_printpoint(pp_dict['layer_0']['path_0'][0], z_hop, False) + pp_copy_dict['layer_0']['path_0'].insert(0, safety_printpoint) + except KeyError as e: + logger.exception(e) # the safety printpoint has already been added at the end since the last printpoint extruder_toggle_type is False print_organizer.printpoints_dict = pp_copy_dict