From 910c87baec17b06ce2690def5ce6373ee27df4a8 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 2 Dec 2022 09:16:37 +0100 Subject: [PATCH 01/18] Tech ENABLE_WORLD_COORDINATE - Fix of Selection::mirror() --- src/slic3r/GUI/GLCanvas3D.cpp | 13 +++++++++++++ src/slic3r/GUI/Selection.cpp | 8 ++++++++ src/slic3r/GUI/Selection.hpp | 5 +++-- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 991bbead2..5cbff5c05 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1954,7 +1954,20 @@ std::vector GLCanvas3D::load_object(const Model& model, int obj_idx) void GLCanvas3D::mirror_selection(Axis axis) { +#if ENABLE_WORLD_COORDINATE + TransformationType transformation_type; + if (wxGetApp().obj_manipul()->is_local_coordinates()) + transformation_type.set_local(); + else if (wxGetApp().obj_manipul()->is_instance_coordinates()) + transformation_type.set_instance(); + + transformation_type.set_relative(); + + m_selection.setup_cache(); + m_selection.mirror(axis, transformation_type); +#else m_selection.mirror(axis); +#endif // ENABLE_WORLD_COORDINATE do_mirror(L("Mirror Object")); wxGetApp().obj_manipul()->set_dirty(); } diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index b27f7a738..d317b1887 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -1268,6 +1268,13 @@ void Selection::scale_to_fit_print_volume(const BuildVolume& volume) } } +#if ENABLE_WORLD_COORDINATE +void Selection::mirror(Axis axis, TransformationType transformation_type) +{ + const Vec3d mirror((axis == X) ? -1.0 : 1.0, (axis == Y) ? -1.0 : 1.0, (axis == Z) ? -1.0 : 1.0); + scale_and_translate(mirror, Vec3d::Zero(), transformation_type); +} +#else void Selection::mirror(Axis axis) { if (!m_valid) @@ -1290,6 +1297,7 @@ void Selection::mirror(Axis axis) set_bounding_boxes_dirty(); } +#endif // ENABLE_WORLD_COORDINATE #if ENABLE_WORLD_COORDINATE void Selection::scale_and_translate(const Vec3d& scale, const Vec3d& translation, TransformationType transformation_type) diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index 34b88f160..b95ac3e78 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -302,7 +302,7 @@ public: void set_deserialized(EMode mode, const std::vector> &volumes_and_instances); // Update the selection based on the new instance IDs. - void instances_changed(const std::vector &instance_ids_selected); + void instances_changed(const std::vector &instance_ids_selected); // Update the selection based on the map from old indices to new indices after m_volumes changed. // If the current selection is by instance, this call may select newly added volumes, if they belong to already selected instances. void volumes_changed(const std::vector &map_volume_old_to_new); @@ -402,11 +402,12 @@ public: void flattening_rotate(const Vec3d& normal); void scale(const Vec3d& scale, TransformationType transformation_type); void scale_to_fit_print_volume(const BuildVolume& volume); - void mirror(Axis axis); #if ENABLE_WORLD_COORDINATE void scale_and_translate(const Vec3d& scale, const Vec3d& translation, TransformationType transformation_type); + void mirror(Axis axis, TransformationType transformation_type); void reset_skew(); #else + void mirror(Axis axis); void translate(unsigned int object_idx, const Vec3d& displacement); #endif // ENABLE_WORLD_COORDINATE void translate(unsigned int object_idx, unsigned int instance_idx, const Vec3d& displacement); From 5f26b8c601cb804c078c4e1e9d19cd5ff68f3fb8 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 2 Dec 2022 14:15:04 +0100 Subject: [PATCH 02/18] Tech ENABLE_WORLD_COORDINATE - Modified behavior of mirror buttons in sidebar panel. Trigger transformation but do not show state. --- src/slic3r/GUI/GUI_ObjectManipulation.cpp | 39 ++++++++++++++++++----- src/slic3r/GUI/GUI_ObjectManipulation.hpp | 8 +++-- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index bbcad2919..19a9368f2 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -268,25 +268,39 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : btn->SetToolTip(wxString::Format(_L("Toggle %c axis mirroring"), (int)label)); btn->SetBitmapDisabled_(m_mirror_bitmap_hidden); +#if ENABLE_WORLD_COORDINATE + m_mirror_buttons[axis_idx] = btn; +#else m_mirror_buttons[axis_idx].first = btn; m_mirror_buttons[axis_idx].second = mbShown; +#endif // ENABLE_WORLD_COORDINATE sizer->AddStretchSpacer(2); sizer->Add(btn, 0, wxALIGN_CENTER_VERTICAL); btn->Bind(wxEVT_BUTTON, [this, axis_idx](wxCommandEvent&) { +#if !ENABLE_WORLD_COORDINATE Axis axis = (Axis)(axis_idx + X); if (m_mirror_buttons[axis_idx].second == mbHidden) - return; + return; +#endif // !ENABLE_WORLD_COORDINATE GLCanvas3D* canvas = wxGetApp().plater()->canvas3D(); Selection& selection = canvas->get_selection(); #if ENABLE_WORLD_COORDINATE - if (selection.is_single_volume_or_modifier()) { + TransformationType transformation_type; + if (is_local_coordinates()) + transformation_type.set_local(); + else if (is_instance_coordinates()) + transformation_type.set_instance(); + + transformation_type.set_relative(); + + selection.setup_cache(); + selection.mirror((Axis)axis_idx, transformation_type); #else if (selection.is_single_volume() || selection.is_single_modifier()) { -#endif // ENABLE_WORLD_COORDINATE GLVolume* volume = const_cast(selection.get_first_volume()); volume->set_volume_mirror(axis, -volume->get_volume_mirror(axis)); } @@ -302,6 +316,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : // Update mirroring at the GLVolumes. selection.synchronize_unselected_instances(Selection::SyncRotationType::GENERAL); selection.synchronize_unselected_volumes(); +#endif // ENABLE_WORLD_COORDINATE // Copy mirroring values from GLVolumes into Model (ModelInstance / ModelVolume), trigger background processing. canvas->do_mirror(L("Set Mirror")); UpdateAndShow(true); @@ -977,16 +992,14 @@ void ObjectManipulation::update_mirror_buttons_visibility() { GLCanvas3D* canvas = wxGetApp().plater()->canvas3D(); Selection& selection = canvas->get_selection(); - std::array new_states = {mbHidden, mbHidden, mbHidden}; #if ENABLE_WORLD_COORDINATE if (is_local_coordinates()) { -#else - if (!m_world_coordinates) { -#endif // ENABLE_WORLD_COORDINATE -#if ENABLE_WORLD_COORDINATE if (selection.is_single_full_instance() || selection.is_single_volume_or_modifier()) { #else + std::array new_states = { mbHidden, mbHidden, mbHidden }; + + if (!m_world_coordinates) { if (selection.is_single_full_instance() || selection.is_single_modifier() || selection.is_single_volume()) { #endif // ENABLE_WORLD_COORDINATE const GLVolume* volume = selection.get_first_volume(); @@ -997,10 +1010,13 @@ void ObjectManipulation::update_mirror_buttons_visibility() else mirror = volume->get_volume_mirror(); +#if !ENABLE_WORLD_COORDINATE for (unsigned char i=0; i<3; ++i) new_states[i] = (mirror[i] < 0. ? mbActive : mbShown); +#endif // !ENABLE_WORLD_COORDINATE } } +#if !ENABLE_WORLD_COORDINATE else { // the mirroring buttons should be hidden in world coordinates, // unless we make it actually mirror in world coords. @@ -1022,6 +1038,7 @@ void ObjectManipulation::update_mirror_buttons_visibility() } } }); +#endif // !ENABLE_WORLD_COORDINATE } @@ -1432,8 +1449,14 @@ void ObjectManipulation::sys_color_changed() m_drop_to_bed_button->sys_color_changed(); m_lock_bnt->sys_color_changed(); +#if ENABLE_WORLD_COORDINATE + for (int id = 0; id < 3; ++id) { + m_mirror_buttons[id]->sys_color_changed(); + } +#else for (int id = 0; id < 3; ++id) m_mirror_buttons[id].first->sys_color_changed(); +#endif // ENABLE_WORLD_COORDINATE } #if ENABLE_WORLD_COORDINATE diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.hpp b/src/slic3r/GUI/GUI_ObjectManipulation.hpp index 9995b3e6f..4085d91ce 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.hpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.hpp @@ -132,6 +132,9 @@ private: wxCheckBox* m_check_inch {nullptr}; +#if ENABLE_WORLD_COORDINATE + std::array m_mirror_buttons; +#else // Mirroring buttons and their current state enum MirrorButtonState { mbHidden, @@ -139,6 +142,7 @@ private: mbActive }; std::array, 3> m_mirror_buttons; +#endif // ENABLE_WORLD_COORDINATE // Bitmaps for the mirroring buttons. ScalableBitmap m_mirror_bitmap_on; @@ -149,8 +153,8 @@ private: bool m_dirty = false; // Cached labels for the delayed update, not localized! std::string m_new_move_label_string; - std::string m_new_rotate_label_string; - std::string m_new_scale_label_string; + std::string m_new_rotate_label_string; + std::string m_new_scale_label_string; Vec3d m_new_position; Vec3d m_new_rotation; Vec3d m_new_scale; From 724fd541a43359f71913c4f4cb15645c17b23721 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 8 Dec 2022 10:06:24 +0100 Subject: [PATCH 03/18] Follow-up of 5f26b8c601cb804c078c4e1e9d19cd5ff68f3fb8 --- src/slic3r/GUI/GUI_ObjectManipulation.cpp | 36 +++++++++++++---------- src/slic3r/GUI/GUI_ObjectManipulation.hpp | 4 ++- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index 19a9368f2..325a9621e 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -125,8 +125,10 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : // Load bitmaps to be used for the mirroring buttons: m_mirror_bitmap_on = ScalableBitmap(parent, "mirroring_on"); +#if !ENABLE_WORLD_COORDINATE m_mirror_bitmap_off = ScalableBitmap(parent, "mirroring_off"); m_mirror_bitmap_hidden = ScalableBitmap(parent, "mirroring_transparent"); +#endif // !ENABLE_WORLD_COORDINATE const int border = wxOSX ? 0 : 4; const int em = wxGetApp().em_unit(); @@ -265,12 +267,14 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : // We will add a button to toggle mirroring to each axis: auto btn = new ScalableButton(parent, wxID_ANY, "mirroring_off", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER | wxTRANSPARENT_WINDOW); +#if ENABLE_WORLD_COORDINATE + btn->SetToolTip(_L("Mirror along") + wxString::Format(_L(" %c "), (int)label) + _L("axis")); + + m_mirror_buttons[axis_idx] = btn; +#else btn->SetToolTip(wxString::Format(_L("Toggle %c axis mirroring"), (int)label)); btn->SetBitmapDisabled_(m_mirror_bitmap_hidden); -#if ENABLE_WORLD_COORDINATE - m_mirror_buttons[axis_idx] = btn; -#else m_mirror_buttons[axis_idx].first = btn; m_mirror_buttons[axis_idx].second = mbShown; #endif // ENABLE_WORLD_COORDINATE @@ -675,7 +679,7 @@ void ObjectManipulation::update_ui_from_settings() void ObjectManipulation::update_settings_value(const Selection& selection) { - m_new_move_label_string = L("Position"); + m_new_move_label_string = L("Position"); m_new_rotate_label_string = L("Rotation"); m_new_scale_label_string = L("Scale factors"); @@ -722,7 +726,7 @@ void ObjectManipulation::update_settings_value(const Selection& selection) #endif // ENABLE_WORLD_COORDINATE m_new_size = volume->get_instance_scaling_factor().cwiseProduct(wxGetApp().model().objects[volume->object_idx()]->raw_mesh_bounding_box().size()); m_new_scale = volume->get_instance_scaling_factor() * 100.0; - } + } m_new_enabled = true; } @@ -733,7 +737,7 @@ void ObjectManipulation::update_settings_value(const Selection& selection) m_new_scale = Vec3d(100.0, 100.0, 100.0); m_new_size = box.size(); m_new_rotate_label_string = L("Rotate"); - m_new_scale_label_string = L("Scale"); + m_new_scale_label_string = L("Scale"); m_new_enabled = true; } #if ENABLE_WORLD_COORDINATE @@ -765,9 +769,9 @@ void ObjectManipulation::update_settings_value(const Selection& selection) } else { #endif // ENABLE_WORLD_COORDINATE - m_new_position = volume->get_volume_offset(); - m_new_rotate_label_string = L("Rotate"); - m_new_rotation = Vec3d::Zero(); + m_new_position = volume->get_volume_offset(); + m_new_rotate_label_string = L("Rotate"); + m_new_rotation = Vec3d::Zero(); #if ENABLE_WORLD_COORDINATE m_new_size = volume->transformed_convex_hull_bounding_box(volume->get_volume_transformation().get_matrix()).size(); m_new_scale = m_new_size.cwiseQuotient(volume->transformed_convex_hull_bounding_box(volume->get_volume_transformation().get_matrix_no_scaling_factor()).size()) * 100.0; @@ -780,17 +784,17 @@ void ObjectManipulation::update_settings_value(const Selection& selection) } else if (obj_list->is_connectors_item_selected() || obj_list->multiple_selection() || obj_list->is_selected(itInstanceRoot)) { reset_settings_value(); - m_new_move_label_string = L("Translate"); - m_new_rotate_label_string = L("Rotate"); - m_new_scale_label_string = L("Scale"); + m_new_move_label_string = L("Translate"); + m_new_rotate_label_string = L("Rotate"); + m_new_scale_label_string = L("Scale"); m_new_size = selection.get_bounding_box().size(); m_new_enabled = true; } - else { + else { // No selection, reset the cache. // assert(selection.is_empty()); - reset_settings_value(); - } + reset_settings_value(); + } } void ObjectManipulation::update_if_dirty() @@ -1442,8 +1446,10 @@ void ObjectManipulation::sys_color_changed() editor->sys_color_changed(this); m_mirror_bitmap_on.sys_color_changed(); +#if !ENABLE_WORLD_COORDINATE m_mirror_bitmap_off.sys_color_changed(); m_mirror_bitmap_hidden.sys_color_changed(); +#endif // !ENABLE_WORLD_COORDINATE m_reset_scale_button->sys_color_changed(); m_reset_rotation_button->sys_color_changed(); m_drop_to_bed_button->sys_color_changed(); diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.hpp b/src/slic3r/GUI/GUI_ObjectManipulation.hpp index 4085d91ce..9ec45b939 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.hpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.hpp @@ -146,8 +146,10 @@ private: // Bitmaps for the mirroring buttons. ScalableBitmap m_mirror_bitmap_on; +#if !ENABLE_WORLD_COORDINATE ScalableBitmap m_mirror_bitmap_off; ScalableBitmap m_mirror_bitmap_hidden; +#endif // !ENABLE_WORLD_COORDINATE // Needs to be updated from OnIdle? bool m_dirty = false; @@ -171,7 +173,7 @@ private: choice_ctrl* m_word_local_combo { nullptr }; ScalableBitmap m_manifold_warning_bmp; - wxStaticBitmap* m_fix_throught_netfab_bitmap; + wxStaticBitmap* m_fix_throught_netfab_bitmap{ nullptr }; #if ENABLE_WORLD_COORDINATE // Currently focused editor (nullptr if none) From cd6808fc73c5ec58e31836a0350c9e5bfd8025df Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 8 Dec 2022 10:19:29 +0100 Subject: [PATCH 04/18] Tech ENABLE_WORLD_COORDINATE - Renamed coordinate systems --- src/slic3r/GUI/GUI_ObjectManipulation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index 325a9621e..42ea912f9 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -1080,8 +1080,8 @@ wxString ObjectManipulation::coordinate_type_str(ECoordinatesType type) switch (type) { case ECoordinatesType::World: { return _L("World coordinates"); } - case ECoordinatesType::Instance: { return _L("Instance coordinates"); } - case ECoordinatesType::Local: { return _L("Local coordinates"); } + case ECoordinatesType::Instance: { return _L("Object coordinates"); } + case ECoordinatesType::Local: { return _L("Part coordinates"); } default: { assert(false); return _L("Unknown"); } } } From ed5815f919b57348a9b1a53dee4191cd0b247042 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 8 Dec 2022 10:50:08 +0100 Subject: [PATCH 05/18] Tech ENABLE_WORLD_COORDINATE - Show coordinate axes in scene view, while editing fields into the object manipulator panel, only for instance reference system --- src/slic3r/GUI/Selection.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index cdc653b5b..7e44b73f6 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -119,10 +119,10 @@ Selection::Selection() { this->set_bounding_boxes_dirty(); #if ENABLE_WORLD_COORDINATE - m_axes.set_stem_radius(0.15f); - m_axes.set_stem_length(3.0f); - m_axes.set_tip_radius(0.45f); - m_axes.set_tip_length(1.5f); + m_axes.set_stem_radius(0.5f); + m_axes.set_stem_length(20.0f); + m_axes.set_tip_radius(1.5f); + m_axes.set_tip_length(5.0f); #endif // ENABLE_WORLD_COORDINATE } @@ -1864,7 +1864,7 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field) #if ENABLE_WORLD_COORDINATE if (!boost::starts_with(sidebar_field, "layer")) { - if (!wxGetApp().obj_manipul()->is_world_coordinates()) + if (wxGetApp().obj_manipul()->is_instance_coordinates()) m_axes.render(Geometry::translation_transform(axes_center) * orient_matrix, 0.25f); } #endif // ENABLE_WORLD_COORDINATE From 94da15d3ba0c1248a14f496b41c5e2934b38b35a Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 8 Dec 2022 13:41:37 +0100 Subject: [PATCH 06/18] Tech ENABLE_WORLD_COORDINATE - Fixed sizing using the sidebar panel when there is a multiple selection --- src/slic3r/GUI/Selection.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 7e44b73f6..7ca8647f4 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -1331,14 +1331,19 @@ void Selection::scale_and_translate(const Vec3d& scale, const Vec3d& translation // convert from absolute scaling to relative scaling BoundingBoxf3 original_box; if (m_mode == Instance) { - assert(is_from_fully_selected_instance(i)); + if (is_single_full_instance()) { if (transformation_type.world()) original_box = get_full_unscaled_instance_bounding_box(); else original_box = get_full_unscaled_instance_local_bounding_box(); + } + else + original_box = get_bounding_box(); } else { - if (transformation_type.world()) + if (!is_single_volume_or_modifier()) + original_box = get_bounding_box(); + else if (transformation_type.world()) original_box = v.transformed_convex_hull_bounding_box((volume_data.get_instance_transform() * volume_data.get_volume_transform()).get_matrix_no_scaling_factor()); else if (transformation_type.instance()) @@ -1378,8 +1383,15 @@ void Selection::scale_and_translate(const Vec3d& scale, const Vec3d& translation else assert(false); } - else - transform_volume_relative(v, volume_data, transformation_type, Geometry::translation_transform(translation) * Geometry::scale_transform(relative_scale)); + else { + if (!is_single_volume_or_modifier()) { + const Transform3d scale_matrix = Geometry::scale_transform(relative_scale); + const Vec3d offset = volume_data.get_instance_transform().get_matrix_no_offset().inverse() * (m_cache.dragging_center - inst_trafo.get_offset()); + v.set_volume_transformation(Geometry::translation_transform(offset) * scale_matrix * Geometry::translation_transform(-offset) * volume_data.get_volume_transform().get_matrix()); + } + else + transform_volume_relative(v, volume_data, transformation_type, Geometry::translation_transform(translation) * Geometry::scale_transform(relative_scale)); + } } #if !DISABLE_INSTANCES_SYNCH From c0ab834519da90554351d3d98b1252e56240fe33 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 8 Dec 2022 15:09:36 +0100 Subject: [PATCH 07/18] Tech ENABLE_WORLD_COORDINATE - Fixed sidebar hints not hidden from 3D scene when deleting the current selection --- src/slic3r/GUI/GUI_ObjectList.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 8c1546410..3d55e2174 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -2825,8 +2825,12 @@ void ObjectList::part_selection_changed() panel.Freeze(); #if ENABLE_WORLD_COORDINATE - const ManipulationEditor* const editor = wxGetApp().obj_manipul()->get_focused_editor(); - const std::string opt_key = (editor != nullptr) ? editor->get_full_opt_name() : ""; + std::string opt_key; + if (m_selected_object_id >= 0) { + const ManipulationEditor* const editor = wxGetApp().obj_manipul()->get_focused_editor(); + if (editor != nullptr) + opt_key = editor->get_full_opt_name(); + } wxGetApp().plater()->canvas3D()->handle_sidebar_focus_event(opt_key, !opt_key.empty()); #else wxGetApp().plater()->canvas3D()->handle_sidebar_focus_event("", false); From 0aa88e1deae128c4d0ec7b62ac0cbf2b758f79cc Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 9 Dec 2022 11:12:48 +0100 Subject: [PATCH 08/18] Tech ENABLE_WORLD_COORDINATE - Fixed sizing of volumes --- src/slic3r/GUI/GUI_ObjectManipulation.cpp | 27 ++++++++++++++++------- src/slic3r/GUI/Selection.cpp | 3 +-- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index 42ea912f9..73438f679 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -1219,13 +1219,24 @@ void ObjectManipulation::change_size_value(int axis, double value) #else if (selection.is_single_volume() || selection.is_single_modifier()) { #endif // ENABLE_WORLD_COORDINATE - const GLVolume* v = selection.get_first_volume(); - const Vec3d local_size = size.cwiseQuotient(v->get_instance_scaling_factor()); - const Vec3d local_ref_size = v->bounding_box().size().cwiseProduct(v->get_volume_scaling_factor()); - const Vec3d local_change = local_size.cwiseQuotient(local_ref_size); - size = local_change.cwiseProduct(v->get_volume_scaling_factor()); - ref_size = Vec3d::Ones(); +#if ENABLE_WORLD_COORDINATE + if (is_world_coordinates()) { + size = size.cwiseQuotient(ref_size); + ref_size = Vec3d::Ones(); + } + else { +#endif // ENABLE_WORLD_COORDINATE + const GLVolume* v = selection.get_first_volume(); + const Vec3d local_size = size.cwiseQuotient(v->get_instance_scaling_factor()); + const Vec3d local_ref_size = v->bounding_box().size().cwiseProduct(v->get_volume_scaling_factor()); + const Vec3d local_change = local_size.cwiseQuotient(local_ref_size); + + size = local_change.cwiseProduct(v->get_volume_scaling_factor()); + ref_size = Vec3d::Ones(); +#if ENABLE_WORLD_COORDINATE + } +#endif // ENABLE_WORLD_COORDINATE } else if (selection.is_single_full_instance()) #if ENABLE_WORLD_COORDINATE @@ -1243,8 +1254,8 @@ void ObjectManipulation::change_size_value(int axis, double value) #endif // ENABLE_WORLD_COORDINATE m_cache.size = size; - m_cache.size_rounded(axis) = DBL_MAX; - this->UpdateAndShow(true); + m_cache.size_rounded(axis) = DBL_MAX; + this->UpdateAndShow(true); } void ObjectManipulation::do_scale(int axis, const Vec3d &scale) const diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 7ca8647f4..291688c4b 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -1344,8 +1344,7 @@ void Selection::scale_and_translate(const Vec3d& scale, const Vec3d& translation if (!is_single_volume_or_modifier()) original_box = get_bounding_box(); else if (transformation_type.world()) - original_box = v.transformed_convex_hull_bounding_box((volume_data.get_instance_transform() * - volume_data.get_volume_transform()).get_matrix_no_scaling_factor()); + original_box = get_bounding_box(); else if (transformation_type.instance()) original_box = v.transformed_convex_hull_bounding_box(volume_data.get_volume_transform().get_matrix_no_scaling_factor()); else From cb81bd52fa9ea3abb14e781f981cc56151e15817 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 9 Dec 2022 13:40:22 +0100 Subject: [PATCH 09/18] Tech ENABLE_WORLD_COORDINATE - Show warning icon when the transformation is left handed --- src/slic3r/GUI/GUI_ObjectManipulation.cpp | 25 ++++++++++++++--------- src/slic3r/GUI/GUI_ObjectManipulation.hpp | 3 +++ 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index 73438f679..d5660da59 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -329,7 +329,12 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : editors_grid_sizer->Add(sizer, 0, wxALIGN_CENTER_HORIZONTAL); } +#if ENABLE_WORLD_COORDINATE + m_mirror_warning_bitmap = new wxStaticBitmap(parent, wxID_ANY, wxNullBitmap); + editors_grid_sizer->Add(m_mirror_warning_bitmap, 0, wxALIGN_CENTER_VERTICAL); +#else editors_grid_sizer->AddStretchSpacer(1); +#endif // ENABLE_WORLD_COORDINATE editors_grid_sizer->AddStretchSpacer(1); // add EditBoxes @@ -901,6 +906,7 @@ void ObjectManipulation::update_reset_buttons_visibility() bool show_drop_to_bed = false; #if ENABLE_WORLD_COORDINATE bool show_skew = false; + bool show_mirror_warning = false; if (selection.is_single_full_instance() || selection.is_single_volume_or_modifier()) { const double min_z = selection.is_single_full_instance() ? selection.get_scaled_instance_bounding_box().min.z() : @@ -910,7 +916,6 @@ void ObjectManipulation::update_reset_buttons_visibility() const GLVolume* volume = selection.get_first_volume(); Transform3d rotation = Transform3d::Identity(); Transform3d scale = Transform3d::Identity(); - Geometry::Transformation skew; #else if (selection.is_single_full_instance() || selection.is_single_modifier() || selection.is_single_volume()) { const GLVolume* volume = selection.get_first_volume(); @@ -926,11 +931,9 @@ void ObjectManipulation::update_reset_buttons_visibility() scale = trafo.get_scaling_factor_matrix(); 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; - } + const Geometry::Transformation world_trafo(selection.get_volume(id)->world_matrix()); + show_skew |= world_trafo.has_skew(); + show_mirror_warning |= world_trafo.get_matrix().matrix().determinant() < 0.0; } #else rotation = volume->get_instance_rotation(); @@ -944,8 +947,8 @@ void ObjectManipulation::update_reset_buttons_visibility() rotation = trafo.get_rotation_matrix(); scale = trafo.get_scaling_factor_matrix(); const Geometry::Transformation world_trafo(volume->world_matrix()); - if (world_trafo.has_skew()) - skew = world_trafo; + show_skew |= world_trafo.has_skew(); + show_mirror_warning |= world_trafo.get_matrix().matrix().determinant() < 0.0; #else rotation = volume->get_volume_rotation(); scale = volume->get_volume_scaling_factor(); @@ -955,7 +958,6 @@ void ObjectManipulation::update_reset_buttons_visibility() #if ENABLE_WORLD_COORDINATE 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()); @@ -964,7 +966,7 @@ void ObjectManipulation::update_reset_buttons_visibility() } #if ENABLE_WORLD_COORDINATE - wxGetApp().CallAfter([this, show_rotation, show_scale, show_drop_to_bed, show_skew] { + wxGetApp().CallAfter([this, show_rotation, show_scale, show_drop_to_bed, show_skew, show_mirror_warning] { #else wxGetApp().CallAfter([this, show_rotation, show_scale, show_drop_to_bed] { #endif // ENABLE_WORLD_COORDINATE @@ -978,6 +980,9 @@ void ObjectManipulation::update_reset_buttons_visibility() #if ENABLE_WORLD_COORDINATE m_reset_skew_button->Show(show_skew); m_skew_label->Show(show_skew); + m_mirror_warning_bitmap->SetBitmap(show_mirror_warning ? m_manifold_warning_bmp.bmp() : wxNullBitmap); + m_mirror_warning_bitmap->SetMinSize(show_mirror_warning ? m_manifold_warning_bmp.GetSize() : wxSize(0, 0)); + m_mirror_warning_bitmap->SetToolTip(show_mirror_warning ? _L("Left handed") : ""); #endif // ENABLE_WORLD_COORDINATE // Because of CallAfter we need to layout sidebar after Show/hide of reset buttons one more time diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.hpp b/src/slic3r/GUI/GUI_ObjectManipulation.hpp index 9ec45b939..69022dde7 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.hpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.hpp @@ -174,6 +174,9 @@ private: ScalableBitmap m_manifold_warning_bmp; wxStaticBitmap* m_fix_throught_netfab_bitmap{ nullptr }; +#if ENABLE_WORLD_COORDINATE + wxStaticBitmap* m_mirror_warning_bitmap{ nullptr }; +#endif // ENABLE_WORLD_COORDINATE #if ENABLE_WORLD_COORDINATE // Currently focused editor (nullptr if none) From cd389eb7ebd35c9d615d383e2771171ad27398dc Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Mon, 12 Dec 2022 08:40:39 +0100 Subject: [PATCH 10/18] Follow-up of cd6808fc73c5ec58e31836a0350c9e5bfd8025df --- src/slic3r/GUI/GUI_ObjectManipulation.cpp | 6 +++--- src/slic3r/GUI/Selection.cpp | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index d5660da59..7a5167d4a 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -565,15 +565,15 @@ void ObjectManipulation::Show(const bool show) bool show_world_local_combo = wxGetApp().get_mode() != comSimple && (selection.is_single_full_instance() || selection.is_single_volume_or_modifier()); if (selection.is_single_volume_or_modifier() && m_word_local_combo->GetCount() < 3) { #ifdef __linux__ - m_word_local_combo->Insert(coordinate_type_str(ECoordinatesType::Instance), 1); + m_word_local_combo->Insert(coordinate_type_str(ECoordinatesType::Local), 2); #else - m_word_local_combo->Insert(coordinate_type_str(ECoordinatesType::Instance), wxNullBitmap, 1); + m_word_local_combo->Insert(coordinate_type_str(ECoordinatesType::Local), wxNullBitmap, 2); #endif // __linux__ m_word_local_combo->Select((int)ECoordinatesType::World); this->set_coordinates_type(m_word_local_combo->GetString(m_word_local_combo->GetSelection())); } else if (selection.is_single_full_instance() && m_word_local_combo->GetCount() > 2) { - m_word_local_combo->Delete(1); + m_word_local_combo->Delete(2); m_word_local_combo->Select((int)ECoordinatesType::World); this->set_coordinates_type(m_word_local_combo->GetString(m_word_local_combo->GetSelection())); } diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 291688c4b..24b7d56fb 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -828,7 +828,7 @@ void Selection::translate(const Vec3d& displacement, TransformationType transfor assert(is_from_fully_selected_instance(i)); if (transformation_type.world()) v.set_instance_transformation(Geometry::translation_transform(displacement) * volume_data.get_instance_full_matrix()); - else if (transformation_type.local()) { + else if (transformation_type.instance()) { const Vec3d world_displacement = volume_data.get_instance_rotation_matrix() * displacement; v.set_instance_transformation(Geometry::translation_transform(world_displacement) * volume_data.get_instance_full_matrix()); } @@ -918,7 +918,7 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_ else { if (transformation_type.world()) new_rotation_matrix = rotation_matrix * inst_trafo.get_rotation_matrix(); - else if (transformation_type.local()) + else if (transformation_type.instance()) new_rotation_matrix = inst_trafo.get_rotation_matrix() * rotation_matrix; else assert(false); @@ -948,7 +948,7 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_ SyncRotationType synch; if (transformation_type.world() && rot_axis_max == 2) synch = SyncRotationType::NONE; - else if (transformation_type.local()) + else if (transformation_type.instance()) synch = SyncRotationType::FULL; else synch = SyncRotationType::GENERAL; @@ -1365,7 +1365,7 @@ void Selection::scale_and_translate(const Vec3d& scale, const Vec3d& translation Geometry::translation_transform(translation) * inst_trafo.get_offset_matrix(); v.set_instance_transformation(offset_matrix * scale_matrix * inst_trafo.get_matrix_no_offset()); } - else if (transformation_type.local()) { + else if (transformation_type.instance()) { const Transform3d scale_matrix = Geometry::scale_transform(relative_scale); Vec3d offset; if (transformation_type.joint() && translation.isApprox(Vec3d::Zero())) { From a4b64862cc143eb942014187362c757102329c1a Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 13 Dec 2022 09:42:37 +0100 Subject: [PATCH 11/18] Tech ENABLE_WORLD_COORDINATE - Fixed rotation of multipart selections --- src/slic3r/GUI/Selection.cpp | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 24b7d56fb..ff1156c1a 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -931,13 +931,23 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_ inst_trafo.get_scaling_factor_matrix(), inst_trafo.get_mirror_matrix())); } else { - if (transformation_type.absolute()) { + if (!is_single_volume_or_modifier()) { + assert(transformation_type.world()); const Geometry::Transformation& volume_trafo = volume_data.get_volume_transform(); - v.set_volume_transformation(Geometry::assemble_transform(volume_trafo.get_offset_matrix(), Geometry::rotation_transform(rotation), - volume_trafo.get_scaling_factor_matrix(), volume_trafo.get_mirror_matrix())); + const Geometry::Transformation& inst_trafo = volume_data.get_instance_transform(); + const Vec3d inst_pivot = transformation_type.independent() ? volume_trafo.get_offset() : (Vec3d)(inst_trafo.get_matrix().inverse() * m_cache.dragging_center); + const Transform3d trafo = Geometry::translation_transform(inst_pivot) * rotation_matrix * Geometry::translation_transform(-inst_pivot); + v.set_volume_transformation(trafo * volume_trafo.get_matrix()); + } + else { + if (transformation_type.absolute()) { + const Geometry::Transformation& volume_trafo = volume_data.get_volume_transform(); + v.set_volume_transformation(Geometry::assemble_transform(volume_trafo.get_offset_matrix(), Geometry::rotation_transform(rotation), + volume_trafo.get_scaling_factor_matrix(), volume_trafo.get_mirror_matrix())); + } + else + transform_volume_relative(v, volume_data, transformation_type, Geometry::rotation_transform(rotation)); } - else - transform_volume_relative(v, volume_data, transformation_type, Geometry::rotation_transform(rotation)); } } @@ -1384,6 +1394,9 @@ void Selection::scale_and_translate(const Vec3d& scale, const Vec3d& translation } else { if (!is_single_volume_or_modifier()) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + assert(transformation_type.world()); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ const Transform3d scale_matrix = Geometry::scale_transform(relative_scale); const Vec3d offset = volume_data.get_instance_transform().get_matrix_no_offset().inverse() * (m_cache.dragging_center - inst_trafo.get_offset()); v.set_volume_transformation(Geometry::translation_transform(offset) * scale_matrix * Geometry::translation_transform(-offset) * volume_data.get_volume_transform().get_matrix()); From f67f7772a4328d6c10d7c79da08f3f8f2f5e3f2a Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 13 Dec 2022 13:31:34 +0100 Subject: [PATCH 12/18] Tech ENABLE_WORLD_COORDINATE - Fixed rendering of selection bounding box --- src/slic3r/GUI/Selection.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index ff1156c1a..98993907d 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -1394,9 +1394,7 @@ void Selection::scale_and_translate(const Vec3d& scale, const Vec3d& translation } else { if (!is_single_volume_or_modifier()) { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ assert(transformation_type.world()); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ const Transform3d scale_matrix = Geometry::scale_transform(relative_scale); const Vec3d offset = volume_data.get_instance_transform().get_matrix_no_offset().inverse() * (m_cache.dragging_center - inst_trafo.get_offset()); v.set_volume_transformation(Geometry::translation_transform(offset) * scale_matrix * Geometry::translation_transform(-offset) * volume_data.get_volume_transform().get_matrix()); @@ -1739,8 +1737,8 @@ void Selection::render(float scale_factor) } else if (coordinates_type == ECoordinatesType::Local && is_single_volume_or_modifier()) { const GLVolume& v = *get_first_volume(); - box = v.transformed_convex_hull_bounding_box(v.get_volume_transformation().get_scaling_factor_matrix()); - trafo = v.get_instance_transformation().get_matrix() * v.get_volume_transformation().get_matrix_no_scaling_factor(); + box = v.bounding_box(); + trafo = v.world_matrix(); } else { const Selection::IndicesList& ids = get_volume_idxs(); @@ -1748,9 +1746,7 @@ void Selection::render(float scale_factor) const GLVolume& v = *get_volume(id); box.merge(v.transformed_convex_hull_bounding_box(v.get_volume_transformation().get_matrix())); } - const Geometry::Transformation inst_trafo = get_first_volume()->get_instance_transformation(); - box = box.transformed(inst_trafo.get_scaling_factor_matrix()); - trafo = inst_trafo.get_matrix_no_scaling_factor(); + trafo = get_first_volume()->get_instance_transformation().get_matrix(); } render_bounding_box(box, trafo, ColorRGB::WHITE()); From 88bd5de57860d6d290dc2939c263a7335466c746 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 13 Dec 2022 15:10:42 +0100 Subject: [PATCH 13/18] Follow-up of 0aa88e1deae128c4d0ec7b62ac0cbf2b758f79cc --- src/slic3r/GUI/GUI_ObjectManipulation.cpp | 33 +++++++++-------------- src/slic3r/GUI/Selection.cpp | 2 +- 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index 7a5167d4a..a13206cbf 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -1221,36 +1221,29 @@ void ObjectManipulation::change_size_value(int axis, double value) Vec3d ref_size = m_cache.size; #if ENABLE_WORLD_COORDINATE if (selection.is_single_volume_or_modifier()) { + size = size.cwiseQuotient(ref_size); + ref_size = Vec3d::Ones(); #else if (selection.is_single_volume() || selection.is_single_modifier()) { -#endif // ENABLE_WORLD_COORDINATE + const GLVolume* v = selection.get_first_volume(); + const Vec3d local_size = size.cwiseQuotient(v->get_instance_scaling_factor()); + const Vec3d local_ref_size = v->bounding_box().size().cwiseProduct(v->get_volume_scaling_factor()); + const Vec3d local_change = local_size.cwiseQuotient(local_ref_size); -#if ENABLE_WORLD_COORDINATE - if (is_world_coordinates()) { - size = size.cwiseQuotient(ref_size); - ref_size = Vec3d::Ones(); - } - else { -#endif // ENABLE_WORLD_COORDINATE - const GLVolume* v = selection.get_first_volume(); - const Vec3d local_size = size.cwiseQuotient(v->get_instance_scaling_factor()); - const Vec3d local_ref_size = v->bounding_box().size().cwiseProduct(v->get_volume_scaling_factor()); - const Vec3d local_change = local_size.cwiseQuotient(local_ref_size); - - size = local_change.cwiseProduct(v->get_volume_scaling_factor()); - ref_size = Vec3d::Ones(); -#if ENABLE_WORLD_COORDINATE - } + size = local_change.cwiseProduct(v->get_volume_scaling_factor()); + ref_size = Vec3d::Ones(); #endif // ENABLE_WORLD_COORDINATE } - else if (selection.is_single_full_instance()) + else if (selection.is_single_full_instance()) { #if ENABLE_WORLD_COORDINATE - ref_size = is_world_coordinates() ? + size = size.cwiseQuotient(ref_size); + ref_size = Vec3d::Ones(); #else ref_size = m_world_coordinates ? -#endif // ENABLE_WORLD_COORDINATE selection.get_unscaled_instance_bounding_box().size() : wxGetApp().model().objects[selection.get_first_volume()->object_idx()]->raw_mesh_bounding_box().size(); +#endif // ENABLE_WORLD_COORDINATE + } #if ENABLE_WORLD_COORDINATE this->do_size(axis, size.cwiseQuotient(ref_size)); diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 98993907d..5705ffafc 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -1356,7 +1356,7 @@ void Selection::scale_and_translate(const Vec3d& scale, const Vec3d& translation else if (transformation_type.world()) original_box = get_bounding_box(); else if (transformation_type.instance()) - original_box = v.transformed_convex_hull_bounding_box(volume_data.get_volume_transform().get_matrix_no_scaling_factor()); + original_box = v.transformed_convex_hull_bounding_box(volume_data.get_volume_transform().get_matrix()); else original_box = v.bounding_box(); } From 010c12612cc3842c578db8ec87c258689d4e3b1e Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 13 Dec 2022 15:53:15 +0100 Subject: [PATCH 14/18] Tech ENABLE_WORLD_COORDINATE - Rework of method Selection::transform_volume_relative() and simplified client code --- src/slic3r/GUI/Selection.cpp | 51 ++++++++++++++++++------------------ src/slic3r/GUI/Selection.hpp | 2 +- 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 5705ffafc..014a30322 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -836,9 +836,8 @@ void Selection::translate(const Vec3d& displacement, TransformationType transfor assert(false); } else { - const Vec3d offset = transformation_type.local() ? - (Vec3d)(volume_data.get_volume_transform().get_rotation_matrix() * displacement) : displacement; - transform_volume_relative(v, volume_data, transformation_type, Geometry::translation_transform(offset)); + assert(transformation_type.relative()); + transform_volume_relative(v, volume_data, transformation_type, Geometry::translation_transform(displacement), m_cache.dragging_center); } } @@ -933,20 +932,12 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_ else { if (!is_single_volume_or_modifier()) { assert(transformation_type.world()); - const Geometry::Transformation& volume_trafo = volume_data.get_volume_transform(); - const Geometry::Transformation& inst_trafo = volume_data.get_instance_transform(); - const Vec3d inst_pivot = transformation_type.independent() ? volume_trafo.get_offset() : (Vec3d)(inst_trafo.get_matrix().inverse() * m_cache.dragging_center); - const Transform3d trafo = Geometry::translation_transform(inst_pivot) * rotation_matrix * Geometry::translation_transform(-inst_pivot); - v.set_volume_transformation(trafo * volume_trafo.get_matrix()); + transform_volume_relative(v, volume_data, transformation_type, rotation_matrix, m_cache.dragging_center); } else { - if (transformation_type.absolute()) { - const Geometry::Transformation& volume_trafo = volume_data.get_volume_transform(); - v.set_volume_transformation(Geometry::assemble_transform(volume_trafo.get_offset_matrix(), Geometry::rotation_transform(rotation), - volume_trafo.get_scaling_factor_matrix(), volume_trafo.get_mirror_matrix())); - } - else - transform_volume_relative(v, volume_data, transformation_type, Geometry::rotation_transform(rotation)); + assert(transformation_type.relative()); + transformation_type.set_independent(); + transform_volume_relative(v, volume_data, transformation_type, rotation_matrix, m_cache.dragging_center); } } } @@ -1395,12 +1386,13 @@ void Selection::scale_and_translate(const Vec3d& scale, const Vec3d& translation else { if (!is_single_volume_or_modifier()) { assert(transformation_type.world()); - const Transform3d scale_matrix = Geometry::scale_transform(relative_scale); - const Vec3d offset = volume_data.get_instance_transform().get_matrix_no_offset().inverse() * (m_cache.dragging_center - inst_trafo.get_offset()); - v.set_volume_transformation(Geometry::translation_transform(offset) * scale_matrix * Geometry::translation_transform(-offset) * volume_data.get_volume_transform().get_matrix()); + transform_volume_relative(v, volume_data, transformation_type, Geometry::translation_transform(translation) * Geometry::scale_transform(relative_scale), m_cache.dragging_center); + } + else { + assert(transformation_type.relative()); + transformation_type.set_independent(); + transform_volume_relative(v, volume_data, transformation_type, Geometry::translation_transform(translation) * Geometry::scale_transform(relative_scale), m_cache.dragging_center); } - else - transform_volume_relative(v, volume_data, transformation_type, Geometry::translation_transform(translation) * Geometry::scale_transform(relative_scale)); } } @@ -3049,17 +3041,24 @@ void Selection::paste_objects_from_clipboard() #if ENABLE_WORLD_COORDINATE void Selection::transform_volume_relative(GLVolume& volume, const VolumeCache& volume_data, TransformationType transformation_type, - const Transform3d& transform) + const Transform3d& transform, const Vec3d& world_pivot) { - const Geometry::Transformation& inst_trafo = volume_data.get_instance_transform(); + assert(transformation_type.relative()); + const Geometry::Transformation& volume_trafo = volume_data.get_volume_transform(); + const Geometry::Transformation& inst_trafo = volume_data.get_instance_transform(); + if (transformation_type.world()) { + const Vec3d inst_pivot = transformation_type.independent() ? volume_trafo.get_offset() : (Vec3d)(inst_trafo.get_matrix().inverse() * world_pivot); const Transform3d inst_matrix_no_offset = inst_trafo.get_matrix_no_offset(); - const Transform3d new_volume_matrix = inst_matrix_no_offset.inverse() * transform * inst_matrix_no_offset; - volume.set_volume_transformation(volume_trafo.get_offset_matrix() * new_volume_matrix * volume_trafo.get_matrix_no_offset()); + const Transform3d trafo = Geometry::translation_transform(inst_pivot) * inst_matrix_no_offset.inverse() * transform * inst_matrix_no_offset * Geometry::translation_transform(-inst_pivot); + volume.set_volume_transformation(trafo * volume_trafo.get_matrix()); + } + else if (transformation_type.instance()) { + const Vec3d inst_pivot = transformation_type.independent() ? volume_trafo.get_offset() : (Vec3d)(inst_trafo.get_matrix().inverse() * world_pivot); + const Transform3d trafo = Geometry::translation_transform(inst_pivot) * transform * Geometry::translation_transform(-inst_pivot); + volume.set_volume_transformation(trafo * volume_trafo.get_matrix()); } - else if (transformation_type.instance()) - volume.set_volume_transformation(volume_trafo.get_offset_matrix() * transform * volume_trafo.get_matrix_no_offset()); else if (transformation_type.local()) { const Geometry::Transformation trafo(transform); volume.set_volume_transformation(trafo.get_offset_matrix() * volume_trafo.get_matrix() * trafo.get_matrix_no_offset()); diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index a9479d5a9..f6bc41260 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -502,7 +502,7 @@ private: #if ENABLE_WORLD_COORDINATE void transform_volume_relative(GLVolume& volume, const VolumeCache& volume_data, TransformationType transformation_type, - const Transform3d& transform); + const Transform3d& transform, const Vec3d& world_pivot); #endif // ENABLE_WORLD_COORDINATE }; From 9cc5659e5040299cc5abf71bf86f825328fdae9d Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 14 Dec 2022 12:45:40 +0100 Subject: [PATCH 15/18] Tech ENABLE_WORLD_COORDINATE - Fixed scaling using sidebar panel --- src/slic3r/GUI/GUI_ObjectManipulation.cpp | 16 +++++++++++----- src/slic3r/GUI/Selection.cpp | 16 ++++++++-------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index a13206cbf..2fa985a0a 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -712,25 +712,29 @@ void ObjectManipulation::update_settings_value(const Selection& selection) #if ENABLE_WORLD_COORDINATE if (is_world_coordinates()) { m_new_position = volume->get_instance_offset(); + m_new_scale_label_string = L("Scale"); + m_new_scale = Vec3d(100.0, 100.0, 100.0); #else if (m_world_coordinates) { + m_new_scale = m_new_size.cwiseQuotient(selection.get_unscaled_instance_bounding_box().size()) * 100.0; #endif // ENABLE_WORLD_COORDINATE m_new_rotate_label_string = L("Rotate"); m_new_rotation = Vec3d::Zero(); m_new_size = selection.get_scaled_instance_bounding_box().size(); - m_new_scale = m_new_size.cwiseQuotient(selection.get_unscaled_instance_bounding_box().size()) * 100.0; } else { #if ENABLE_WORLD_COORDINATE m_new_move_label_string = L("Translate"); m_new_rotate_label_string = L("Rotate"); + m_new_scale_label_string = L("Scale"); m_new_position = Vec3d::Zero(); m_new_rotation = Vec3d::Zero(); + m_new_scale = Vec3d(100.0, 100.0, 100.0); #else m_new_rotation = volume->get_instance_rotation() * (180.0 / M_PI); + m_new_scale = volume->get_instance_scaling_factor() * 100.0; #endif // ENABLE_WORLD_COORDINATE m_new_size = volume->get_instance_scaling_factor().cwiseProduct(wxGetApp().model().objects[volume->object_idx()]->raw_mesh_bounding_box().size()); - m_new_scale = volume->get_instance_scaling_factor() * 100.0; } m_new_enabled = true; @@ -760,9 +764,10 @@ void ObjectManipulation::update_settings_value(const Selection& selection) m_new_position = offset; m_new_rotate_label_string = L("Rotate"); + m_new_scale_label_string = L("Scale"); + m_new_scale = Vec3d(100.0, 100.0, 100.0); m_new_rotation = Vec3d::Zero(); m_new_size = volume->transformed_convex_hull_bounding_box(trafo.get_matrix()).size(); - m_new_scale = m_new_size.cwiseQuotient(volume->transformed_convex_hull_bounding_box(volume->get_instance_transformation().get_matrix() * volume->get_volume_transformation().get_matrix_no_scaling_factor()).size()) * 100.0; } else if (is_local_coordinates()) { m_new_move_label_string = L("Translate"); @@ -778,8 +783,9 @@ void ObjectManipulation::update_settings_value(const Selection& selection) m_new_rotate_label_string = L("Rotate"); m_new_rotation = Vec3d::Zero(); #if ENABLE_WORLD_COORDINATE + m_new_scale_label_string = L("Scale"); m_new_size = volume->transformed_convex_hull_bounding_box(volume->get_volume_transformation().get_matrix()).size(); - m_new_scale = m_new_size.cwiseQuotient(volume->transformed_convex_hull_bounding_box(volume->get_volume_transformation().get_matrix_no_scaling_factor()).size()) * 100.0; + m_new_scale = Vec3d(100.0, 100.0, 100.0); } #else m_new_scale = volume->get_volume_scaling_factor() * 100.0; @@ -1270,7 +1276,7 @@ void ObjectManipulation::do_scale(int axis, const Vec3d &scale) const else if (is_instance_coordinates()) transformation_type.set_instance(); - if (!selection.is_single_full_instance() && !selection.is_single_volume_or_modifier()) + if (!(selection.is_single_volume_or_modifier() && is_local_coordinates())) transformation_type.set_relative(); const Vec3d scaling_factor = m_uniform_scale ? scale(axis) * Vec3d::Ones() : scale; diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 014a30322..60c069d4e 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -835,10 +835,8 @@ void Selection::translate(const Vec3d& displacement, TransformationType transfor else assert(false); } - else { - assert(transformation_type.relative()); + else transform_volume_relative(v, volume_data, transformation_type, Geometry::translation_transform(displacement), m_cache.dragging_center); - } } #if !DISABLE_INSTANCES_SYNCH @@ -935,7 +933,6 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_ transform_volume_relative(v, volume_data, transformation_type, rotation_matrix, m_cache.dragging_center); } else { - assert(transformation_type.relative()); transformation_type.set_independent(); transform_volume_relative(v, volume_data, transformation_type, rotation_matrix, m_cache.dragging_center); } @@ -1331,6 +1328,7 @@ void Selection::scale_and_translate(const Vec3d& scale, const Vec3d& translation if (transformation_type.absolute()) { // convert from absolute scaling to relative scaling BoundingBoxf3 original_box; + BoundingBoxf3 reference_box = m_box.get_bounding_box(); if (m_mode == Instance) { if (is_single_full_instance()) { if (transformation_type.world()) @@ -1348,11 +1346,14 @@ void Selection::scale_and_translate(const Vec3d& scale, const Vec3d& translation original_box = get_bounding_box(); else if (transformation_type.instance()) original_box = v.transformed_convex_hull_bounding_box(volume_data.get_volume_transform().get_matrix()); - else + else { original_box = v.bounding_box(); + reference_box = v.bounding_box().transformed(volume_data.get_volume_transform().get_scaling_factor_matrix()); + } + transformation_type.set_relative(); } - - relative_scale = original_box.size().cwiseProduct(scale).cwiseQuotient(m_box.get_bounding_box().size()); + + relative_scale = original_box.size().cwiseProduct(scale).cwiseQuotient(reference_box.size()); } if (m_mode == Instance) { @@ -1389,7 +1390,6 @@ void Selection::scale_and_translate(const Vec3d& scale, const Vec3d& translation transform_volume_relative(v, volume_data, transformation_type, Geometry::translation_transform(translation) * Geometry::scale_transform(relative_scale), m_cache.dragging_center); } else { - assert(transformation_type.relative()); transformation_type.set_independent(); transform_volume_relative(v, volume_data, transformation_type, Geometry::translation_transform(translation) * Geometry::scale_transform(relative_scale), m_cache.dragging_center); } From d51b537431fafc008b03c577d034efc9b01af30c Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 15 Dec 2022 09:53:10 +0100 Subject: [PATCH 16/18] Follow up of 9cc5659e5040299cc5abf71bf86f825328fdae9d and 0aa88e1deae128c4d0ec7b62ac0cbf2b758f79cc - Further fixes in scaling/sizing objects/volumes using sidebar panel --- src/slic3r/GUI/GUI_ObjectManipulation.cpp | 27 ++++++++++++++++++----- src/slic3r/GUI/Selection.cpp | 2 +- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index 2fa985a0a..edf4d5b07 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -726,14 +726,13 @@ void ObjectManipulation::update_settings_value(const Selection& selection) #if ENABLE_WORLD_COORDINATE m_new_move_label_string = L("Translate"); m_new_rotate_label_string = L("Rotate"); - m_new_scale_label_string = L("Scale"); m_new_position = Vec3d::Zero(); m_new_rotation = Vec3d::Zero(); m_new_scale = Vec3d(100.0, 100.0, 100.0); #else m_new_rotation = volume->get_instance_rotation() * (180.0 / M_PI); - m_new_scale = volume->get_instance_scaling_factor() * 100.0; #endif // ENABLE_WORLD_COORDINATE + m_new_scale = volume->get_instance_scaling_factor() * 100.0; m_new_size = volume->get_instance_scaling_factor().cwiseProduct(wxGetApp().model().objects[volume->object_idx()]->raw_mesh_bounding_box().size()); } @@ -1194,13 +1193,24 @@ void ObjectManipulation::change_scale_value(int axis, double value) return; Vec3d scale = m_cache.scale; - scale(axis) = value; + scale(axis) = value; +#if ENABLE_WORLD_COORDINATE + const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection(); + Vec3d ref_scale = m_cache.scale; + if (selection.is_single_full_instance()) { + scale = scale.cwiseQuotient(ref_scale); + ref_scale = Vec3d::Ones(); + } + + this->do_scale(axis, scale.cwiseQuotient(ref_scale)); +#else this->do_scale(axis, 0.01 * scale); +#endif // ENABLE_WORLD_COORDINATE m_cache.scale = scale; - m_cache.scale_rounded(axis) = DBL_MAX; - this->UpdateAndShow(true); + m_cache.scale_rounded(axis) = DBL_MAX; + this->UpdateAndShow(true); } @@ -1227,6 +1237,8 @@ void ObjectManipulation::change_size_value(int axis, double value) Vec3d ref_size = m_cache.size; #if ENABLE_WORLD_COORDINATE if (selection.is_single_volume_or_modifier()) { + if (is_local_coordinates()) + ref_size = selection.get_first_volume()->bounding_box().size(); size = size.cwiseQuotient(ref_size); ref_size = Vec3d::Ones(); #else @@ -1242,6 +1254,8 @@ void ObjectManipulation::change_size_value(int axis, double value) } else if (selection.is_single_full_instance()) { #if ENABLE_WORLD_COORDINATE + if (is_world_coordinates()) + ref_size = selection.get_unscaled_instance_bounding_box().size(); size = size.cwiseQuotient(ref_size); ref_size = Vec3d::Ones(); #else @@ -1276,7 +1290,8 @@ void ObjectManipulation::do_scale(int axis, const Vec3d &scale) const else if (is_instance_coordinates()) transformation_type.set_instance(); - if (!(selection.is_single_volume_or_modifier() && is_local_coordinates())) + if (!(selection.is_single_volume_or_modifier() && is_local_coordinates()) && + !(selection.is_single_full_instance() && is_instance_coordinates())) transformation_type.set_relative(); const Vec3d scaling_factor = m_uniform_scale ? scale(axis) * Vec3d::Ones() : scale; diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 60c069d4e..ba8378d1f 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -1352,7 +1352,7 @@ void Selection::scale_and_translate(const Vec3d& scale, const Vec3d& translation } transformation_type.set_relative(); } - + relative_scale = original_box.size().cwiseProduct(scale).cwiseQuotient(reference_box.size()); } From 3b7fa36ed7438a4f4ccf5223008ac95e1f4a7685 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 15 Dec 2022 12:48:48 +0100 Subject: [PATCH 17/18] Tech ENABLE_WORLD_COORDINATE - Fixed rotation of wipe tower --- src/slic3r/GUI/GLCanvas3D.cpp | 62 +++++++++++++++++++++++++ src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp | 2 +- 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 4175e5438..cdb893a7b 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3627,6 +3627,56 @@ void GLCanvas3D::do_move(const std::string& snapshot_type) m_dirty = true; } +#if ENABLE_WORLD_COORDINATE +// This function is a replacement for function Vec3d Geometry::extract_rotation(const Transform3d& transform) +// which is returning wrong values for the call made in the following method GLCanvas3D::do_rotate() when rotating the wipe tower +Vec3d extract_rotation(const Transform3d& transform) +{ + // use only the non-translational part of the transform + Eigen::Matrix rotation_matrix = transform.matrix().block(0, 0, 3, 3); + // remove scale + rotation_matrix.col(0).normalize(); + rotation_matrix.col(1).normalize(); + rotation_matrix.col(2).normalize(); + + // reference: http://eecs.qmul.ac.uk/~gslabaugh/publications/euler.pdf + Vec3d angles1 = Vec3d::Zero(); + Vec3d angles2 = Vec3d::Zero(); + if (std::abs(std::abs(rotation_matrix(2, 0)) - 1.0) < 1e-5) { + angles1.z() = 0.0; + if (rotation_matrix(2, 0) < 0.0) { // == -1.0 + angles1.y() = 0.5 * double(PI); + angles1.x() = angles1.z() + ::atan2(rotation_matrix(0, 1), rotation_matrix(0, 2)); + } + else { // == 1.0 + angles1.y() = -0.5 * double(PI); + angles1.x() = -angles1.y() + ::atan2(-rotation_matrix(0, 1), -rotation_matrix(0, 2)); + } + angles2 = angles1; + } + else { + angles1.y() = -::asin(rotation_matrix(2, 0)); + const double inv_cos1 = 1.0 / ::cos(angles1.y()); + angles1.x() = ::atan2(rotation_matrix(2, 1) * inv_cos1, rotation_matrix(2, 2) * inv_cos1); + angles1.z() = ::atan2(rotation_matrix(1, 0) * inv_cos1, rotation_matrix(0, 0) * inv_cos1); + + angles2.y() = double(PI) - angles1.y(); + const double inv_cos2 = 1.0 / ::cos(angles2.y()); + angles2.x() = ::atan2(rotation_matrix(2, 1) * inv_cos2, rotation_matrix(2, 2) * inv_cos2); + angles2.z() = ::atan2(rotation_matrix(1, 0) * inv_cos2, rotation_matrix(0, 0) * inv_cos2); + } + + // The following euristic is the best found up to now (in the sense that it works fine with the greatest number of edge use-cases) + // but there are other use-cases were it does not + // We need to improve it + const double min_1 = angles1.cwiseAbs().minCoeff(); + const double min_2 = angles2.cwiseAbs().minCoeff(); + const bool use_1 = (min_1 < min_2) || (is_approx(min_1, min_2) && (angles1.norm() <= angles2.norm())); + + return use_1 ? angles1 : angles2; +} +#endif // ENABLE_WORLD_COORDINATE + void GLCanvas3D::do_rotate(const std::string& snapshot_type) { if (m_model == nullptr) @@ -3659,7 +3709,11 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type) for (const GLVolume* v : m_volumes.volumes) { if (v->is_wipe_tower) { const Vec3d offset = v->get_volume_offset(); +#if ENABLE_WORLD_COORDINATE + post_event(Vec3dEvent(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3d(offset.x(), offset.y(), extract_rotation(v->get_volume_transformation().get_matrix()).z()))); +#else post_event(Vec3dEvent(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3d(offset.x(), offset.y(), v->get_volume_rotation().z()))); +#endif // ENABLE_WORLD_COORDINATE } const int object_idx = v->object_idx(); if (object_idx < 0 || (int)m_model->objects.size() <= object_idx) @@ -5109,9 +5163,17 @@ void GLCanvas3D::_refresh_if_shown_on_screen() const Size& cnv_size = get_canvas_size(); _resize((unsigned int)cnv_size.get_width(), (unsigned int)cnv_size.get_height()); + // When the application starts the following call to render() triggers the opengl initialization. + // We need to ask for an extra call to reload_scene() to force the generation of the model for wipe tower + // for printers using it, which is skipped by all the previous calls to reload_scene() because m_initialized == false + const bool requires_reload_scene = !m_initialized; + // Because of performance problems on macOS, where PaintEvents are not delivered // frequently enough, we call render() here directly when we can. render(); + assert(m_initialized); + if (requires_reload_scene) + reload_scene(true); } } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp index 6e7cf9c83..0be1d1655 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp @@ -614,7 +614,7 @@ bool GLGizmoRotate3D::on_mouse(const wxMouseEvent &mouse_event) #if ENABLE_WORLD_COORDINATE TransformationType transformation_type; if (m_parent.get_selection().is_wipe_tower()) - transformation_type = TransformationType::Instance_Relative_Joint; + transformation_type = TransformationType::World_Relative_Joint; else { switch (wxGetApp().obj_manipul()->get_coordinates_type()) { From 625baaefeee0e58cb37a0a68375b03b39c2abf8a Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Thu, 15 Dec 2022 16:02:33 +0100 Subject: [PATCH 18/18] Follow-up to previous commit (wipe tower rotation) --- src/slic3r/GUI/GLCanvas3D.cpp | 54 ++--------------------------------- 1 file changed, 3 insertions(+), 51 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index cdb893a7b..de912a134 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3627,56 +3627,6 @@ void GLCanvas3D::do_move(const std::string& snapshot_type) m_dirty = true; } -#if ENABLE_WORLD_COORDINATE -// This function is a replacement for function Vec3d Geometry::extract_rotation(const Transform3d& transform) -// which is returning wrong values for the call made in the following method GLCanvas3D::do_rotate() when rotating the wipe tower -Vec3d extract_rotation(const Transform3d& transform) -{ - // use only the non-translational part of the transform - Eigen::Matrix rotation_matrix = transform.matrix().block(0, 0, 3, 3); - // remove scale - rotation_matrix.col(0).normalize(); - rotation_matrix.col(1).normalize(); - rotation_matrix.col(2).normalize(); - - // reference: http://eecs.qmul.ac.uk/~gslabaugh/publications/euler.pdf - Vec3d angles1 = Vec3d::Zero(); - Vec3d angles2 = Vec3d::Zero(); - if (std::abs(std::abs(rotation_matrix(2, 0)) - 1.0) < 1e-5) { - angles1.z() = 0.0; - if (rotation_matrix(2, 0) < 0.0) { // == -1.0 - angles1.y() = 0.5 * double(PI); - angles1.x() = angles1.z() + ::atan2(rotation_matrix(0, 1), rotation_matrix(0, 2)); - } - else { // == 1.0 - angles1.y() = -0.5 * double(PI); - angles1.x() = -angles1.y() + ::atan2(-rotation_matrix(0, 1), -rotation_matrix(0, 2)); - } - angles2 = angles1; - } - else { - angles1.y() = -::asin(rotation_matrix(2, 0)); - const double inv_cos1 = 1.0 / ::cos(angles1.y()); - angles1.x() = ::atan2(rotation_matrix(2, 1) * inv_cos1, rotation_matrix(2, 2) * inv_cos1); - angles1.z() = ::atan2(rotation_matrix(1, 0) * inv_cos1, rotation_matrix(0, 0) * inv_cos1); - - angles2.y() = double(PI) - angles1.y(); - const double inv_cos2 = 1.0 / ::cos(angles2.y()); - angles2.x() = ::atan2(rotation_matrix(2, 1) * inv_cos2, rotation_matrix(2, 2) * inv_cos2); - angles2.z() = ::atan2(rotation_matrix(1, 0) * inv_cos2, rotation_matrix(0, 0) * inv_cos2); - } - - // The following euristic is the best found up to now (in the sense that it works fine with the greatest number of edge use-cases) - // but there are other use-cases were it does not - // We need to improve it - const double min_1 = angles1.cwiseAbs().minCoeff(); - const double min_2 = angles2.cwiseAbs().minCoeff(); - const bool use_1 = (min_1 < min_2) || (is_approx(min_1, min_2) && (angles1.norm() <= angles2.norm())); - - return use_1 ? angles1 : angles2; -} -#endif // ENABLE_WORLD_COORDINATE - void GLCanvas3D::do_rotate(const std::string& snapshot_type) { if (m_model == nullptr) @@ -3710,7 +3660,9 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type) if (v->is_wipe_tower) { const Vec3d offset = v->get_volume_offset(); #if ENABLE_WORLD_COORDINATE - post_event(Vec3dEvent(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3d(offset.x(), offset.y(), extract_rotation(v->get_volume_transformation().get_matrix()).z()))); + Vec3d rot_unit_x = v->get_volume_transformation().get_matrix().linear() * Vec3d::UnitX(); + double z_rot = std::atan2(rot_unit_x.y(), rot_unit_x.x()); + post_event(Vec3dEvent(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3d(offset.x(), offset.y(), z_rot))); #else post_event(Vec3dEvent(EVT_GLCANVAS_WIPETOWER_ROTATED, Vec3d(offset.x(), offset.y(), v->get_volume_rotation().z()))); #endif // ENABLE_WORLD_COORDINATE