Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorenricoturri1966 <enricoturri@seznam.cz>2022-05-12 10:41:01 +0300
committerenricoturri1966 <enricoturri@seznam.cz>2022-06-06 11:00:28 +0300
commit19712749c3eedaed1fc25d10e1ec6f66571c3607 (patch)
treeeeeb04bbb676bf2aad2aafa8240f5607dc0f1704
parenteeb81b1ef8d3e34d4b8cd755f2bb9bddde714a54 (diff)
Tech ENABLE_TRANSFORMATIONS_BY_MATRICES - Added reset button to remove skew, when detected, in object manipulator panel
Fixed conflicts during rebase with master
-rw-r--r--src/libslic3r/Geometry.cpp24
-rw-r--r--src/libslic3r/Geometry.hpp1
-rw-r--r--src/slic3r/GUI/GLCanvas3D.cpp50
-rw-r--r--src/slic3r/GUI/GLCanvas3D.hpp6
-rw-r--r--src/slic3r/GUI/GUI_ObjectManipulation.cpp83
-rw-r--r--src/slic3r/GUI/GUI_ObjectManipulation.hpp13
-rw-r--r--src/slic3r/GUI/Plater.cpp3
-rw-r--r--src/slic3r/GUI/Selection.cpp42
-rw-r--r--src/slic3r/GUI/Selection.hpp1
9 files changed, 218 insertions, 5 deletions
diff --git a/src/libslic3r/Geometry.cpp b/src/libslic3r/Geometry.cpp
index 61217f4a1..a611e10c0 100644
--- a/src/libslic3r/Geometry.cpp
+++ b/src/libslic3r/Geometry.cpp
@@ -702,6 +702,30 @@ void Transformation::reset()
}
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+void Transformation::reset_skew()
+{
+ Matrix3d rotation;
+ Matrix3d scale;
+ m_matrix.computeRotationScaling(&rotation, &scale);
+
+ const double average_scale = std::cbrt(scale(0, 0) * scale(1, 1) * scale(2, 2));
+
+ scale(0, 0) = average_scale;
+ scale(1, 1) = average_scale;
+ scale(2, 2) = average_scale;
+
+ scale(0, 1) = 0.0;
+ scale(0, 2) = 0.0;
+ scale(1, 0) = 0.0;
+ scale(1, 2) = 0.0;
+ scale(2, 0) = 0.0;
+ scale(2, 1) = 0.0;
+
+ const Vec3d offset = get_offset();
+ m_matrix = rotation * scale;
+ m_matrix.translation() = offset;
+}
+
Transform3d Transformation::get_matrix_no_offset() const
{
Transformation copy(*this);
diff --git a/src/libslic3r/Geometry.hpp b/src/libslic3r/Geometry.hpp
index bbca3a5e3..0d804c52c 100644
--- a/src/libslic3r/Geometry.hpp
+++ b/src/libslic3r/Geometry.hpp
@@ -496,6 +496,7 @@ public:
void reset_rotation() { set_rotation(Vec3d::Zero()); }
void reset_scaling_factor() { set_scaling_factor(Vec3d::Ones()); }
void reset_mirror() { set_mirror(Vec3d::Ones()); }
+ void reset_skew();
const Transform3d& get_matrix() const { return m_matrix; }
Transform3d get_matrix_no_offset() const;
diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp
index 8a2599866..45ef3c002 100644
--- a/src/slic3r/GUI/GLCanvas3D.cpp
+++ b/src/slic3r/GUI/GLCanvas3D.cpp
@@ -1101,6 +1101,9 @@ wxDEFINE_EVENT(EVT_GLCANVAS_QUESTION_MARK, SimpleEvent);
wxDEFINE_EVENT(EVT_GLCANVAS_INCREASE_INSTANCES, Event<int>);
wxDEFINE_EVENT(EVT_GLCANVAS_INSTANCE_MOVED, SimpleEvent);
wxDEFINE_EVENT(EVT_GLCANVAS_INSTANCE_ROTATED, SimpleEvent);
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+wxDEFINE_EVENT(EVT_GLCANVAS_RESET_SKEW, SimpleEvent);
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
wxDEFINE_EVENT(EVT_GLCANVAS_INSTANCE_SCALED, SimpleEvent);
wxDEFINE_EVENT(EVT_GLCANVAS_FORCE_UPDATE, SimpleEvent);
wxDEFINE_EVENT(EVT_GLCANVAS_WIPETOWER_MOVED, Vec3dEvent);
@@ -4098,9 +4101,17 @@ void GLCanvas3D::do_mirror(const std::string& snapshot_type)
ModelObject* model_object = m_model->objects[object_idx];
if (model_object != nullptr) {
if (selection_mode == Selection::Instance)
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation());
+#else
model_object->instances[instance_idx]->set_mirror(v->get_instance_mirror());
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
else if (selection_mode == Selection::Volume)
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ model_object->volumes[volume_idx]->set_transformation(v->get_volume_transformation());
+#else
model_object->volumes[volume_idx]->set_mirror(v->get_volume_mirror());
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
model_object->invalidate_bounding_box();
}
@@ -4124,6 +4135,45 @@ void GLCanvas3D::do_mirror(const std::string& snapshot_type)
m_dirty = true;
}
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+void GLCanvas3D::do_reset_skew(const std::string& snapshot_type)
+{
+ if (m_model == nullptr)
+ return;
+
+ if (!snapshot_type.empty())
+ wxGetApp().plater()->take_snapshot(_(snapshot_type));
+
+ std::set<std::pair<int, int>> done; // keeps track of modified instances
+
+ Selection::EMode selection_mode = m_selection.get_mode();
+ const Selection::IndicesList& idxs = m_selection.get_volume_idxs();
+
+ for (unsigned int id : idxs) {
+ const GLVolume* v = m_volumes.volumes[id];
+ int object_idx = v->object_idx();
+ if (object_idx < 0 || (int)m_model->objects.size() <= object_idx)
+ continue;
+
+ int instance_idx = v->instance_idx();
+ int volume_idx = v->volume_idx();
+
+ done.insert(std::pair<int, int>(object_idx, instance_idx));
+
+ ModelObject* model_object = m_model->objects[object_idx];
+ if (model_object != nullptr) {
+ model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation());
+ model_object->volumes[volume_idx]->set_transformation(v->get_volume_transformation());
+ model_object->invalidate_bounding_box();
+ }
+ }
+
+ post_event(SimpleEvent(EVT_GLCANVAS_RESET_SKEW));
+
+ m_dirty = true;
+}
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
+
void GLCanvas3D::update_gizmos_on_off_state()
{
set_as_dirty();
diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp
index 1876500e2..2daa10321 100644
--- a/src/slic3r/GUI/GLCanvas3D.hpp
+++ b/src/slic3r/GUI/GLCanvas3D.hpp
@@ -156,6 +156,9 @@ wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_MOVED, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_FORCE_UPDATE, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_WIPETOWER_MOVED, Vec3dEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_ROTATED, SimpleEvent);
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+wxDECLARE_EVENT(EVT_GLCANVAS_RESET_SKEW, SimpleEvent);
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_SCALED, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3dEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, Event<bool>);
@@ -807,6 +810,9 @@ public:
void do_rotate(const std::string& snapshot_type);
void do_scale(const std::string& snapshot_type);
void do_mirror(const std::string& snapshot_type);
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ void do_reset_skew(const std::string& snapshot_type);
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
void update_gizmos_on_off_state();
void reset_all_gizmos() { m_gizmos.reset_all_states(); }
diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp
index 141c34c9b..c82e06d7d 100644
--- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp
+++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp
@@ -481,6 +481,25 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
m_main_grid_sizer->Add(editors_grid_sizer, 1, wxEXPAND);
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ m_skew_label = new wxStaticText(parent, wxID_ANY, _L("Skew"));
+ m_main_grid_sizer->Add(m_skew_label, 1, wxEXPAND);
+
+ m_reset_skew_button = new ScalableButton(parent, wxID_ANY, ScalableBitmap(parent, "undo"));
+ m_reset_skew_button->SetToolTip(_L("Reset skew"));
+ m_reset_skew_button->Bind(wxEVT_BUTTON, [this](wxCommandEvent& e) {
+ GLCanvas3D* canvas = wxGetApp().plater()->canvas3D();
+ Selection& selection = canvas->get_selection();
+ if (selection.is_single_full_instance() || selection.is_single_volume_or_modifier()) {
+ selection.setup_cache();
+ selection.reset_skew();
+ canvas->do_reset_skew(L("Reset skew"));
+ UpdateAndShow(true);
+ }
+ });
+ m_main_grid_sizer->Add(m_reset_skew_button);
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
+
m_check_inch = new wxCheckBox(parent, wxID_ANY, _L("Inches"));
m_check_inch->SetFont(wxGetApp().normal_font());
@@ -880,6 +899,9 @@ void ObjectManipulation::update_reset_buttons_visibility()
bool show_rotation = false;
bool show_scale = false;
bool show_drop_to_bed = false;
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ bool show_skew = false;
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
#if ENABLE_WORLD_COORDINATE
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
@@ -898,8 +920,14 @@ void ObjectManipulation::update_reset_buttons_visibility()
if (m_coordinates_type == ECoordinatesType::Local && (selection.is_single_full_instance() || selection.is_single_volume_or_modifier())) {
#endif // !ENABLE_TRANSFORMATIONS_BY_MATRICES
const GLVolume* volume = selection.get_first_volume();
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ Transform3d rotation = Transform3d::Identity();
+ Transform3d scale = Transform3d::Identity();
+ Geometry::Transformation skew;
+#else
Vec3d rotation = Vec3d::Zero();
Vec3d scale = Vec3d::Ones();
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
#else
if (selection.is_single_full_instance() || selection.is_single_modifier() || selection.is_single_volume()) {
const GLVolume* volume = selection.get_first_volume();
@@ -909,27 +937,72 @@ void ObjectManipulation::update_reset_buttons_visibility()
#endif // ENABLE_WORLD_COORDINATE
if (selection.is_single_full_instance()) {
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ const Geometry::Transformation& trafo = volume->get_instance_transformation();
+ rotation = trafo.get_rotation_matrix();
+ scale = trafo.get_scaling_factor_matrix();
+ if (trafo.has_skew())
+ // the instance transform contains skew
+ skew = trafo;
+ else {
+ // the world transform contains skew
+ const Selection::IndicesList& idxs = selection.get_volume_idxs();
+ for (unsigned int id : idxs) {
+ const Geometry::Transformation world_trafo(selection.get_volume(id)->world_matrix());
+ if (world_trafo.has_skew()) {
+ skew = world_trafo;
+ break;
+ }
+ }
+ }
+#else
rotation = volume->get_instance_rotation();
scale = volume->get_instance_scaling_factor();
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
#if !ENABLE_WORLD_COORDINATE
min_z = selection.get_scaled_instance_bounding_box().min.z();
#endif // !ENABLE_WORLD_COORDINATE
}
else {
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ const Geometry::Transformation& trafo = volume->get_volume_transformation();
+ rotation = trafo.get_rotation_matrix();
+ scale = trafo.get_scaling_factor_matrix();
+ if (trafo.has_skew())
+ // the volume transform contains skew
+ skew = trafo;
+ else {
+ // the world transform contains skew
+ const Geometry::Transformation world_trafo(volume->world_matrix());
+ if (world_trafo.has_skew())
+ skew = world_trafo;
+ }
+#else
rotation = volume->get_volume_rotation();
scale = volume->get_volume_scaling_factor();
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
#if !ENABLE_WORLD_COORDINATE
min_z = get_volume_min_z(*volume);
#endif // !ENABLE_WORLD_COORDINATE
}
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ show_rotation = !rotation.isApprox(Transform3d::Identity());
+ show_scale = !scale.isApprox(Transform3d::Identity());
+ show_skew = skew.has_skew();
+#else
show_rotation = !rotation.isApprox(Vec3d::Zero());
show_scale = !scale.isApprox(Vec3d::Ones());
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
#if !ENABLE_WORLD_COORDINATE
show_drop_to_bed = std::abs(min_z) > SINKING_Z_THRESHOLD;
#endif // !ENABLE_WORLD_COORDINATE
}
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ wxGetApp().CallAfter([this, show_rotation, show_scale, show_drop_to_bed, show_skew] {
+#else
wxGetApp().CallAfter([this, show_rotation, show_scale, show_drop_to_bed] {
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
// There is a case (under OSX), when this function is called after the Manipulation panel is hidden
// So, let check if Manipulation panel is still shown for this moment
if (!this->IsShown())
@@ -937,6 +1010,10 @@ void ObjectManipulation::update_reset_buttons_visibility()
m_reset_rotation_button->Show(show_rotation);
m_reset_scale_button->Show(show_scale);
m_drop_to_bed_button->Show(show_drop_to_bed);
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ m_reset_skew_button->Show(show_skew);
+ m_skew_label->Show(show_skew);
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
// Because of CallAfter we need to layout sidebar after Show/hide of reset buttons one more time
Sidebar& panel = wxGetApp().sidebar();
@@ -1423,6 +1500,9 @@ void ObjectManipulation::msw_rescale()
m_mirror_bitmap_hidden.msw_rescale();
m_reset_scale_button->msw_rescale();
m_reset_rotation_button->msw_rescale();
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ m_reset_skew_button->msw_rescale();
+#endif /// ENABLE_TRANSFORMATIONS_BY_MATRICES
m_drop_to_bed_button->msw_rescale();
m_lock_bnt->msw_rescale();
@@ -1462,6 +1542,9 @@ void ObjectManipulation::sys_color_changed()
m_mirror_bitmap_hidden.msw_rescale();
m_reset_scale_button->msw_rescale();
m_reset_rotation_button->msw_rescale();
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ m_reset_skew_button->msw_rescale();
+#endif /// ENABLE_TRANSFORMATIONS_BY_MATRICES
m_drop_to_bed_button->msw_rescale();
m_lock_bnt->msw_rescale();
diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.hpp b/src/slic3r/GUI/GUI_ObjectManipulation.hpp
index 289485dad..696f75128 100644
--- a/src/slic3r/GUI/GUI_ObjectManipulation.hpp
+++ b/src/slic3r/GUI/GUI_ObjectManipulation.hpp
@@ -120,9 +120,12 @@ private:
wxStaticText* m_empty_str = nullptr;
// Non-owning pointers to the reset buttons, so we can hide and show them.
- ScalableButton* m_reset_scale_button = nullptr;
- ScalableButton* m_reset_rotation_button = nullptr;
- ScalableButton* m_drop_to_bed_button = nullptr;
+ ScalableButton* m_reset_scale_button{ nullptr };
+ ScalableButton* m_reset_rotation_button{ nullptr };
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ ScalableButton* m_reset_skew_button{ nullptr };
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
+ ScalableButton* m_drop_to_bed_button{ nullptr };
wxCheckBox* m_check_inch {nullptr};
@@ -176,6 +179,10 @@ private:
wxFlexGridSizer* m_main_grid_sizer;
wxFlexGridSizer* m_labels_grid_sizer;
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ wxStaticText* m_skew_label{ nullptr };
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
+
// sizers, used for msw_rescale
wxBoxSizer* m_word_local_combo_sizer;
std::vector<wxBoxSizer*> m_rescalable_sizers;
diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp
index c7ddf8f78..c9cc7fc22 100644
--- a/src/slic3r/GUI/Plater.cpp
+++ b/src/slic3r/GUI/Plater.cpp
@@ -2085,6 +2085,9 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
view3D_canvas->Bind(EVT_GLCANVAS_WIPETOWER_MOVED, &priv::on_wipetower_moved, this);
view3D_canvas->Bind(EVT_GLCANVAS_WIPETOWER_ROTATED, &priv::on_wipetower_rotated, this);
view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_ROTATED, [this](SimpleEvent&) { update(); });
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ view3D_canvas->Bind(EVT_GLCANVAS_RESET_SKEW, [this](SimpleEvent&) { update(); });
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
view3D_canvas->Bind(EVT_GLCANVAS_INSTANCE_SCALED, [this](SimpleEvent&) { update(); });
view3D_canvas->Bind(EVT_GLCANVAS_ENABLE_ACTION_BUTTONS, [this](Event<bool>& evt) { this->sidebar->enable_buttons(evt.data); });
view3D_canvas->Bind(EVT_GLCANVAS_UPDATE_GEOMETRY, &priv::on_update_geometry, this);
diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp
index 33ecd2412..346d0fe9b 100644
--- a/src/slic3r/GUI/Selection.cpp
+++ b/src/slic3r/GUI/Selection.cpp
@@ -1347,8 +1347,6 @@ void Selection::scale_and_translate(const Vec3d& scale, const Vec3d& translation
if (!m_valid)
return;
- std::cout << "Selection::scale_and_translate: " << to_string(scale) << " - " << to_string(translation) << "\n";
-
for (unsigned int i : m_list) {
GLVolume& v = *(*m_volumes)[i];
const VolumeCache& volume_data = m_cache.volumes_data[i];
@@ -1412,6 +1410,46 @@ void Selection::scale_and_translate(const Vec3d& scale, const Vec3d& translation
set_bounding_boxes_dirty();
wxGetApp().plater()->canvas3D()->requires_check_outside_state();
}
+
+void Selection::reset_skew()
+{
+ if (!m_valid)
+ return;
+
+ for (unsigned int i : m_list) {
+ GLVolume& v = *(*m_volumes)[i];
+ const VolumeCache& volume_data = m_cache.volumes_data[i];
+ const Geometry::Transformation& inst_trafo = volume_data.get_instance_transform();
+ const Geometry::Transformation& vol_trafo = volume_data.get_volume_transform();
+ if (m_mode == Instance && inst_trafo.has_skew()) {
+ Geometry::Transformation trafo = inst_trafo;
+ trafo.reset_skew();
+ v.set_instance_transformation(trafo);
+ }
+ else if (m_mode == Volume && vol_trafo.has_skew()) {
+ Geometry::Transformation trafo = vol_trafo;
+ trafo.reset_skew();
+ v.set_volume_transformation(trafo);
+ }
+ else {
+ const Geometry::Transformation world_trafo = inst_trafo * vol_trafo;
+ if (world_trafo.has_skew()) {
+ if (m_mode == Instance) {
+ // TODO
+ int a = 0;
+ }
+ else {
+ // TODO
+ int a = 0;
+ }
+ }
+ }
+ }
+
+ ensure_on_bed();
+ set_bounding_boxes_dirty();
+ wxGetApp().plater()->canvas3D()->requires_check_outside_state();
+}
#else
void Selection::translate(unsigned int object_idx, const Vec3d& displacement)
{
diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp
index bd9c9216c..0be33b1e8 100644
--- a/src/slic3r/GUI/Selection.hpp
+++ b/src/slic3r/GUI/Selection.hpp
@@ -382,6 +382,7 @@ public:
void mirror(Axis axis);
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
void scale_and_translate(const Vec3d& scale, const Vec3d& translation, TransformationType transformation_type);
+ void reset_skew();
#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
#if !ENABLE_TRANSFORMATIONS_BY_MATRICES