mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-24 09:11:23 -06:00
Priority for wipe tower, Increased safety distance from bed edges.
* WipeTowerInfo class extended in plater (WipeTower) instead of GLCanvas3D * Bed origin support in ModelInstance and WipeTower
This commit is contained in:
parent
5446167c11
commit
44801f4429
9 changed files with 164 additions and 153 deletions
|
|
@ -584,6 +584,7 @@ void arrange(ArrangePolygons & arrangables,
|
|||
outp.back().rotation(rotation);
|
||||
outp.back().translation({offs.x(), offs.y()});
|
||||
outp.back().binId(arrpoly.bed_idx);
|
||||
outp.back().priority(arrpoly.priority);
|
||||
};
|
||||
|
||||
for (ArrangePolygon &arrangeable : arrangables)
|
||||
|
|
@ -595,7 +596,7 @@ void arrange(ArrangePolygons & arrangables,
|
|||
for (Item &itm : fixeditems) itm.inflate(-2 * SCALED_EPSILON);
|
||||
|
||||
// Integer ceiling the min distance from the bed perimeters
|
||||
coord_t md = min_obj_dist - SCALED_EPSILON;
|
||||
coord_t md = min_obj_dist - 2 * scaled(0.1 + EPSILON);
|
||||
md = (md % 2) ? md / 2 + 1 : md / 2;
|
||||
|
||||
auto &cfn = stopcondition;
|
||||
|
|
|
|||
|
|
@ -140,15 +140,18 @@ static const constexpr int UNARRANGED = -1;
|
|||
/// 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; /// The 2D silhouette to be arranged
|
||||
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
|
||||
int bed_idx{UNARRANGED}; /// To which logical bed does poly belong...
|
||||
int priority{0};
|
||||
|
||||
ArrangePolygon(ExPolygon p, const Vec2crd &tr = {}, double rot = 0.0)
|
||||
: poly{std::move(p)}, translation{tr}, rotation{rot}
|
||||
{}
|
||||
/// Optional setter function which can store arbitrary data in its closure
|
||||
std::function<void(const ArrangePolygon&)> setter = nullptr;
|
||||
|
||||
/// Helper function to call the setter with the arrange data arguments
|
||||
void apply() const { if (setter) setter(*this); }
|
||||
};
|
||||
|
||||
using ArrangePolygons = std::vector<ArrangePolygon>;
|
||||
|
|
|
|||
|
|
@ -387,20 +387,24 @@ bool Model::arrange_objects(coordf_t dist, const BoundingBoxf* bb)
|
|||
}
|
||||
|
||||
arrangement::BedShapeHint bedhint;
|
||||
|
||||
if (bb)
|
||||
coord_t bedwidth = 0;
|
||||
|
||||
if (bb) {
|
||||
bedwidth = scaled(bb->size().x());
|
||||
bedhint = arrangement::BedShapeHint(
|
||||
BoundingBox(scaled(bb->min), scaled(bb->max)));
|
||||
}
|
||||
|
||||
arrangement::arrange(input, scaled(dist), bedhint);
|
||||
|
||||
bool ret = true;
|
||||
coord_t stride = bedwidth + bedwidth / 5;
|
||||
|
||||
for(size_t i = 0; i < input.size(); ++i) {
|
||||
if (input[i].bed_idx == 0) { // no logical beds are allowed
|
||||
instances[i]->apply_arrange_result(input[i].translation,
|
||||
input[i].rotation);
|
||||
} else ret = false;
|
||||
if (input[i].bed_idx != 0) ret = false;
|
||||
if (input[i].bed_idx >= 0)
|
||||
instances[i]->apply_arrange_result(input[i],
|
||||
{input[i].bed_idx * stride, 0});
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
@ -1822,22 +1826,24 @@ arrangement::ArrangePolygon ModelInstance::get_arrange_polygon() const
|
|||
|
||||
// this may happen for malformed models, see:
|
||||
// https://github.com/prusa3d/PrusaSlicer/issues/2209
|
||||
if (p.points.empty()) return {{}};
|
||||
if (p.points.empty()) return {};
|
||||
|
||||
Polygons pp{p};
|
||||
pp = p.simplify(scaled<double>(SIMPLIFY_TOLERANCE_MM));
|
||||
if (!pp.empty()) p = pp.front();
|
||||
m_arrange_cache.poly.contour = std::move(p);
|
||||
m_arrange_cache.bed_origin = {0, 0};
|
||||
m_arrange_cache.bed_idx = arrangement::UNARRANGED;
|
||||
m_arrange_cache.valid = true;
|
||||
}
|
||||
|
||||
arrangement::ArrangePolygon ret{m_arrange_cache.poly,
|
||||
Vec2crd{scaled(get_offset(X)),
|
||||
scaled(get_offset(Y))},
|
||||
get_rotation(Z)};
|
||||
|
||||
ret.bed_idx = m_arrange_cache.bed_idx;
|
||||
|
||||
arrangement::ArrangePolygon ret;
|
||||
ret.poly = m_arrange_cache.poly;
|
||||
ret.translation = Vec2crd{scaled(get_offset(X)), scaled(get_offset(Y))} -
|
||||
m_arrange_cache.bed_origin;
|
||||
ret.rotation = get_rotation(Z);
|
||||
ret.bed_idx = m_arrange_cache.bed_idx;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -558,13 +558,15 @@ public:
|
|||
arrangement::ArrangePolygon get_arrange_polygon() const;
|
||||
|
||||
// Apply the arrange result on the ModelInstance
|
||||
void apply_arrange_result(Vec2crd offs, double rot_rads, int bed_idx = 0)
|
||||
void apply_arrange_result(const arrangement::ArrangePolygon& ap,
|
||||
const Vec2crd& bed_origin = {0, 0})
|
||||
{
|
||||
// write the transformation data into the model instance
|
||||
set_rotation(Z, rot_rads);
|
||||
set_offset(X, unscale<double>(offs(X)));
|
||||
set_offset(Y, unscale<double>(offs(Y)));
|
||||
m_arrange_cache.bed_idx = bed_idx;
|
||||
set_rotation(Z, ap.rotation);
|
||||
set_offset(X, unscale<double>(ap.translation(X) + bed_origin.x()));
|
||||
set_offset(Y, unscale<double>(ap.translation(Y) + bed_origin.y()));
|
||||
m_arrange_cache.bed_origin = bed_origin;
|
||||
m_arrange_cache.bed_idx = ap.bed_idx;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
@ -599,8 +601,9 @@ private:
|
|||
// Warning! This object is not guarded against concurrency.
|
||||
mutable struct ArrangeCache {
|
||||
bool valid = false;
|
||||
int bed_idx { arrangement::UNARRANGED };
|
||||
Vec2crd bed_origin {0, 0};
|
||||
ExPolygon poly;
|
||||
int bed_idx = arrangement::UNARRANGED;
|
||||
} m_arrange_cache;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue