#ifndef ARRANGE_HPP #define ARRANGE_HPP #include "ExPolygon.hpp" #include "PrintConfig.hpp" #define BED_SHRINK_SEQ_PRINT 5 namespace Slic3r { class BoundingBox; namespace arrangement { /// A geometry abstraction for a circular print bed. Similarly to BoundingBox. class CircleBed { Point center_; double radius_; public: inline CircleBed(): center_(0, 0), radius_(std::nan("")) {} explicit inline CircleBed(const Point& c, double r): center_(c), radius_(r) {} inline double radius() const { return radius_; } inline const Point& center() const { return center_; } }; /// Representing an unbounded bed. struct InfiniteBed { Point center; explicit InfiniteBed(const Point &p = {0, 0}): center{p} {} }; /// A logical bed representing an object not being arranged. Either the arrange /// has not yet successfully run on this ArrangePolygon or it could not fit the /// object due to overly large size or invalid geometry. static const constexpr int UNARRANGED = -1; /// Input/Output structure for the arrange() function. The poly field will not /// be modified during arrangement. Instead, the translation and rotation fields /// will mark the needed transformation for the polygon to be in the arranged /// position. These can also be set to an initial offset and rotation. /// /// The bed_idx field will indicate the logical bed into which the /// polygon belongs: UNARRANGED means no place for the polygon /// (also the initial state before arrange), 0..N means the index of the bed. /// Zero is the physical bed, larger than zero means a virtual bed. struct ArrangePolygon { ExPolygon poly; /// The 2D silhouette to be arranged Vec2crd translation{0, 0}; /// The translation of the poly double rotation{0.0}; /// The rotation of the poly in radians coord_t inflation = 0; /// Arrange with inflated polygon int bed_idx{UNARRANGED}; /// To which logical bed does poly belong... int priority{0}; //BBS: add locked_plate to indicate whether it is in the locked plate int locked_plate{ -1 }; bool is_virt_object{ false }; bool is_extrusion_cali_object{ false }; bool is_wipe_tower{ false }; bool has_tree_support{false}; //BBS: add row/col for sudoku-style layout int row{0}; int col{0}; std::vector extrude_ids{}; /// extruder_id for least extruder switch int filament_temp_type{ -1 }; int bed_temp{0}; ///bed temperature for different material judge int print_temp{0}; ///print temperature for different material judge int first_bed_temp{ 0 }; ///first layer bed temperature for different material judge int first_print_temp{ 0 }; ///first layer print temperature for different material judge int vitrify_temp{ 0 }; // max bed temperature for material compatibility, which is usually the filament vitrification temp int itemid{ 0 }; // item id in the vector, used for accessing all possible params like extrude_id int is_applied{ 0 }; // transform has been applied double height{ 0 }; // item height double brim_width{ 0 }; // brim width std::string name; // If empty, any rotation is allowed (currently unsupported) // If only a zero is there, no rotation is allowed std::vector allowed_rotations = {0.}; /// Optional setter function which can store arbitrary data in its closure std::function setter = nullptr; /// Helper function to call the setter with the arrange data arguments void apply() { if (setter && !is_applied) { setter(*this); is_applied = 1; } } /// Test if arrange() was called previously and gave a successful result. bool is_arranged() const { return bed_idx != UNARRANGED; } inline ExPolygon transformed_poly() const { ExPolygon ret = poly; ret.rotate(rotation); ret.translate(translation.x(), translation.y()); return ret; } }; using ArrangePolygons = std::vector; struct ArrangeParams { /// The minimum distance which is allowed for any /// pair of items on the print bed in any direction. coord_t min_obj_distance = 0; /// The accuracy of optimization. /// Goes from 0.0 to 1.0 and scales performance as well float accuracy = 1.f; /// Allow parallel execution. bool parallel = true; bool allow_rotations = false; bool do_final_align = true; //BBS: add specific arrange params bool allow_multi_materials_on_same_plate = true; bool avoid_extrusion_cali_region = true; bool is_seq_print = false; bool align_to_y_axis = false; float bed_shrink_x = 0.1; float bed_shrink_y = 0.1; float brim_skirt_distance = 0; float clearance_height_to_rod = 0; float clearance_height_to_lid = 0; float cleareance_radius = 0; float nozzle_height = 0; float printable_height = 256.0; Vec2d align_center{ 0.5,0.5 }; ArrangePolygons excluded_regions; // regions cant't be used ArrangePolygons nonprefered_regions; // regions can be used but not prefered /// Progress indicator callback called when an object gets packed. /// The unsigned argument is the number of items remaining to pack. std::function progressind = [](unsigned st, std::string str = "") { std::cout << "st=" << st << ", " << str << std::endl; }; std::function on_packed; /// A predicate returning true if abort is needed. std::function stopcondition; ArrangeParams() = default; explicit ArrangeParams(coord_t md) : min_obj_distance(md) {} // to json format std::string to_json() const{ std::string ret = "{"; ret += "\"min_obj_distance\":" + std::to_string(min_obj_distance) + ","; ret += "\"accuracy\":" + std::to_string(accuracy) + ","; ret += "\"parallel\":" + std::to_string(parallel) + ","; ret += "\"allow_rotations\":" + std::to_string(allow_rotations) + ","; ret += "\"do_final_align\":" + std::to_string(do_final_align) + ","; ret += "\"allow_multi_materials_on_same_plate\":" + std::to_string(allow_multi_materials_on_same_plate) + ","; ret += "\"avoid_extrusion_cali_region\":" + std::to_string(avoid_extrusion_cali_region) + ","; ret += "\"is_seq_print\":" + std::to_string(is_seq_print) + ","; ret += "\"bed_shrink_x\":" + std::to_string(bed_shrink_x) + ","; ret += "\"bed_shrink_y\":" + std::to_string(bed_shrink_y) + ","; ret += "\"brim_skirt_distance\":" + std::to_string(brim_skirt_distance) + ","; ret += "\"clearance_height_to_rod\":" + std::to_string(clearance_height_to_rod) + ","; ret += "\"clearance_height_to_lid\":" + std::to_string(clearance_height_to_lid) + ","; ret += "\"cleareance_radius\":" + std::to_string(cleareance_radius) + ","; ret += "\"printable_height\":" + std::to_string(printable_height) + ","; return ret; } }; void update_arrange_params(ArrangeParams& params, const DynamicPrintConfig* print_cfg, const ArrangePolygons& selected); void update_selected_items_inflation(ArrangePolygons& selected, const DynamicPrintConfig* print_cfg, ArrangeParams& params); void update_unselected_items_inflation(ArrangePolygons& unselected, const DynamicPrintConfig* print_cfg, const ArrangeParams& params); void update_selected_items_axis_align(ArrangePolygons& selected, const DynamicPrintConfig* print_cfg, const ArrangeParams& params); Points get_shrink_bedpts(const DynamicPrintConfig* print_cfg, const ArrangeParams& params); /** * \brief Arranges the input polygons. * * WARNING: Currently, only convex polygons are supported by the libnest2d * library which is used to do the arrangement. This might change in the future * this is why the interface contains a general polygon capable to have holes. * * \param items Input vector of ArrangePolygons. The transformation, rotation * and bin_idx fields will be changed after the call finished and can be used * to apply the result on the input polygon. */ template void arrange(ArrangePolygons &items, const ArrangePolygons &excludes, const TBed &bed, const ArrangeParams ¶ms = {}); // A dispatch function that determines the bed shape from a set of points. template<> void arrange(ArrangePolygons &items, const ArrangePolygons &excludes, const Points &bed, const ArrangeParams ¶ms); extern template void arrange(ArrangePolygons &items, const ArrangePolygons &excludes, const BoundingBox &bed, const ArrangeParams ¶ms); extern template void arrange(ArrangePolygons &items, const ArrangePolygons &excludes, const CircleBed &bed, const ArrangeParams ¶ms); extern template void arrange(ArrangePolygons &items, const ArrangePolygons &excludes, const Polygon &bed, const ArrangeParams ¶ms); extern template void arrange(ArrangePolygons &items, const ArrangePolygons &excludes, const InfiniteBed &bed, const ArrangeParams ¶ms); inline void arrange(ArrangePolygons &items, const Points &bed, const ArrangeParams ¶ms = {}) { arrange(items, {}, bed, params); } inline void arrange(ArrangePolygons &items, const BoundingBox &bed, const ArrangeParams ¶ms = {}) { arrange(items, {}, bed, params); } inline void arrange(ArrangePolygons &items, const CircleBed &bed, const ArrangeParams ¶ms = {}) { arrange(items, {}, bed, params); } inline void arrange(ArrangePolygons &items, const Polygon &bed, const ArrangeParams ¶ms = {}) { arrange(items, {}, bed, params); } inline void arrange(ArrangePolygons &items, const InfiniteBed &bed, const ArrangeParams ¶ms = {}) { arrange(items, {}, bed, params); } }} // namespace Slic3r::arrangement #endif // MODELARRANGE_HPP