diff --git a/src/libnest2d/include/libnest2d/geometry_traits.hpp b/src/libnest2d/include/libnest2d/geometry_traits.hpp
index 5c213c110..c4f2fcaca 100644
--- a/src/libnest2d/include/libnest2d/geometry_traits.hpp
+++ b/src/libnest2d/include/libnest2d/geometry_traits.hpp
@@ -192,7 +192,7 @@ public:
return Unit(width())*height();
}
- static inline _Box infinite(const P ¢er);
+ static inline _Box infinite(const P ¢er = {TCoord
(0), TCoord
(0)});
};
template struct PointType<_Box> {
diff --git a/src/libnest2d/include/libnest2d/libnest2d.hpp b/src/libnest2d/include/libnest2d/libnest2d.hpp
index ab018f3f8..f106ad3d8 100644
--- a/src/libnest2d/include/libnest2d/libnest2d.hpp
+++ b/src/libnest2d/include/libnest2d/libnest2d.hpp
@@ -908,7 +908,8 @@ private:
item.removeOffset();
});
- if(stopfn_ && !stopfn_()) { // Ignore results if nesting was stopped.
+ if(!stopfn_ || (stopfn_ && !stopfn_())) {
+ // Ignore results if nesting was stopped.
const PackGroup& bins = lastResult();
unsigned binidx = 0;
for(auto& bin : bins) {
diff --git a/src/libslic3r/Arrange.cpp b/src/libslic3r/Arrange.cpp
index 84a406fd9..f778a7f75 100644
--- a/src/libslic3r/Arrange.cpp
+++ b/src/libslic3r/Arrange.cpp
@@ -573,7 +573,7 @@ inline SLIC3R_CONSTEXPR coord_t stride_padding(coord_t w)
// a stop predicate can be also be passed to control the process.
bool arrange(ArrangeablePtrs & arrangables,
const ArrangeablePtrs & excludes,
- coord_t min_obj_distance,
+ coord_t min_obj_dist,
const BedShapeHint & bedhint,
std::function progressind,
std::function stopcondition)
@@ -615,13 +615,14 @@ bool arrange(ArrangeablePtrs & arrangables,
arrangeable,
items,
// callback called by arrange to apply the result on the arrangeable
- [arrangeable, &binwidth](const Item &itm, unsigned binidx) {
+ [arrangeable, &binwidth, &ret](const Item &itm, unsigned binidx) {
+ ret = !binidx; // Return value false more bed is required
clppr::cInt stride = binidx * stride_padding(binwidth);
clppr::IntPoint offs = itm.translation();
arrangeable->apply_arrange_result({unscaled(offs.X + stride),
unscaled(offs.Y)},
- itm.rotation());
+ itm.rotation(), binidx);
});
}
@@ -629,66 +630,61 @@ bool arrange(ArrangeablePtrs & arrangables,
process_arrangeable(fixed, fixeditems, nullptr);
// Integer ceiling the min distance from the bed perimeters
- coord_t md = min_obj_distance - SCALED_EPSILON;
+ coord_t md = min_obj_dist - SCALED_EPSILON;
md = (md % 2) ? md / 2 + 1 : md / 2;
- auto& cfn = stopcondition;
+ auto &cfn = stopcondition;
+ auto &pri = progressind;
switch (bedhint.type) {
-// case BedShapeType::BOX: {
-// // Create the arranger for the box shaped bed
-// BoundingBox bbb = bedhint.shape.box;
-// bbb.min -= Point{md, md}, bbb.max += Point{md, md};
-// Box binbb{{bbb.min(X), bbb.min(Y)}, {bbb.max(X), bbb.max(Y)}};
-// binwidth = coord_t(binbb.width());
+ case BedShapeType::BOX: {
+ // Create the arranger for the box shaped bed
+ BoundingBox bbb = bedhint.shape.box;
+ bbb.min -= Point{md, md}, bbb.max += Point{md, md};
+ Box binbb{{bbb.min(X), bbb.min(Y)}, {bbb.max(X), bbb.max(Y)}};
+ binwidth = coord_t(binbb.width());
-// _arrange(items, fixeditems, binbb, min_obj_distance, progressind, cfn);
-// break;
-// }
-// case BedShapeType::CIRCLE: {
-// auto c = bedhint.shape.circ;
-// auto cc = to_lnCircle(c);
-// binwidth = scaled(c.radius());
+ _arrange(items, fixeditems, binbb, min_obj_dist, pri, cfn);
+ break;
+ }
+ case BedShapeType::CIRCLE: {
+ auto c = bedhint.shape.circ;
+ auto cc = to_lnCircle(c);
+ binwidth = scaled(c.radius());
-// _arrange(items, fixeditems, cc, min_obj_distance, progressind, cfn);
-// break;
-// }
-// case BedShapeType::IRREGULAR: {
-// auto ctour = Slic3rMultiPoint_to_ClipperPath(bedhint.shape.polygon);
-// auto irrbed = sl::create(std::move(ctour));
-// BoundingBox polybb(bedhint.shape.polygon);
-// binwidth = (polybb.max(X) - polybb.min(X));
+ _arrange(items, fixeditems, cc, min_obj_dist, pri, cfn);
+ break;
+ }
+ case BedShapeType::IRREGULAR: {
+ auto ctour = Slic3rMultiPoint_to_ClipperPath(bedhint.shape.polygon);
+ auto irrbed = sl::create(std::move(ctour));
+ BoundingBox polybb(bedhint.shape.polygon);
+ binwidth = (polybb.max(X) - polybb.min(X));
-// _arrange(items, fixeditems, irrbed, min_obj_distance, progressind, cfn);
-// break;
-// }
-// case BedShapeType::INFINITE: {
-// const InfiniteBed& nobin = bedhint.shape.infinite;
-// Box infbb{{nobin.center.x(), nobin.center.y()}};
+ _arrange(items, fixeditems, irrbed, min_obj_dist, pri, cfn);
+ break;
+ }
+ case BedShapeType::INFINITE: {
+ const InfiniteBed& nobin = bedhint.shape.infinite;
+ auto infbb = Box::infinite({nobin.center.x(), nobin.center.y()});
-// _arrange(items, fixeditems, infbb, min_obj_distance, progressind, cfn);
-// break;
-// }
-// case BedShapeType::UNKNOWN: {
-// // We know nothing about the bed, let it be infinite and zero centered
-// _arrange(items, fixeditems, Box{}, min_obj_distance, progressind, cfn);
-// break;
-// }
- default: {
- Box infbb = Box::infinite({bedhint.shape.box.center().x(), bedhint.shape.box.center().y()});
-
- _arrange(items, fixeditems, infbb, min_obj_distance, progressind, cfn);
+ _arrange(items, fixeditems, infbb, min_obj_dist, pri, cfn);
+ break;
+ }
+ case BedShapeType::UNKNOWN: {
+ // We know nothing about the bed, let it be infinite and zero centered
+ _arrange(items, fixeditems, Box::infinite(), min_obj_dist, pri, cfn);
break;
}
};
- if(stopcondition()) return false;
+ if(stopcondition && stopcondition()) return false;
return ret;
}
// Arrange, without the fixed items (excludes)
-bool arrange(ArrangeablePtrs & inp,
+bool arrange(ArrangeablePtrs & inp,
coord_t min_d,
const BedShapeHint & bedhint,
std::function prfn,
diff --git a/src/libslic3r/Arrange.hpp b/src/libslic3r/Arrange.hpp
index 87514a600..337a7d959 100644
--- a/src/libslic3r/Arrange.hpp
+++ b/src/libslic3r/Arrange.hpp
@@ -58,7 +58,7 @@ public:
virtual ~Arrangeable() = default;
/// Apply the result transformation calculated by the arrangement.
- virtual void apply_arrange_result(Vec2d offset, double rotation_rads) = 0;
+ virtual void apply_arrange_result(Vec2d offset, double rotation_rads, unsigned bed_num) = 0;
/// Get the 2D silhouette to arrange and an initial offset and rotation
virtual std::tuple get_arrange_polygon() const = 0;
diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp
index 51759640c..d0ed0bc88 100644
--- a/src/libslic3r/Model.hpp
+++ b/src/libslic3r/Model.hpp
@@ -559,10 +559,10 @@ public:
// /////////////////////////////////////////////////////////////////////////
// Getting the input polygon for arrange
- virtual std::tuple get_arrange_polygon() const final;
+ virtual std::tuple get_arrange_polygon() const override;
// Apply the arrange result on the ModelInstance
- virtual void apply_arrange_result(Vec2d offs, double rot_rads) final
+ virtual void apply_arrange_result(Vec2d offs, double rot_rads, unsigned /*bed_num*/) override
{
// write the transformation data into the model instance
set_rotation(Z, rot_rads);
diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp
index 4e3093489..e5b2b38f8 100644
--- a/src/slic3r/GUI/GLCanvas3D.cpp
+++ b/src/slic3r/GUI/GLCanvas3D.cpp
@@ -5739,7 +5739,7 @@ const SLAPrint* GLCanvas3D::sla_print() const
return (m_process == nullptr) ? nullptr : m_process->sla_print();
}
-void GLCanvas3D::WipeTowerInfo::apply_arrange_result(Vec2d offset, double rotation_rads)
+void GLCanvas3D::WipeTowerInfo::apply_arrange_result(Vec2d offset, double rotation_rads, unsigned /*bed_num*/)
{
m_pos = offset;
m_rotation = rotation_rads;
diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp
index 524e0c883..8f419a16d 100644
--- a/src/slic3r/GUI/GLCanvas3D.hpp
+++ b/src/slic3r/GUI/GLCanvas3D.hpp
@@ -624,9 +624,9 @@ public:
return !std::isnan(m_pos.x()) && !std::isnan(m_pos.y());
}
- virtual void apply_arrange_result(Vec2d offset, double rotation_rads) final;
+ virtual void apply_arrange_result(Vec2d offset, double rotation_rads, unsigned /*bed_num*/) override;
- virtual std::tuple get_arrange_polygon() const final
+ virtual std::tuple get_arrange_polygon() const override
{
Polygon p({
{coord_t(0), coord_t(0)},
diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp
index 08c70dbe0..a49b541b5 100644
--- a/src/slic3r/GUI/Plater.cpp
+++ b/src/slic3r/GUI/Plater.cpp
@@ -2482,33 +2482,35 @@ arrangement::BedShapeHint Plater::priv::get_bed_shape_hint() const {
return bedshape;
}
-void Plater::priv::ExclusiveJobGroup::ArrangeJob::process() {
- static const auto arrangestr = _(L("Arranging"));
-
- // FIXME: I don't know how to obtain the minimum distance, it depends
- // on printer technology. I guess the following should work but it crashes.
- double dist = 6; // PrintConfig::min_object_distance(config);
- if (plater().printer_technology == ptFFF) {
- dist = PrintConfig::min_object_distance(plater().config);
- }
-
- coord_t min_obj_distance = scaled(dist);
+void Plater::priv::ExclusiveJobGroup::ArrangeJob::process() {
auto count = unsigned(m_selected.size());
- arrangement::BedShapeHint bedshape = plater().get_bed_shape_hint();
+ plater().model.arrange_objects(6.f, nullptr);
+// static const auto arrangestr = _(L("Arranging"));
- try {
- arrangement::arrange(m_selected, m_unselected, min_obj_distance,
- bedshape,
- [this, count](unsigned st) {
- if (st > 0) // will not finalize after last one
- update_status(count - st, arrangestr);
- },
- [this]() { return was_canceled(); });
- } catch (std::exception & /*e*/) {
- GUI::show_error(plater().q,
- _(L("Could not arrange model objects! "
- "Some geometries may be invalid.")));
- }
+// // FIXME: I don't know how to obtain the minimum distance, it depends
+// // on printer technology. I guess the following should work but it crashes.
+// double dist = 6; // PrintConfig::min_object_distance(config);
+// if (plater().printer_technology == ptFFF) {
+// dist = PrintConfig::min_object_distance(plater().config);
+// }
+
+// coord_t min_obj_distance = scaled(dist);
+// auto count = unsigned(m_selected.size());
+// arrangement::BedShapeHint bedshape = plater().get_bed_shape_hint();
+
+// try {
+// arrangement::arrange(m_selected, m_unselected, min_obj_distance,
+// bedshape,
+// [this, count](unsigned st) {
+// if (st > 0) // will not finalize after last one
+// update_status(count - st, arrangestr);
+// },
+// [this]() { return was_canceled(); });
+// } catch (std::exception & /*e*/) {
+// GUI::show_error(plater().q,
+// _(L("Could not arrange model objects! "
+// "Some geometries may be invalid.")));
+// }
// finalize just here.
update_status(int(count),