diff --git a/src/libslic3r/Arrange.hpp b/src/libslic3r/Arrange.hpp index ec46da8d3..0ff87c88d 100644 --- a/src/libslic3r/Arrange.hpp +++ b/src/libslic3r/Arrange.hpp @@ -62,6 +62,15 @@ struct ArrangePolygon { /// 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; diff --git a/src/libslic3r/BoundingBox.hpp b/src/libslic3r/BoundingBox.hpp index 819162ec9..8de28af5c 100644 --- a/src/libslic3r/BoundingBox.hpp +++ b/src/libslic3r/BoundingBox.hpp @@ -53,6 +53,9 @@ public: return point(0) >= this->min(0) && point(0) <= this->max(0) && point(1) >= this->min(1) && point(1) <= this->max(1); } + bool contains(const BoundingBoxBase &other) const { + return contains(other.min) && contains(other.max); + } bool overlap(const BoundingBoxBase &other) const { return ! (this->max(0) < other.min(0) || this->min(0) > other.max(0) || this->max(1) < other.min(1) || this->min(1) > other.max(1)); diff --git a/src/slic3r/GUI/Jobs/FillBedJob.cpp b/src/slic3r/GUI/Jobs/FillBedJob.cpp index 69aa7c5a6..d2ff5252a 100644 --- a/src/slic3r/GUI/Jobs/FillBedJob.cpp +++ b/src/slic3r/GUI/Jobs/FillBedJob.cpp @@ -29,7 +29,9 @@ void FillBedJob::prepare() for (ModelInstance *inst : model_object->instances) if (inst->printable) { ArrangePolygon ap = get_arrange_poly(PtrWrapper{inst}, m_plater); - ++ap.priority; // need to be included in the result + // Existing objects need to be included in the result. Only + // the needed amount of object will be added, no more. + ++ap.priority; m_selected.emplace_back(ap); } @@ -38,11 +40,18 @@ void FillBedJob::prepare() m_bedpts = get_bed_shape(*m_plater->config()); auto &objects = m_plater->model().objects; + BoundingBox bedbb = get_extents(m_bedpts); + for (size_t idx = 0; idx < objects.size(); ++idx) if (int(idx) != m_object_idx) for (ModelInstance *mi : objects[idx]->instances) { - m_unselected.emplace_back(get_arrange_poly(PtrWrapper{mi}, m_plater)); - m_unselected.back().bed_idx = 0; + ArrangePolygon ap = get_arrange_poly(PtrWrapper{mi}, m_plater); + auto ap_bb = ap.transformed_poly().contour.bounding_box(); + + if (ap.bed_idx == 0 && !bedbb.contains(ap_bb)) + ap.bed_idx = arrangement::UNARRANGED; + + m_unselected.emplace_back(ap); } if (auto wt = get_wipe_tower_arrangepoly(*m_plater)) @@ -78,6 +87,12 @@ void FillBedJob::prepare() } m_status_range = m_selected.size(); + + // The strides have to be removed from the fixed items. For the + // arrangeable (selected) items bed_idx is ignored and the + // translation is irrelevant. + double stride = bed_stride(m_plater); + for (auto &p : m_unselected) p.translation(X) -= p.bed_idx * stride; } void FillBedJob::process()