From a1c1f9dbd094c0627a454b729334d3032c19771a Mon Sep 17 00:00:00 2001 From: Joris Burger <33052142+joburger@users.noreply.github.com> Date: Mon, 4 Apr 2022 16:14:06 +0200 Subject: [PATCH 1/8] Changed the method that compas slicer checks for installed packages --- .vscode/settings.json | 1 - src/compas_slicer/post_processing/simplify_paths_rdp.py | 6 +----- .../slicers/planar_slicing/planar_slicing_cgal.py | 7 +++---- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index b7e254a5..391bbf6c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,5 +2,4 @@ "python.linting.pylintEnabled": false, "python.linting.flake8Enabled": true, "python.linting.enabled": true, - "python.pythonPath": "C:\\Users\\joburger\\Anaconda3\\envs\\compas_slicer\\python.exe" } \ No newline at end of file diff --git a/src/compas_slicer/post_processing/simplify_paths_rdp.py b/src/compas_slicer/post_processing/simplify_paths_rdp.py index 8d3937af..e8978069 100644 --- a/src/compas_slicer/post_processing/simplify_paths_rdp.py +++ b/src/compas_slicer/post_processing/simplify_paths_rdp.py @@ -6,10 +6,6 @@ import compas_slicer.utilities as utils from compas.plugins import PluginNotInstalledError -packages = utils.TerminalCommand('conda list').get_split_output_strings() -if 'igl' in packages: - import igl - logger = logging.getLogger('logger') __all__ = ['simplify_paths_rdp', @@ -55,7 +51,7 @@ def simplify_paths_rdp_igl(slicer, threshold): Low threshold removes few points, high threshold removes many points. """ try: - utils.check_package_is_installed('igl') + import igl logger.info("Paths simplification rdp - igl") remaining_pts_num = 0 diff --git a/src/compas_slicer/slicers/planar_slicing/planar_slicing_cgal.py b/src/compas_slicer/slicers/planar_slicing/planar_slicing_cgal.py index baee5d57..8aa9425e 100644 --- a/src/compas_slicer/slicers/planar_slicing/planar_slicing_cgal.py +++ b/src/compas_slicer/slicers/planar_slicing/planar_slicing_cgal.py @@ -4,7 +4,6 @@ from compas_slicer.geometry import Path import progressbar import logging -import compas_slicer.utilities as utils from compas.plugins import PluginNotInstalledError logger = logging.getLogger('logger') @@ -21,17 +20,17 @@ def create_planar_paths_cgal(mesh, planes): A compas mesh. planes: list, :class: 'compas.geometry.Plane' """ - packages = utils.TerminalCommand('conda list').get_split_output_strings() - if 'compas-cgal' in packages or 'compas_cgal' in packages: + try: from compas_cgal.slicer import slice_mesh - else: + except: raise PluginNotInstalledError("--------ATTENTION! ----------- \ Compas_cgal library is missing! \ You can't use this planar slicing method without it. \ Check the README instructions for how to install it, \ or use another planar slicing method.") + # prepare mesh for slicing M = mesh.to_vertices_and_faces() From af33b3233d78ac35e4d7de3d040180933c0fb8e6 Mon Sep 17 00:00:00 2001 From: Joris Burger <33052142+joburger@users.noreply.github.com> Date: Mon, 4 Apr 2022 23:47:20 +0200 Subject: [PATCH 2/8] Added layer/path index to the PrintPoint attributes. --- src/compas_slicer/geometry/print_point.py | 7 +++++++ .../print_organization/planar_print_organizer.py | 3 +++ 2 files changed, 10 insertions(+) diff --git a/src/compas_slicer/geometry/print_point.py b/src/compas_slicer/geometry/print_point.py index 17d68170..5f04eab1 100644 --- a/src/compas_slicer/geometry/print_point.py +++ b/src/compas_slicer/geometry/print_point.py @@ -42,6 +42,10 @@ def __init__(self, pt, layer_height, mesh_normal): self.pt = pt self.layer_height = layer_height + # --- layer, path index attributes + self.layer_index = None + self.path_index = None + self.mesh_normal = mesh_normal # compas.geometry.Vector self.up_vector = Vector(0, 0, 1) # default value that can be updated self.frame = self.get_frame() # compas.geometry.Frame @@ -90,6 +94,9 @@ def to_data(self): 'point': [self.pt[0], self.pt[1], self.pt[2]], 'layer_height': self.layer_height, + 'layer_index': self.layer_index, + 'path_index': self.path_index, + 'mesh_normal': self.mesh_normal.to_data(), 'up_vector': self.up_vector.to_data(), 'frame': self.frame.to_data(), diff --git a/src/compas_slicer/print_organization/planar_print_organizer.py b/src/compas_slicer/print_organization/planar_print_organizer.py index cb37689b..4bbd32d7 100644 --- a/src/compas_slicer/print_organization/planar_print_organizer.py +++ b/src/compas_slicer/print_organization/planar_print_organizer.py @@ -60,6 +60,9 @@ def create_printpoints(self, generate_mesh_normals=True): n = normals[count] if generate_mesh_normals else Vector(0, 0, 1) printpoint = PrintPoint(pt=point, layer_height=self.slicer.layer_height, mesh_normal=n) + printpoint.layer_index = i + printpoint.path_index = j + self.printpoints_dict['layer_%d' % i]['path_%d' % j].append(printpoint) bar.update(count) count += 1 From d2bebbe0161190764afe28ba80c49ed9ec1badfd Mon Sep 17 00:00:00 2001 From: Joris Burger <33052142+joburger@users.noreply.github.com> Date: Fri, 6 May 2022 18:44:18 +0200 Subject: [PATCH 3/8] Bug in unify paths orientation --- .../post_processing/unify_paths_orientation.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/compas_slicer/post_processing/unify_paths_orientation.py b/src/compas_slicer/post_processing/unify_paths_orientation.py index d0bbb84b..fa830651 100644 --- a/src/compas_slicer/post_processing/unify_paths_orientation.py +++ b/src/compas_slicer/post_processing/unify_paths_orientation.py @@ -19,14 +19,15 @@ def unify_paths_orientation(slicer): for i, layer in enumerate(slicer.layers): for j, path in enumerate(layer.paths): - reference_points = None # find reference points for each path, if possible - if j > 0: - reference_points = layer.paths[0].points - elif i > 0 and j == 0: - reference_points = slicer.layers[i - 1].paths[0].points - - if reference_points: # then reorient current pts based on reference - path.points = match_paths_orientations(path.points, reference_points, path.is_closed) + if path.is_closed: + reference_points = None # find reference points for each path, if possible + if j > 0: + reference_points = layer.paths[0].points + elif i > 0 and j == 0: + reference_points = slicer.layers[i - 1].paths[0].points + + if reference_points: # then reorient current pts based on reference + path.points = match_paths_orientations(path.points, reference_points, path.is_closed) def match_paths_orientations(pts, reference_points, is_closed): From 95b104d374d4e30951e0166af95f9ade556832c7 Mon Sep 17 00:00:00 2001 From: Joris Burger <33052142+joburger@users.noreply.github.com> Date: Fri, 6 May 2022 18:44:45 +0200 Subject: [PATCH 4/8] Added reverse_open_paths argument to minium travel time --- .../sort_paths_minimum_travel_time.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/compas_slicer/post_processing/sort_paths_minimum_travel_time.py b/src/compas_slicer/post_processing/sort_paths_minimum_travel_time.py index 50f15a5b..dab2cae2 100644 --- a/src/compas_slicer/post_processing/sort_paths_minimum_travel_time.py +++ b/src/compas_slicer/post_processing/sort_paths_minimum_travel_time.py @@ -8,7 +8,7 @@ __all__ = ['sort_paths_minimum_travel_time'] -def sort_paths_minimum_travel_time(slicer): +def sort_paths_minimum_travel_time(slicer, reverse_open_paths=False): """Sorts the paths within a horizontal layer to reduce total travel time. Parameters @@ -23,7 +23,7 @@ def sort_paths_minimum_travel_time(slicer): for i, layer in enumerate(slicer.layers): sorted_paths = [] while len(layer.paths) > 0: - index = closest_path(ref_point, layer.paths) # find the closest path to the reference point + index = closest_path(ref_point, layer.paths, reverse_open_paths) # find the closest path to the reference point sorted_paths.append(layer.paths[index]) # add the closest path to the sorted list ref_point = layer.paths[index].points[-1] layer.paths.pop(index) @@ -31,7 +31,7 @@ def sort_paths_minimum_travel_time(slicer): slicer.layers[i].paths = sorted_paths -def adjust_seam_to_closest_pos(ref_point, path): +def adjust_seam_to_closest_pos(ref_point, path, reverse_open_paths): """Aligns the seam (start- and endpoint) of a contour so that it is closest to a given point. for open paths, check if the end point closest to the reference point is the start point @@ -57,11 +57,12 @@ def adjust_seam_to_closest_pos(ref_point, path): path.points = adjusted_seam else: # if path is open # if end point is closer than start point >> flip - if distance_point_point(ref_point, path.points[0]) > distance_point_point(ref_point, path.points[-1]): - path.points.reverse() + if reverse_open_paths: + if distance_point_point(ref_point, path.points[0]) > distance_point_point(ref_point, path.points[-1]): + path.points.reverse() -def closest_path(ref_point, somepaths): +def closest_path(ref_point, somepaths, reverse_open_paths): """Finds the closest path to a reference point in a list of paths. Parameters @@ -74,7 +75,7 @@ def closest_path(ref_point, somepaths): for i, path in enumerate(somepaths): # for each path, adjust the seam to be in the closest vertex to ref_point - adjust_seam_to_closest_pos(ref_point, path) + adjust_seam_to_closest_pos(ref_point, path, reverse_open_paths) # calculate the minimum distance to the nearest seam of each path min_dist_temp = distance_point_point(ref_point, path.points[0]) if min_dist_temp < min_dist: From 4848b5a79b808fee75c94326fc1d4b96e5951007 Mon Sep 17 00:00:00 2001 From: Joris Burger <33052142+joburger@users.noreply.github.com> Date: Fri, 6 May 2022 18:44:55 +0200 Subject: [PATCH 5/8] Added reverse_open_paths argument to seams_align --- .../post_processing/seams_align.py | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/compas_slicer/post_processing/seams_align.py b/src/compas_slicer/post_processing/seams_align.py index d5063d0a..31e5db66 100644 --- a/src/compas_slicer/post_processing/seams_align.py +++ b/src/compas_slicer/post_processing/seams_align.py @@ -8,7 +8,7 @@ __all__ = ['seams_align'] -def seams_align(slicer, align_with="next_path"): +def seams_align(slicer, align_with="next_path", reverse_open_paths=False): """Aligns the seams (start- and endpoint) of a print. Parameters @@ -39,24 +39,23 @@ def seams_align(slicer, align_with="next_path"): # determines the correct point to align the current path with if len(layer.paths) == 1 and i == 0: # if ONE PATH and FIRST LAYER - # >>> align with second layer - pt_to_align_with = slicer.layers[i + 1].paths[0].points[0] + # >>> align with first point of first layer (no change) + pt_to_align_with = slicer.layers[0].paths[0].points[0] if len(layer.paths) == 1 and i != 0: - last_path_index = len(slicer.layers[i - 1].paths) - 1 # if ONE PATH and NOT FIRST LAYER - # >>> align with previous layer - pt_to_align_with = slicer.layers[i - 1].paths[last_path_index].points[-1] + # >>> align with last point of previous layer + pt_to_align_with = slicer.layers[i - 1].paths[0].points[-1] if len(layer.paths) != 1 and i == 0 and j == 0: # if MULTIPLE PATHS and FIRST LAYER and FIRST PATH - # >>> align with second path of first layer + # >>> align with last point of next path of first layer pt_to_align_with = slicer.layers[i].paths[i + 1].points[-1] if len(layer.paths) != 1 and j != 0: # if MULTIPLE PATHS and NOT FIRST PATH - # >>> align with previous path + # >>> align with last point of previous path pt_to_align_with = slicer.layers[i].paths[j - 1].points[-1] if len(layer.paths) != 1 and i != 0 and j == 0: - # if MULTIPLE PATHS and NOT FIRST LAYER and FIRST PATH - # >>> align with first path of previous layer + # if MULTIPLE PATHS and NOT FIRST LAYER and NOT FIRST PATH + # >>> align with last point of previous path of previous layer last_path_index = len(slicer.layers[i - 1].paths) - 1 pt_to_align_with = slicer.layers[i - 1].paths[last_path_index].points[-1] @@ -74,7 +73,7 @@ def seams_align(slicer, align_with="next_path"): # CLOSED PATHS if path.is_closed: # get the points of the current layer and path - path_to_change = layer.paths[j].points + path_to_change = path.points # check if start- and end-points are the same point if path_to_change[0] == path_to_change[-1]: @@ -94,11 +93,11 @@ def seams_align(slicer, align_with="next_path"): if first_last_point_the_same: shift_list = shift_list + [shift_list[0]] - layer.paths[j].points = shift_list + path.points = shift_list else: # OPEN PATHS - path_to_change = layer.paths[j].points + path_to_change = path.points # get the distance between the align point and the start/end point start = path_to_change[0] @@ -107,8 +106,11 @@ def seams_align(slicer, align_with="next_path"): d_end = distance_point_point(end, pt_to_align_with) # if closer to end point > reverse list - if d_start > d_end: - layer.paths[j].points.reverse() + if reverse_open_paths: + if d_start > d_end: + path.points.reverse() + + if __name__ == "__main__": From 47f6881d1f8ea48f784c05bcc9d73cfeb7a8fff9 Mon Sep 17 00:00:00 2001 From: Joris Burger <33052142+joburger@users.noreply.github.com> Date: Fri, 6 May 2022 18:44:59 +0200 Subject: [PATCH 6/8] Update CHANGELOG.rst --- CHANGELOG.rst | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 31297d8b..763d69d4 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -11,14 +11,16 @@ Unreleased **Added** * Output nested printpoints +* Added reverse_open_paths argument to seams_align to control if the direction of open paths should be reversed or not. Defaults to False. +* Added reverse_open_paths argument to sort_paths_minimum_travel_time to control if the direction of open paths should be reversed or not. Defaults to False. **Changed** -* Updates in the visualization of PrintPoints -* Added seams_align(next_path) to the standard planar slicing routine -* Added unify_path_orientation back into the standard planar slicing routine - +* Updates in the visualization of PrintPoints. +* Added seams_align(next_path) to the standard planar slicing routine. +* Added unify_path_orientation back into the standard planar slicing routine. **Fixed** +* Changed unify_path_orientation to only work for closed paths. **Deprecated** From 8fe14208b9fecb345bffe99060267ed1d704c721 Mon Sep 17 00:00:00 2001 From: Joris Burger <33052142+joburger@users.noreply.github.com> Date: Fri, 6 May 2022 19:13:53 +0200 Subject: [PATCH 7/8] Flake8 --- src/compas_slicer/post_processing/seams_align.py | 2 -- src/compas_slicer/post_processing/simplify_paths_rdp.py | 1 - .../slicers/planar_slicing/planar_slicing_cgal.py | 3 +-- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/compas_slicer/post_processing/seams_align.py b/src/compas_slicer/post_processing/seams_align.py index 31e5db66..5fdb9170 100644 --- a/src/compas_slicer/post_processing/seams_align.py +++ b/src/compas_slicer/post_processing/seams_align.py @@ -111,7 +111,5 @@ def seams_align(slicer, align_with="next_path", reverse_open_paths=False): path.points.reverse() - - if __name__ == "__main__": pass diff --git a/src/compas_slicer/post_processing/simplify_paths_rdp.py b/src/compas_slicer/post_processing/simplify_paths_rdp.py index e8978069..212d8d63 100644 --- a/src/compas_slicer/post_processing/simplify_paths_rdp.py +++ b/src/compas_slicer/post_processing/simplify_paths_rdp.py @@ -3,7 +3,6 @@ import logging import progressbar from compas.geometry import Point -import compas_slicer.utilities as utils from compas.plugins import PluginNotInstalledError logger = logging.getLogger('logger') diff --git a/src/compas_slicer/slicers/planar_slicing/planar_slicing_cgal.py b/src/compas_slicer/slicers/planar_slicing/planar_slicing_cgal.py index 8aa9425e..d15fbeaf 100644 --- a/src/compas_slicer/slicers/planar_slicing/planar_slicing_cgal.py +++ b/src/compas_slicer/slicers/planar_slicing/planar_slicing_cgal.py @@ -23,14 +23,13 @@ def create_planar_paths_cgal(mesh, planes): try: from compas_cgal.slicer import slice_mesh - except: + except Exception: raise PluginNotInstalledError("--------ATTENTION! ----------- \ Compas_cgal library is missing! \ You can't use this planar slicing method without it. \ Check the README instructions for how to install it, \ or use another planar slicing method.") - # prepare mesh for slicing M = mesh.to_vertices_and_faces() From a652a162784f3f65a82000b98c69e7a2cd161c8a Mon Sep 17 00:00:00 2001 From: Joris Burger <33052142+joburger@users.noreply.github.com> Date: Fri, 6 May 2022 19:51:12 +0200 Subject: [PATCH 8/8] Docstrings --- src/compas_slicer/post_processing/seams_align.py | 2 ++ .../post_processing/sort_paths_minimum_travel_time.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/compas_slicer/post_processing/seams_align.py b/src/compas_slicer/post_processing/seams_align.py index 5fdb9170..21a115e4 100644 --- a/src/compas_slicer/post_processing/seams_align.py +++ b/src/compas_slicer/post_processing/seams_align.py @@ -22,6 +22,8 @@ def seams_align(slicer, align_with="next_path", reverse_open_paths=False): x_axis = orients the seam to the x_axis y_axis = orients the seam to the y_axis Point(x,y,z) = orients the seam according to the given point + reverse_open_paths: bool (defaults to False) + Boolean toggle whether to reverse the direction of open paths or not. Returns ------- diff --git a/src/compas_slicer/post_processing/sort_paths_minimum_travel_time.py b/src/compas_slicer/post_processing/sort_paths_minimum_travel_time.py index dab2cae2..9dc7a865 100644 --- a/src/compas_slicer/post_processing/sort_paths_minimum_travel_time.py +++ b/src/compas_slicer/post_processing/sort_paths_minimum_travel_time.py @@ -15,6 +15,8 @@ def sort_paths_minimum_travel_time(slicer, reverse_open_paths=False): ---------- slicer: :class:`compas_slicer.slicers.BaseSlicer` An instance of one of the compas_slicer.slicers classes. + reverse_open_paths: bool (defaults to False) + Boolean toggle whether to reverse the direction of open paths or not. """ logger.info("Sorting contours to minimize travel time")