def place_product(self, box_idx: int, box_cuboid: Cuboid,
                      chromosome: Chromosome, container_space: Space) -> Space:
        orientations = box_cuboid.get_rotation_permutations()
        orientations = [
            o for o in orientations if o.can_fit_in(container_space)
        ]

        orientation = chromosome.decode_orientation(box_idx, orientations)

        return Space.from_placement(container_space.origin(), orientation)
    def find_best_placement_space(self, container: Container,
                                  product_box: Cuboid) -> Space:
        max_dist = -1.0
        best_ems = None
        orientations = product_box.get_rotation_permutations()

        for ems in container.empty_space_list:
            if ems.volume() >= product_box.volume():
                max_dist, best_ems = self._find_best_ems_for_orientations(
                    max_dist, best_ems, ems, orientations)
        return best_ems
 def find_best_placement_space(self, container: Container,
                               product_box: Cuboid):
     max_dist = -1
     best_ems = None
     if len(container.empty_space_list) == 0:
         return best_ems
     orientations = product_box.get_rotation_permutations()
     bottom_sorted = container.empty_space_list[:]
     bottom_sorted.sort(key=lambda s: self.__axis_value(s))
     z_level = self.__axis_value(bottom_sorted[0])
     for ems in bottom_sorted:
         current_z_level = self.__axis_value(ems)
         # TODO rb: this is pretty hard-edge, works for equal ground level,
         #  but for values > 0 maybe a more interval based approach?
         if z_level < current_z_level and best_ems is not None:
             break
         if ems.volume() >= product_box.volume():
             max_dist, best_ems = self._find_best_ems_for_orientations(
                 max_dist, best_ems, ems, orientations)
         z_level = current_z_level
     return best_ems