diff options
author | tamasmeszaros <meszaros.q@gmail.com> | 2019-07-15 18:30:44 +0300 |
---|---|---|
committer | tamasmeszaros <meszaros.q@gmail.com> | 2019-07-15 18:30:44 +0300 |
commit | 1b0e192046e358ba34941d1895f86c94ad6c6ac0 (patch) | |
tree | 6acd90f4b75a38424d8391358fcd6098824688f4 /src/libslic3r/Arrange.hpp | |
parent | df7bb94dafea6a64922184fe65db3c61f7c85da0 (diff) |
Arrange cache in ModeInstance and logical bed remembered.
Diffstat (limited to 'src/libslic3r/Arrange.hpp')
-rw-r--r-- | src/libslic3r/Arrange.hpp | 167 |
1 files changed, 111 insertions, 56 deletions
diff --git a/src/libslic3r/Arrange.hpp b/src/libslic3r/Arrange.hpp index bc23108cd..c705b612b 100644 --- a/src/libslic3r/Arrange.hpp +++ b/src/libslic3r/Arrange.hpp @@ -22,97 +22,152 @@ public: inline operator bool() { return !std::isnan(radius_); } }; -/// Representing an unbounded bin +/// Representing an unbounded bed. struct InfiniteBed { Point center; }; /// Types of print bed shapes. -enum class BedShapeType { - BOX, - CIRCLE, - IRREGULAR, - INFINITE, - UNKNOWN +enum BedShapes { + bsBox, + bsCircle, + bsIrregular, + bsInfinite, + bsUnknown }; -/// Info about the print bed for the arrange() function. -struct BedShapeHint { - BedShapeType type = BedShapeType::INFINITE; - union BedShape_u { // I know but who cares... TODO: use variant from cpp17? +/// Info about the print bed for the arrange() function. This is a variant +/// holding one of the four shapes a bed can be. +class BedShapeHint { + BedShapes m_type = BedShapes::bsInfinite; + + union BedShape_u { // TODO: use variant from cpp17? CircleBed circ; BoundingBox box; Polyline polygon; - InfiniteBed infinite{}; + InfiniteBed infbed{}; ~BedShape_u() {} BedShape_u() {}; - } shape; + } m_bed; - BedShapeHint() {}; +public: + + BedShapeHint(){}; - ~BedShapeHint() { - if (type == BedShapeType::IRREGULAR) - shape.polygon.Slic3r::Polyline::~Polyline(); - }; + /// Get a bed shape hint for arrange() from a naked Polyline. + explicit BedShapeHint(const Polyline &polyl); + explicit BedShapeHint(const BoundingBox &bb) + { + m_type = bsBox; m_bed.box = bb; + } - BedShapeHint(const BedShapeHint &cpy) { - *this = cpy; + explicit BedShapeHint(const CircleBed &c) + { + m_type = bsCircle; m_bed.circ = c; } - BedShapeHint& operator=(const BedShapeHint &cpy) { - type = cpy.type; - switch(type) { - case BedShapeType::BOX: shape.box = cpy.shape.box; break; - case BedShapeType::CIRCLE: shape.circ = cpy.shape.circ; break; - case BedShapeType::IRREGULAR: shape.polygon = cpy.shape.polygon; break; - case BedShapeType::INFINITE: shape.infinite = cpy.shape.infinite; break; - case BedShapeType::UNKNOWN: break; + explicit BedShapeHint(const InfiniteBed &ibed) + { + m_type = bsInfinite; m_bed.infbed = ibed; + } + + ~BedShapeHint() + { + if (m_type == BedShapes::bsIrregular) + m_bed.polygon.Slic3r::Polyline::~Polyline(); + }; + + BedShapeHint(const BedShapeHint &cpy) { *this = cpy; } + BedShapeHint(BedShapeHint &&cpy) { *this = std::move(cpy); } + + BedShapeHint &operator=(const BedShapeHint &cpy) + { + m_type = cpy.m_type; + switch(m_type) { + case bsBox: m_bed.box = cpy.m_bed.box; break; + case bsCircle: m_bed.circ = cpy.m_bed.circ; break; + case bsIrregular: m_bed.polygon = cpy.m_bed.polygon; break; + case bsInfinite: m_bed.infbed = cpy.m_bed.infbed; break; + case bsUnknown: break; } return *this; } -}; -/// Get a bed shape hint for arrange() from a naked Polyline. -BedShapeHint bedShape(const Polyline& bed); + BedShapeHint& operator=(BedShapeHint &&cpy) + { + m_type = cpy.m_type; + switch(m_type) { + case bsBox: m_bed.box = std::move(cpy.m_bed.box); break; + case bsCircle: m_bed.circ = std::move(cpy.m_bed.circ); break; + case bsIrregular: m_bed.polygon = std::move(cpy.m_bed.polygon); break; + case bsInfinite: m_bed.infbed = std::move(cpy.m_bed.infbed); break; + case bsUnknown: break; + } + + return *this; + } + + BedShapes get_type() const { return m_type; } -static const constexpr long UNARRANGED = -1; + const BoundingBox &get_box() const + { + assert(m_type == bsBox); return m_bed.box; + } + const CircleBed &get_circle() const + { + assert(m_type == bsCircle); return m_bed.circ; + } + const Polyline &get_irregular() const + { + assert(m_type == bsIrregular); return m_bed.polygon; + } + const InfiniteBed &get_infinite() const + { + assert(m_type == bsInfinite); return m_bed.infbed; + } +}; +/// A logical bed representing an object not being arranged. Either the arrange +/// has not yet succesfully 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 { - const ExPolygon poly; - Vec2crd translation{0, 0}; - double rotation{0.0}; - long bed_idx{UNARRANGED}; + const 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 + int bed_idx{UNARRANGED}; /// To which logical bed does poly belong... - ArrangePolygon(const ExPolygon &p, const Vec2crd &tr = {}, double rot = 0.0) - : poly{p}, translation{tr}, rotation{rot} + ArrangePolygon(ExPolygon p, const Vec2crd &tr = {}, double rot = 0.0) + : poly{std::move(p)}, translation{tr}, rotation{rot} {} }; using ArrangePolygons = std::vector<ArrangePolygon>; /** - * \brief Arranges the model objects on the screen. + * \brief Arranges the input polygons. * - * The arrangement considers multiple bins (aka. print beds) for placing - * all the items provided in the model argument. If the items don't fit on - * one print bed, the remaining will be placed onto newly created print - * beds. The first_bin_only parameter, if set to true, disables this - * behavior and makes sure that only one print bed is filled and the - * remaining items will be untouched. When set to false, the items which - * could not fit onto the print bed will be placed next to the print bed so - * the user should see a pile of items on the print bed and some other - * piles outside the print area that can be dragged later onto the print - * bed as a group. + * 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 which are object pointers implementing the - * Arrangeable interface. + * \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. * * \param min_obj_distance The minimum distance which is allowed for any * pair of items on the print bed in any direction. * - * \param bedhint Info about the shape and type of the - * bed. remaining items which do not fit onto the print area next to the - * print bed or leave them untouched (let the user arrange them by hand or - * remove them). + * \param bedhint Info about the shape and type of the bed. * * \param progressind Progress indicator callback called when * an object gets packed. The unsigned argument is the number of items @@ -127,7 +182,7 @@ void arrange(ArrangePolygons & items, std::function<bool(void)> stopcondition = nullptr); /// Same as the previous, only that it takes unmovable items as an -/// additional argument. +/// additional argument. Those will be considered as already arranged objects. void arrange(ArrangePolygons & items, const ArrangePolygons & excludes, coord_t min_obj_distance, |