mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-09-09 08:17:51 -06:00
Add ModelArrange.hpp as extension to Model.hpp, use it for duplicating
Refactored Arrange interface: remove the union based BedShapeHint, replace it with proper function overloads WARN: this commit is only intermediate, it does not compile.
This commit is contained in:
parent
44ca0a6c3d
commit
1bffc2b99b
13 changed files with 389 additions and 481 deletions
|
@ -1,12 +1,10 @@
|
|||
#ifndef MODELARRANGE_HPP
|
||||
#define MODELARRANGE_HPP
|
||||
#ifndef ARRANGE_HPP
|
||||
#define ARRANGE_HPP
|
||||
|
||||
#include "ExPolygon.hpp"
|
||||
#include "BoundingBox.hpp"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
namespace arrangement {
|
||||
namespace Slic3r { namespace arrangement {
|
||||
|
||||
/// A geometry abstraction for a circular print bed. Similarly to BoundingBox.
|
||||
class CircleBed {
|
||||
|
@ -15,96 +13,16 @@ class CircleBed {
|
|||
public:
|
||||
|
||||
inline CircleBed(): center_(0, 0), radius_(std::nan("")) {}
|
||||
inline CircleBed(const Point& c, double r): center_(c), radius_(r) {}
|
||||
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_; }
|
||||
inline operator bool() { return !std::isnan(radius_); }
|
||||
};
|
||||
|
||||
/// Representing an unbounded bed.
|
||||
struct InfiniteBed { Point center; };
|
||||
|
||||
/// Types of print bed shapes.
|
||||
enum BedShapes {
|
||||
bsBox,
|
||||
bsCircle,
|
||||
bsIrregular,
|
||||
bsInfinite,
|
||||
bsUnknown
|
||||
};
|
||||
|
||||
/// 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;
|
||||
|
||||
// The union neither calls constructors nor destructors of its members.
|
||||
// The only member with non-trivial constructor / destructor is the polygon,
|
||||
// a placement new / delete needs to be called over it.
|
||||
union BedShape_u { // TODO: use variant from cpp17?
|
||||
CircleBed circ;
|
||||
BoundingBox box;
|
||||
Polyline polygon;
|
||||
InfiniteBed infbed{};
|
||||
~BedShape_u() {}
|
||||
BedShape_u() {}
|
||||
} m_bed;
|
||||
|
||||
// Reset the type, allocate m_bed properly
|
||||
void reset(BedShapes type);
|
||||
|
||||
public:
|
||||
|
||||
BedShapeHint(){}
|
||||
|
||||
/// 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;
|
||||
}
|
||||
|
||||
explicit BedShapeHint(const CircleBed &c)
|
||||
{
|
||||
m_type = bsCircle; m_bed.circ = c;
|
||||
}
|
||||
|
||||
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);
|
||||
BedShapeHint& operator=(BedShapeHint &&cpy);
|
||||
|
||||
BedShapes get_type() const { return m_type; }
|
||||
|
||||
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;
|
||||
}
|
||||
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
|
||||
|
@ -125,9 +43,14 @@ 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};
|
||||
|
||||
// If empty, any rotation is allowed (currently unsupported)
|
||||
// If only a zero is there, no rotation is allowed
|
||||
std::vector<double> allowed_rotations = {0.};
|
||||
|
||||
/// Optional setter function which can store arbitrary data in its closure
|
||||
std::function<void(const ArrangePolygon&)> setter = nullptr;
|
||||
|
||||
|
@ -140,6 +63,30 @@ struct ArrangePolygon {
|
|||
|
||||
using ArrangePolygons = std::vector<ArrangePolygon>;
|
||||
|
||||
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 = 0.65f;
|
||||
|
||||
/// Allow parallel execution.
|
||||
bool parallel = true;
|
||||
|
||||
/// Progress indicator callback called when an object gets packed.
|
||||
/// The unsigned argument is the number of items remaining to pack.
|
||||
std::function<void(unsigned)> progressind;
|
||||
|
||||
/// A predicate returning true if abort is needed.
|
||||
std::function<bool(void)> stopcondition;
|
||||
|
||||
ArrangeParams() = default;
|
||||
explicit ArrangeParams(coord_t md) : min_obj_distance(md) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Arranges the input polygons.
|
||||
*
|
||||
|
@ -150,33 +97,23 @@ using ArrangePolygons = std::vector<ArrangePolygon>;
|
|||
* \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.
|
||||
*
|
||||
* \param progressind Progress indicator callback called when
|
||||
* an object gets packed. The unsigned argument is the number of items
|
||||
* remaining to pack.
|
||||
*
|
||||
* \param stopcondition A predicate returning true if abort is needed.
|
||||
*/
|
||||
void arrange(ArrangePolygons & items,
|
||||
coord_t min_obj_distance,
|
||||
const BedShapeHint & bedhint,
|
||||
std::function<void(unsigned)> progressind = nullptr,
|
||||
std::function<bool(void)> stopcondition = nullptr);
|
||||
template<class TBed> void arrange(ArrangePolygons &items, const ArrangePolygons &excludes, const TBed &bed, const ArrangeParams ¶ms = {});
|
||||
|
||||
/// Same as the previous, only that it takes unmovable items as an
|
||||
/// additional argument. Those will be considered as already arranged objects.
|
||||
void arrange(ArrangePolygons & items,
|
||||
const ArrangePolygons & excludes,
|
||||
coord_t min_obj_distance,
|
||||
const BedShapeHint & bedhint,
|
||||
std::function<void(unsigned)> progressind = nullptr,
|
||||
std::function<bool(void)> stopcondition = nullptr);
|
||||
// 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
|
||||
|
||||
} // arr
|
||||
} // Slic3r
|
||||
#endif // MODELARRANGE_HPP
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue