From 0aaca75688e5f6b4b786400c6647de6e62754f8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ach?= Date: Mon, 18 Nov 2024 13:37:50 +0100 Subject: [PATCH] Arrange: Do not take instances outside of bed into consideration, new icons --- resources/icons/arrange.svg | 95 +++-------- resources/icons/arrange_current.svg | 49 +----- .../include/arrange-wrapper/SceneBuilder.hpp | 8 + .../src/SceneBuilder.cpp | 29 +++- src/slic3r/GUI/Jobs/ArrangeJob2.cpp | 160 ++++++------------ 5 files changed, 115 insertions(+), 226 deletions(-) diff --git a/resources/icons/arrange.svg b/resources/icons/arrange.svg index 0ade9c6595..0fd10f5a5d 100644 --- a/resources/icons/arrange.svg +++ b/resources/icons/arrange.svg @@ -9,79 +9,38 @@ viewBox="0 0 128 128" enable-background="new 0 0 128 128" xml:space="preserve" - sodipodi:docname="arrange_current.svg" - inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"> + id="defs22" /> - - + id="g4"> - - + fill="#ED6B21" + d="M120,122.5H8c-1.38,0-2.5-1.12-2.5-2.5V8c0-1.38,1.12-2.5,2.5-2.5h112c1.38,0,2.5,1.12,2.5,2.5v112 C122.5,121.38,121.38,122.5,120,122.5z M10.5,117.5h107v-107h-107V117.5z" + id="path2" /> + + + + + + + + + + diff --git a/resources/icons/arrange_current.svg b/resources/icons/arrange_current.svg index a516a1a3bb..b88c30602e 100644 --- a/resources/icons/arrange_current.svg +++ b/resources/icons/arrange_current.svg @@ -1,46 +1,5 @@ - - - - - - - - - - - - - - - - - - + + + + diff --git a/src/slic3r-arrange-wrapper/include/arrange-wrapper/SceneBuilder.hpp b/src/slic3r-arrange-wrapper/include/arrange-wrapper/SceneBuilder.hpp index 2ce6227e3d..5f6316ce43 100644 --- a/src/slic3r-arrange-wrapper/include/arrange-wrapper/SceneBuilder.hpp +++ b/src/slic3r-arrange-wrapper/include/arrange-wrapper/SceneBuilder.hpp @@ -216,6 +216,7 @@ protected: AnyPtr m_vbed_handler; // Determines how virtual beds are handled AnyPtr m_selmask; // Determines which objects are selected/unselected BedConstraints m_bed_constraints; + std::optional> m_considered_instances; private: friend class SceneBuilder; @@ -249,6 +250,7 @@ protected: AnyPtr m_model; std::vector> m_wipetower_handlers; BedConstraints m_bed_constraints; + std::optional> m_considered_instances; AnyPtr m_vbed_handler; AnyPtr m_selection; @@ -288,6 +290,12 @@ public: return std::move(*this); } + SceneBuilder && set_considered_instances(std::set &&considered_instances) + { + m_considered_instances = std::move(considered_instances); + return std::move(*this); + } + SceneBuilder && set_virtual_bed_handler(AnyPtr vbedh) { m_vbed_handler = std::move(vbedh); diff --git a/src/slic3r-arrange-wrapper/src/SceneBuilder.cpp b/src/slic3r-arrange-wrapper/src/SceneBuilder.cpp index abf495471e..eda6dd9712 100644 --- a/src/slic3r-arrange-wrapper/src/SceneBuilder.cpp +++ b/src/slic3r-arrange-wrapper/src/SceneBuilder.cpp @@ -227,6 +227,7 @@ void SceneBuilder::build_arrangeable_slicer_model(ArrangeableSlicerModel &amodel amodel.m_selmask = std::move(m_selection); amodel.m_wths = std::move(m_wipetower_handlers); amodel.m_bed_constraints = std::move(m_bed_constraints); + amodel.m_considered_instances = std::move(m_considered_instances); for (auto &wth : amodel.m_wths) { wth->set_selection_predicate( @@ -547,20 +548,32 @@ std::optional get_bed_constraint( return found_constraint->second; } +bool should_include_instance( + const ObjectID &instance_id, + const std::set &considered_instances +) { + if (considered_instances.find(instance_id) == considered_instances.end()) { + return false; + } + return true; +} + template void ArrangeableSlicerModel::for_each_arrangeable_(Self &&self, Fn &&fn) { InstPos pos; for (auto *obj : self.m_model->objects) { for (auto *inst : obj->instances) { - ArrangeableModelInstance ainst{ - inst, - self.m_vbed_handler.get(), - self.m_selmask.get(), - pos, - get_bed_constraint(inst->id(), self.m_bed_constraints) - }; - fn(ainst); + if (!self.m_considered_instances || should_include_instance(inst->id(), *self.m_considered_instances)) { + ArrangeableModelInstance ainst{ + inst, + self.m_vbed_handler.get(), + self.m_selmask.get(), + pos, + get_bed_constraint(inst->id(), self.m_bed_constraints) + }; + fn(ainst); + } ++pos.inst_idx; } pos.inst_idx = 0; diff --git a/src/slic3r/GUI/Jobs/ArrangeJob2.cpp b/src/slic3r/GUI/Jobs/ArrangeJob2.cpp index bc6a367cd8..7e7ea29c3b 100644 --- a/src/slic3r/GUI/Jobs/ArrangeJob2.cpp +++ b/src/slic3r/GUI/Jobs/ArrangeJob2.cpp @@ -74,91 +74,6 @@ public: } }; -class BedSelectionMask: public arr2::SelectionMask { - const int m_bed_index; - std::vector> m_selected_instances; - std::vector m_selected_objects; - -public: - explicit BedSelectionMask(const int bed_index, const ModelObjectPtrs &objects, const std::set &instances_on_bed): - m_bed_index{bed_index}, - m_selected_instances(get_selected_instances(objects, instances_on_bed)), - m_selected_objects(get_selected_objects(this->m_selected_instances)) - {} - - bool is_wipe_tower_selected(int wipe_tower_index) const override - { - return wipe_tower_index == m_bed_index; - } - - std::vector selected_objects() const override - { - return this->m_selected_objects; - } - - std::vector selected_instances(int obj_id) const override { - return this->m_selected_instances[obj_id]; - } - -private: - static std::vector get_selected_objects( - const std::vector> &selected_instances - ) { - std::vector result; - - std::transform( - selected_instances.begin(), - selected_instances.end(), - std::back_inserter(result), - [&](const std::vector &object_selected_instances) { - return std::any_of( - object_selected_instances.begin(), - object_selected_instances.end(), - [](const bool is_selected){ return is_selected; } - ); - } - ); - - return result; - } - - std::vector get_selected_instances( - const ModelObject &object, - const std::set &instances_on_bed - ) { - std::vector result; - std::transform( - object.instances.begin(), - object.instances.end(), - std::back_inserter(result), - [&](const ModelInstance *instance) { - const auto instance_bed_index{instances_on_bed.find(instance->id())}; - if(instance_bed_index != instances_on_bed.end()) { - return true; - } - return false; - } - ); - return result; - } - - std::vector> get_selected_instances( - const ModelObjectPtrs &objects, - const std::set &instances_on_bed - ) { - std::vector> result; - std::transform( - objects.begin(), - objects.end(), - std::back_inserter(result), - [&](const ModelObject *object){ - return get_selected_instances(*object, instances_on_bed); - } - ); - return result; - } -}; - static Polygon get_wtpoly(const GLCanvas3D::WipeTowerInfo &wti) { @@ -263,37 +178,69 @@ arr2::SceneBuilder build_scene(Plater &plater, ArrangeSelectionMode mode) arr2::SceneBuilder builder; const int current_bed{s_multiple_beds.get_active_bed()}; + const std::map &beds_map{s_multiple_beds.get_inst_map()}; if (mode == ArrangeSelectionMode::SelectionOnly) { - auto sel = std::make_unique(&plater.get_selection()); - builder.set_selection(std::move(sel)); - } else if (mode == ArrangeSelectionMode::CurrentBedSelectionOnly) { - arr2::BedConstraints constraints; - for (const ModelObject *object : plater.model().objects) { - for (const ModelInstance *instance : object->instances) { - constraints.insert({instance->id(), current_bed}); + auto gui_selection = std::make_unique(&plater.get_selection()); + + std::set considered_instances; + for (std::size_t object_index{0}; object_index < plater.model().objects.size(); ++object_index) { + const ModelObject *object{plater.model().objects[object_index]}; + for (std::size_t instance_index{0}; instance_index < object->instances.size(); ++instance_index) { + const ModelInstance *instance{object->instances[instance_index]}; + + const bool is_selected{gui_selection->selected_instances(object_index)[instance_index]}; + const auto instance_bed_index{beds_map.find(instance->id())}; + + if ( + is_selected + || instance_bed_index != beds_map.end() + ) { + considered_instances.insert(instance->id()); + } } } - builder.set_bed_constraints(std::move(constraints)); - - auto gui_selection{std::make_unique(&plater.get_selection())}; builder.set_selection(std::move(gui_selection)); + builder.set_considered_instances(std::move(considered_instances)); + } else if (mode == ArrangeSelectionMode::CurrentBedSelectionOnly) { + auto gui_selection{std::make_unique(&plater.get_selection())}; + + std::set considered_instances; + arr2::BedConstraints constraints; + for (std::size_t object_index{0}; object_index < plater.model().objects.size(); ++object_index) { + const ModelObject *object{plater.model().objects[object_index]}; + for (std::size_t instance_index{0}; instance_index < object->instances.size(); ++instance_index) { + const ModelInstance *instance{object->instances[instance_index]}; + + const bool is_selected{gui_selection->selected_instances(object_index)[instance_index]}; + + const auto instance_bed_index{beds_map.find(instance->id())}; + if ( + is_selected + || ( + instance_bed_index != beds_map.end() + && instance_bed_index->second == current_bed + ) + ) { + constraints.insert({instance->id(), current_bed}); + considered_instances.insert(instance->id()); + } + } + } + + builder.set_selection(std::move(gui_selection)); + builder.set_bed_constraints(std::move(constraints)); + builder.set_considered_instances(std::move(considered_instances)); } else if (mode == ArrangeSelectionMode::CurrentBedFull) { std::set instances_on_bed; arr2::BedConstraints constraints; - for (const auto &instance_bed : s_multiple_beds.get_inst_map()) { + for (const auto &instance_bed : beds_map) { if (instance_bed.second == current_bed) { - instances_on_bed.emplace(instance_bed.first); - constraints.emplace(instance_bed); + instances_on_bed.insert(instance_bed.first); + constraints.insert(instance_bed); } } builder.set_bed_constraints(std::move(constraints)); - - auto bed_selection{std::make_unique( - current_bed, - plater.model().objects, - instances_on_bed - )}; - builder.set_selection(std::move(bed_selection)); + builder.set_considered_instances(std::move(instances_on_bed)); } builder.set_arrange_settings(plater.canvas3D()->get_arrange_settings_view()); @@ -304,6 +251,9 @@ arr2::SceneBuilder build_scene(Plater &plater, ArrangeSelectionMode mode) for (const auto &info : wipe_tower_infos) { if (info) { + if (mode == ArrangeSelectionMode::CurrentBedFull && info.bed_index() != current_bed) { + continue; + } auto handler{std::make_unique(wipe_tower_instance_id(info.bed_index()), info)}; if (plater.config() && is_XL_printer(*plater.config())) { handler->xl_bb = bounding_box(get_bed_shape(*plater.config()));