From 82b4a4fe113a948ee778635eb9a243f4375f7d60 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Fri, 17 Sep 2021 09:26:47 +0200 Subject: [PATCH 1/2] Place on face improvement: respect different z-rotation of instances --- src/slic3r/GUI/Selection.cpp | 10 +++------- src/slic3r/GUI/Selection.hpp | 4 +--- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 92c758d4be..3f1848d30d 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -823,10 +823,10 @@ void Selection::flattening_rotate(const Vec3d& normal) } #if !DISABLE_INSTANCES_SYNCH - // we want to synchronize z-rotation as well, otherwise the flattening behaves funny - // when applied on one of several identical instances + // Apply the same transformation also to other instances, + // but respect their possibly diffrent z-rotation. if (m_mode == Instance) - synchronize_unselected_instances(SYNC_ROTATION_FULL); + synchronize_unselected_instances(SYNC_ROTATION_GENERAL); #endif // !DISABLE_INSTANCES_SYNCH this->set_bounding_boxes_dirty(); @@ -2055,10 +2055,6 @@ void Selection::synchronize_unselected_instances(SyncRotationType sync_rotation_ v->set_instance_offset(Z, volume->get_instance_offset().z()); break; } - case SYNC_ROTATION_FULL: - // rotation comes from place on face -> force given z - v->set_instance_rotation({ rotation.x(), rotation.y(), rotation.z() }); - break; case SYNC_ROTATION_GENERAL: // generic rotation -> update instance z with the delta of the rotation. const double z_diff = Geometry::rotation_diff_z(m_cache.volumes_data[i].get_instance_rotation(), m_cache.volumes_data[j].get_instance_rotation()); diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index b3304571f8..3e67640c59 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -375,10 +375,8 @@ public: enum SyncRotationType { // Do not synchronize rotation. Either not rotating at all, or rotating by world Z axis. SYNC_ROTATION_NONE = 0, - // Synchronize fully. Used from "place on bed" feature. - SYNC_ROTATION_FULL = 1, // Synchronize after rotation by an axis not parallel with Z. - SYNC_ROTATION_GENERAL = 2, + SYNC_ROTATION_GENERAL = 1, }; void synchronize_unselected_instances(SyncRotationType sync_rotation_type); void synchronize_unselected_volumes(); From 9d7549e6610d58477838df4dcc7711e57752308d Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 17 Sep 2021 13:24:37 +0200 Subject: [PATCH 2/2] Use std::optional to replace dirty flags for bounding boxes in Selection --- src/slic3r/GUI/Selection.cpp | 96 +++++++++++++++--------------------- src/slic3r/GUI/Selection.hpp | 18 +++---- 2 files changed, 47 insertions(+), 67 deletions(-) diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 3f1848d30d..4a9c7cd564 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* bbox = const_cast*>(&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* bbox = const_cast*>(&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* bbox = const_cast*>(&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(&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(&m_bounding_box_dirty) = false; -} - -void Selection::calc_unscaled_instance_bounding_box() const -{ - BoundingBoxf3* unscaled_instance_bounding_box = const_cast(&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(&m_unscaled_instance_bounding_box_dirty) = false; -} - -void Selection::calc_scaled_instance_bounding_box() const -{ - BoundingBoxf3* scaled_instance_bounding_box = const_cast(&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(&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 3e67640c59..dea5075114 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 #include "libslic3r/Geometry.hpp" #include "GLModel.hpp" +#include +#include + 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 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 m_unscaled_instance_bounding_box; + std::optional 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;