Source code for compas_slicer.post_processing.reorder_vertical_layers


import logging
import itertools

from compas.geometry import Point, distance_point_point

logger = logging.getLogger('logger')

__all__ = ['reorder_vertical_layers']


[docs]def reorder_vertical_layers(slicer, align_with): """Re-orders the vertical layers in a specific way Parameters ---------- slicer: :class:`compas_slicer.slicers.BaseSlicer` An instance of one of the compas_slicer.slicers classes. align_with: str or :class:`compas.geometry.Point` x_axis = reorders the vertical layers starting from the positive x-axis y_axis = reorders the vertical layers starting from the positive y-axis Point(x,y,z) = reorders the vertical layers starting from a given Point """ if align_with == "x_axis": align_pt = Point(2 ** 32, 0, 0) elif align_with == "y_axis": align_pt = Point(0, 2 ** 32, 0) elif isinstance(align_with, Point): align_pt = align_with else: raise NameError("Unknown align_with : " + str(align_with)) logger.info("Re-ordering vertical layers to start with the vertical layer closest to: %s" % align_with) for layer in slicer.layers: assert layer.min_max_z_height[0] is not None and layer.min_max_z_height[1] is not None, \ "To use the 'reorder_vertical_layers function you need first to calculate the layers' z_bounds. To do " \ "that use the function 'Layer.calculate_z_bounds()'" # group vertical layers based on the min_max_z_height grouped_iter = itertools.groupby(slicer.layers, lambda x: x.min_max_z_height) grouped_layer_list = [list(group) for _key, group in grouped_iter] reordered_layers = [] for grouped_layers in grouped_layer_list: distances = [] for vert_layer in grouped_layers: # recreate head_centroid_pt as compas.Point head_centroid_pt = Point(vert_layer.head_centroid[0], vert_layer.head_centroid[1], vert_layer.head_centroid[2]) # measure distance distances.append(distance_point_point(head_centroid_pt, align_pt)) # sort lists based on closest distance to align pt grouped_new = [x for _, x in sorted(zip(distances, grouped_layers))] reordered_layers.append(grouped_new) # flatten list slicer.layers = [item for sublist in reordered_layers for item in sublist]
if __name__ == "__main__": pass