diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 3f1848d30..4a9c7cd56 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -620,24 +620,54 @@ const GLVolume* Selection::get_volume(unsigned int volume_idx) const const BoundingBoxf3& Selection::get_bounding_box() const { - if (m_bounding_box_dirty) - calc_bounding_box(); - - return m_bounding_box; + if (!m_bounding_box.has_value()) { + std::optional<BoundingBoxf3>* bbox = const_cast<std::optional<BoundingBoxf3>*>(&m_bounding_box); + *bbox = BoundingBoxf3(); + if (m_valid) { + for (unsigned int i : m_list) { + (*bbox)->merge((*m_volumes)[i]->transformed_convex_hull_bounding_box()); + } + } + } + return *m_bounding_box; } const BoundingBoxf3& Selection::get_unscaled_instance_bounding_box() const { - if (m_unscaled_instance_bounding_box_dirty) - calc_unscaled_instance_bounding_box(); - return m_unscaled_instance_bounding_box; + if (!m_unscaled_instance_bounding_box.has_value()) { + std::optional<BoundingBoxf3>* bbox = const_cast<std::optional<BoundingBoxf3>*>(&m_unscaled_instance_bounding_box); + *bbox = BoundingBoxf3(); + if (m_valid) { + for (unsigned int i : m_list) { + const GLVolume& volume = *(*m_volumes)[i]; + if (volume.is_modifier) + continue; + Transform3d trafo = volume.get_instance_transformation().get_matrix(false, false, true, false) * volume.get_volume_transformation().get_matrix(); + trafo.translation().z() += volume.get_sla_shift_z(); + (*bbox)->merge(volume.transformed_convex_hull_bounding_box(trafo)); + } + } + } + return *m_unscaled_instance_bounding_box; } const BoundingBoxf3& Selection::get_scaled_instance_bounding_box() const { - if (m_scaled_instance_bounding_box_dirty) - calc_scaled_instance_bounding_box(); - return m_scaled_instance_bounding_box; + if (!m_scaled_instance_bounding_box.has_value()) { + std::optional<BoundingBoxf3>* bbox = const_cast<std::optional<BoundingBoxf3>*>(&m_scaled_instance_bounding_box); + *bbox = BoundingBoxf3(); + if (m_valid) { + for (unsigned int i : m_list) { + const GLVolume& volume = *(*m_volumes)[i]; + if (volume.is_modifier) + continue; + Transform3d trafo = volume.get_instance_transformation().get_matrix(false, false, false, false) * volume.get_volume_transformation().get_matrix(); + trafo.translation().z() += volume.get_sla_shift_z(); + (*bbox)->merge(volume.transformed_convex_hull_bounding_box(trafo)); + } + } + } + return *m_scaled_instance_bounding_box; } void Selection::start_dragging() @@ -1692,52 +1722,6 @@ void Selection::do_remove_object(unsigned int object_idx) } } -void Selection::calc_bounding_box() const -{ - BoundingBoxf3* bounding_box = const_cast<BoundingBoxf3*>(&m_bounding_box); - *bounding_box = BoundingBoxf3(); - if (m_valid) { - for (unsigned int i : m_list) { - bounding_box->merge((*m_volumes)[i]->transformed_convex_hull_bounding_box()); - } - } - *const_cast<bool*>(&m_bounding_box_dirty) = false; -} - -void Selection::calc_unscaled_instance_bounding_box() const -{ - BoundingBoxf3* unscaled_instance_bounding_box = const_cast<BoundingBoxf3*>(&m_unscaled_instance_bounding_box); - *unscaled_instance_bounding_box = BoundingBoxf3(); - if (m_valid) { - for (unsigned int i : m_list) { - const GLVolume& volume = *(*m_volumes)[i]; - if (volume.is_modifier) - continue; - Transform3d trafo = volume.get_instance_transformation().get_matrix(false, false, true, false) * volume.get_volume_transformation().get_matrix(); - trafo.translation().z() += volume.get_sla_shift_z(); - unscaled_instance_bounding_box->merge(volume.transformed_convex_hull_bounding_box(trafo)); - } - } - *const_cast<bool*>(&m_unscaled_instance_bounding_box_dirty) = false; -} - -void Selection::calc_scaled_instance_bounding_box() const -{ - BoundingBoxf3* scaled_instance_bounding_box = const_cast<BoundingBoxf3*>(&m_scaled_instance_bounding_box); - *scaled_instance_bounding_box = BoundingBoxf3(); - if (m_valid) { - for (unsigned int i : m_list) { - const GLVolume& volume = *(*m_volumes)[i]; - if (volume.is_modifier) - continue; - Transform3d trafo = volume.get_instance_transformation().get_matrix(false, false, false, false) * volume.get_volume_transformation().get_matrix(); - trafo.translation().z() += volume.get_sla_shift_z(); - scaled_instance_bounding_box->merge(volume.transformed_convex_hull_bounding_box(trafo)); - } - } - *const_cast<bool*>(&m_scaled_instance_bounding_box_dirty) = false; -} - void Selection::render_selected_volumes() const { float color[3] = { 1.0f, 1.0f, 1.0f }; diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index 3e67640c5..dea507511 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -1,10 +1,12 @@ #ifndef slic3r_GUI_Selection_hpp_ #define slic3r_GUI_Selection_hpp_ -#include <set> #include "libslic3r/Geometry.hpp" #include "GLModel.hpp" +#include <set> +#include <optional> + namespace Slic3r { class Shader; @@ -203,14 +205,11 @@ private: IndicesList m_list; Cache m_cache; Clipboard m_clipboard; - BoundingBoxf3 m_bounding_box; - bool m_bounding_box_dirty; + std::optional<BoundingBoxf3> m_bounding_box; // Bounding box of a selection, with no instance scaling applied. This bounding box // is useful for absolute scaling of tilted objects in world coordinate space. - BoundingBoxf3 m_unscaled_instance_bounding_box; - bool m_unscaled_instance_bounding_box_dirty; - BoundingBoxf3 m_scaled_instance_bounding_box; - bool m_scaled_instance_bounding_box_dirty; + std::optional<BoundingBoxf3> m_unscaled_instance_bounding_box; + std::optional<BoundingBoxf3> m_scaled_instance_bounding_box; #if ENABLE_RENDER_SELECTION_CENTER GLModel m_vbo_sphere; @@ -359,10 +358,7 @@ private: void do_remove_volume(unsigned int volume_idx); void do_remove_instance(unsigned int object_idx, unsigned int instance_idx); void do_remove_object(unsigned int object_idx); - void calc_bounding_box() const; - void calc_unscaled_instance_bounding_box() const; - void calc_scaled_instance_bounding_box() const; - void set_bounding_boxes_dirty() { m_bounding_box_dirty = true; m_unscaled_instance_bounding_box_dirty = true; m_scaled_instance_bounding_box_dirty = true; } + void set_bounding_boxes_dirty() { m_bounding_box.reset(); m_unscaled_instance_bounding_box.reset(); m_scaled_instance_bounding_box.reset(); } void render_selected_volumes() const; void render_synchronized_volumes() const; void render_bounding_box(const BoundingBoxf3& box, float* color) const;