FIX:add "absolute rotation" in rotate gizmo
jira: STUDIO-8726 Change-Id: I23deb4ab11cf24ca4f0f0c5a35a74268c34f60f6 (cherry picked from commit d26b8f9fcadf8f7709a302991e43be711560e84e)
This commit is contained in:
parent
0e84f6acc7
commit
496d69f9d1
|
@ -447,6 +447,16 @@ const Vec3d &Transformation::get_rotation() const
|
|||
return m_temp_rotation;
|
||||
}
|
||||
|
||||
const Vec3d &Transformation::get_rotation_by_quaternion() const
|
||||
{
|
||||
Matrix3d rotation_matrix = m_matrix.matrix().block(0, 0, 3, 3);
|
||||
Eigen::Quaterniond quaternion(rotation_matrix);
|
||||
quaternion.normalize();
|
||||
m_temp_rotation = quaternion.matrix().eulerAngles(2, 1, 0);
|
||||
std::swap(m_temp_rotation(0), m_temp_rotation(2));
|
||||
return m_temp_rotation;
|
||||
}
|
||||
|
||||
Transform3d Transformation::get_rotation_matrix() const { return extract_rotation_matrix(m_matrix); }
|
||||
|
||||
void Transformation::set_rotation(const Vec3d &rotation)
|
||||
|
|
|
@ -395,6 +395,7 @@ public:
|
|||
void set_offset(Axis axis, double offset) { m_matrix.translation()[axis] = offset; }
|
||||
|
||||
const Vec3d &get_rotation() const;
|
||||
const Vec3d &get_rotation_by_quaternion() const;
|
||||
double get_rotation(Axis axis) const { return get_rotation()[axis]; }
|
||||
|
||||
Transform3d get_rotation_matrix() const;
|
||||
|
|
|
@ -91,12 +91,19 @@ void GizmoObjectManipulation::update_ui_from_settings()
|
|||
update_buffered_value();
|
||||
}
|
||||
}
|
||||
void delete_negative_sign(Vec3d& value) {
|
||||
for (size_t i = 0; i < value.size(); i++) {
|
||||
if (abs(value[i]) < 0.001)
|
||||
value[i] = 0.f;
|
||||
}
|
||||
}
|
||||
|
||||
void GizmoObjectManipulation::update_settings_value(const Selection& selection)
|
||||
void GizmoObjectManipulation::update_settings_value(const Selection &selection)
|
||||
{
|
||||
m_new_move_label_string = L("Position");
|
||||
m_new_rotate_label_string = L("Rotate (relative)");
|
||||
m_new_rotation = Vec3d::Zero();
|
||||
m_new_absolute_rotation = Vec3d::Zero();
|
||||
m_new_scale_label_string = L("Scale ratios");
|
||||
|
||||
ObjectList* obj_list = wxGetApp().obj_list();
|
||||
|
@ -104,7 +111,9 @@ void GizmoObjectManipulation::update_settings_value(const Selection& selection)
|
|||
// all volumes in the selection belongs to the same instance, any of them contains the needed instance data, so we take the first one
|
||||
const GLVolume* volume = selection.get_volume(*selection.get_volume_idxs().begin());
|
||||
m_new_position = volume->get_instance_offset();
|
||||
|
||||
auto rotation = volume->get_instance_transformation().get_rotation_by_quaternion();
|
||||
m_new_absolute_rotation = rotation * (180. / M_PI);
|
||||
delete_negative_sign(m_new_absolute_rotation);
|
||||
if (is_world_coordinates()) {//for move and rotate
|
||||
m_new_size = selection.get_bounding_box_in_current_reference_system().first.size();
|
||||
m_unscale_size = selection.get_unscaled_instance_bounding_box().size();
|
||||
|
@ -132,6 +141,9 @@ void GizmoObjectManipulation::update_settings_value(const Selection& selection)
|
|||
m_new_title_string = L("Object Operations");
|
||||
} else if (selection.is_single_volume_or_modifier()) {
|
||||
const GLVolume *volume = selection.get_first_volume();
|
||||
auto rotation = volume->get_volume_transformation().get_rotation_by_quaternion();
|
||||
m_new_absolute_rotation = rotation * (180. / M_PI);
|
||||
delete_negative_sign(m_new_absolute_rotation);
|
||||
if (is_world_coordinates()) {//for move and rotate
|
||||
const Geometry::Transformation trafo(volume->world_matrix());
|
||||
const Vec3d &offset = trafo.get_offset();
|
||||
|
@ -180,7 +192,7 @@ void GizmoObjectManipulation::update_buffered_value()
|
|||
m_buffered_position = this->m_new_position;
|
||||
|
||||
m_buffered_rotation = this->m_new_rotation;
|
||||
|
||||
m_buffered_absolute_rotation = this->m_new_absolute_rotation;
|
||||
m_buffered_scale = this->m_new_scale;
|
||||
|
||||
if (this->m_imperial_units)
|
||||
|
@ -206,6 +218,7 @@ void GizmoObjectManipulation::update_if_dirty()
|
|||
};
|
||||
update_label(m_cache.move_label_string, m_new_move_label_string);
|
||||
update_label(m_cache.rotate_label_string, m_new_rotate_label_string);
|
||||
update_label(m_cache.rotate_label_string, m_new_rotate_label_string);
|
||||
update_label(m_cache.scale_label_string, m_new_scale_label_string);
|
||||
|
||||
enum ManipulationEditorKey
|
||||
|
@ -234,6 +247,7 @@ void GizmoObjectManipulation::update_if_dirty()
|
|||
update(m_cache.scale, m_cache.scale_rounded, m_new_scale);
|
||||
update(m_cache.size, m_cache.size_rounded, m_new_size);
|
||||
update(m_cache.rotation, m_cache.rotation_rounded, m_new_rotation);
|
||||
update(m_cache.absolute_rotation, m_cache.absolute_rotation_rounded, m_new_absolute_rotation);
|
||||
}
|
||||
|
||||
update_reset_buttons_visibility();
|
||||
|
@ -274,6 +288,7 @@ void GizmoObjectManipulation::reset_settings_value()
|
|||
{
|
||||
m_new_position = Vec3d::Zero();
|
||||
m_new_rotation = Vec3d::Zero();
|
||||
m_new_absolute_rotation = Vec3d::Zero();
|
||||
m_new_scale = Vec3d::Ones() * 100.;
|
||||
m_new_size = Vec3d::Zero();
|
||||
m_new_enabled = false;
|
||||
|
@ -345,6 +360,34 @@ void GizmoObjectManipulation::change_rotation_value(int axis, double value)
|
|||
this->UpdateAndShow(true);
|
||||
}
|
||||
|
||||
void GizmoObjectManipulation::change_absolute_rotation_value(int axis, double value) {
|
||||
if (std::abs(m_cache.absolute_rotation_rounded(axis) - value) < EPSILON)
|
||||
return;
|
||||
|
||||
Vec3d absolute_rotation = m_cache.absolute_rotation;
|
||||
absolute_rotation(axis) = value;
|
||||
|
||||
Selection &selection = m_glcanvas.get_selection();
|
||||
TransformationType transformation_type;
|
||||
transformation_type.set_relative();
|
||||
if (selection.is_single_full_instance())
|
||||
transformation_type.set_independent();
|
||||
if (is_local_coordinates())
|
||||
transformation_type.set_local();
|
||||
if (is_instance_coordinates())
|
||||
transformation_type.set_instance();
|
||||
|
||||
selection.setup_cache();
|
||||
auto diff_rotation = transformation_type.absolute() ? absolute_rotation : absolute_rotation - m_cache.absolute_rotation;
|
||||
selection.rotate((M_PI / 180.0) * diff_rotation, transformation_type);
|
||||
wxGetApp().plater()->take_snapshot("set absolute orientation", UndoRedo::SnapshotType::GizmoAction);
|
||||
m_glcanvas.do_rotate("");
|
||||
|
||||
m_cache.absolute_rotation = absolute_rotation;
|
||||
m_cache.absolute_rotation_rounded(axis) = DBL_MAX;
|
||||
this->UpdateAndShow(true);
|
||||
}
|
||||
|
||||
void GizmoObjectManipulation::change_scale_value(int axis, double value)
|
||||
{
|
||||
if (value <= 0.0)
|
||||
|
@ -441,6 +484,8 @@ void GizmoObjectManipulation::on_change(const std::string &opt_key, int axis, do
|
|||
change_position_value(axis, new_value);
|
||||
else if (opt_key == "rotation")
|
||||
change_rotation_value(axis, new_value);
|
||||
else if (opt_key == "absolute_rotation")
|
||||
change_absolute_rotation_value(axis, new_value);
|
||||
else if (opt_key == "scale")
|
||||
change_scale_value(axis, new_value);
|
||||
else if (opt_key == "size")
|
||||
|
@ -578,9 +623,10 @@ void GizmoObjectManipulation::set_coordinates_type(ECoordinatesType type)
|
|||
|
||||
}
|
||||
|
||||
static const char* label_values[2][3] = {
|
||||
static const char* label_values[3][3] = {
|
||||
{ "##position_x", "##position_y", "##position_z"},
|
||||
{ "##rotation_x", "##rotation_y", "##rotation_z"}
|
||||
{ "##rotation_x", "##rotation_y", "##rotation_z"},
|
||||
{ "##absolute_rotation_x", "##absolute_rotation_y", "##absolute_rotation_z"}
|
||||
};
|
||||
|
||||
static const char* label_scale_values[2][3] = {
|
||||
|
@ -800,7 +846,6 @@ void GizmoObjectManipulation::set_init_rotation(const Geometry::Transformation &
|
|||
Vec3d display_position = m_buffered_position;
|
||||
|
||||
// Rotation
|
||||
Vec3d rotation = this->m_buffered_rotation;
|
||||
float unit_size = imgui_wrapper->calc_text_size(MAX_SIZE).x + space_size;
|
||||
int index = 1;
|
||||
int index_unit = 1;
|
||||
|
@ -949,7 +994,7 @@ void GizmoObjectManipulation::do_render_rotate_window(ImGuiWrapper *imgui_wrappe
|
|||
Vec3d display_position = m_buffered_position;
|
||||
// Rotation
|
||||
Vec3d rotation = this->m_buffered_rotation;
|
||||
|
||||
Vec3d absolute_rotation = this->m_buffered_absolute_rotation;
|
||||
float unit_size = imgui_wrapper->calc_text_size(MAX_SIZE).x + space_size;
|
||||
int index = 1;
|
||||
int index_unit = 1;
|
||||
|
@ -967,33 +1012,41 @@ void GizmoObjectManipulation::do_render_rotate_window(ImGuiWrapper *imgui_wrappe
|
|||
ImGui::SameLine(caption_max + (++index_unit) * unit_size + (++index) * space_size);
|
||||
ImGui::PushItemWidth(unit_size);
|
||||
ImGui::TextAlignCenter("Z");
|
||||
if (m_show_reset_0_rotation) {
|
||||
ImGui::SameLine(caption_max + 3 * unit_size + 4 * space_size + end_text_size);
|
||||
if (reset_zero_button(imgui_wrapper, caption_max, unit_size, space_size, end_text_size)) { reset_rotation_value(false); }
|
||||
if (ImGui::IsItemHovered()) {
|
||||
float tooltip_size = imgui_wrapper->calc_text_size(_L("Reset current rotation to real zeros.")).x + 3 * space_size;
|
||||
imgui_wrapper->tooltip(_L("Reset current rotation to real zeros."), tooltip_size);
|
||||
}
|
||||
}
|
||||
|
||||
index = 1;
|
||||
index_unit = 1;
|
||||
|
||||
// ImGui::PushItemWidth(unit_size * 2);
|
||||
bool is_relative_input = false;
|
||||
ImGui::AlignTextToFramePadding();
|
||||
imgui_wrapper->text(_L("Rotate (relative)"));
|
||||
ImGui::SameLine(caption_max + index * space_size);
|
||||
ImGui::PushItemWidth(unit_size);
|
||||
ImGui::BBLInputDouble(label_values[1][0], &rotation[0], 0.0f, 0.0f, "%.2f");
|
||||
if (ImGui::BBLInputDouble(label_values[1][0], &rotation[0], 0.0f, 0.0f, "%.2f")) {
|
||||
is_relative_input = true;
|
||||
}
|
||||
ImGui::SameLine(caption_max + unit_size + (++index) * space_size);
|
||||
ImGui::PushItemWidth(unit_size);
|
||||
ImGui::BBLInputDouble(label_values[1][1], &rotation[1], 0.0f, 0.0f, "%.2f");
|
||||
if (ImGui::BBLInputDouble(label_values[1][1], &rotation[1], 0.0f, 0.0f, "%.2f")) {
|
||||
is_relative_input = true;
|
||||
}
|
||||
ImGui::SameLine(caption_max + (++index_unit) * unit_size + (++index) * space_size);
|
||||
ImGui::PushItemWidth(unit_size);
|
||||
ImGui::BBLInputDouble(label_values[1][2], &rotation[2], 0.0f, 0.0f, "%.2f");
|
||||
if (ImGui::BBLInputDouble(label_values[1][2], &rotation[2], 0.0f, 0.0f, "%.2f")) {
|
||||
is_relative_input = true;
|
||||
}
|
||||
ImGui::SameLine(caption_max + (++index_unit) * unit_size + (++index) * space_size);
|
||||
imgui_wrapper->text(_L("°"));
|
||||
m_buffered_rotation = rotation;
|
||||
update(current_active_id, "rotation", this->m_new_rotation, m_buffered_rotation);
|
||||
if (is_relative_input) {
|
||||
m_last_rotate_type = RotateType::Relative;
|
||||
}
|
||||
if (m_last_rotate_type == RotateType::Relative) {
|
||||
bool is_valid = update(current_active_id, "rotation", this->m_new_rotation, m_buffered_rotation) >= 0;
|
||||
if (is_valid) {
|
||||
m_last_rotate_type = RotateType::None;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_show_clear_rotation) {
|
||||
ImGui::SameLine(caption_max + 3 * unit_size + 4 * space_size + end_text_size);
|
||||
|
@ -1008,7 +1061,6 @@ void GizmoObjectManipulation::do_render_rotate_window(ImGuiWrapper *imgui_wrappe
|
|||
ImGui::SameLine(caption_max + 3 * unit_size + 5 * space_size + end_text_size);
|
||||
ImGui::InvisibleButton("", ImVec2(ImGui::GetFontSize(), ImGui::GetFontSize()));
|
||||
}
|
||||
|
||||
// send focus to m_glcanvas
|
||||
bool focued_on_text = false;
|
||||
for (int j = 0; j < 3; j++) {
|
||||
|
@ -1019,7 +1071,61 @@ void GizmoObjectManipulation::do_render_rotate_window(ImGuiWrapper *imgui_wrappe
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (!focued_on_text) m_glcanvas.handle_sidebar_focus_event("", false);
|
||||
|
||||
index = 1;
|
||||
index_unit = 1;
|
||||
ImGui::AlignTextToFramePadding();
|
||||
imgui_wrapper->text(_L("Rotate (absolute)"));
|
||||
ImGui::SameLine(caption_max + index * space_size);
|
||||
ImGui::PushItemWidth(unit_size);
|
||||
bool is_absolute_input = false;
|
||||
if (ImGui::BBLInputDouble(label_values[2][0], &absolute_rotation[0], 0.0f, 0.0f, "%.2f")) {
|
||||
is_absolute_input = true;
|
||||
}
|
||||
ImGui::SameLine(caption_max + unit_size + (++index) * space_size);
|
||||
ImGui::PushItemWidth(unit_size);
|
||||
if (ImGui::BBLInputDouble(label_values[2][1], &absolute_rotation[1], 0.0f, 0.0f, "%.2f")) {
|
||||
is_absolute_input = true;
|
||||
}
|
||||
ImGui::SameLine(caption_max + (++index_unit) * unit_size + (++index) * space_size);
|
||||
ImGui::PushItemWidth(unit_size);
|
||||
if (ImGui::BBLInputDouble(label_values[2][2], &absolute_rotation[2], 0.0f, 0.0f, "%.2f")) {
|
||||
is_absolute_input = true;
|
||||
}
|
||||
ImGui::SameLine(caption_max + (++index_unit) * unit_size + (++index) * space_size);
|
||||
imgui_wrapper->text(_L("°"));
|
||||
m_buffered_absolute_rotation = absolute_rotation;
|
||||
if (is_absolute_input) {
|
||||
m_last_rotate_type = RotateType::Absolute;
|
||||
}
|
||||
if (m_last_rotate_type == RotateType::Absolute) {
|
||||
bool is_valid = update(current_active_id, "absolute_rotation", this->m_new_absolute_rotation, m_buffered_absolute_rotation) >= 0;
|
||||
if (is_valid) {
|
||||
m_last_rotate_type = RotateType::None;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_show_reset_0_rotation) {
|
||||
ImGui::SameLine(caption_max + 3 * unit_size + 4 * space_size + end_text_size);
|
||||
if (reset_zero_button(imgui_wrapper, caption_max, unit_size, space_size, end_text_size)) { reset_rotation_value(false); }
|
||||
if (ImGui::IsItemHovered()) {
|
||||
float tooltip_size = imgui_wrapper->calc_text_size(_L("Reset current rotation to real zeros.")).x + 3 * space_size;
|
||||
imgui_wrapper->tooltip(_L("Reset current rotation to real zeros."), tooltip_size);
|
||||
}
|
||||
}
|
||||
// send focus to m_glcanvas
|
||||
bool absolute_focued_on_text = false;
|
||||
for (int j = 0; j < 3; j++) {
|
||||
unsigned int id = ImGui::GetID(label_values[2][j]);
|
||||
if (current_active_id == id) {
|
||||
m_glcanvas.handle_sidebar_focus_event(label_values[2][j] + 2, true);
|
||||
absolute_focued_on_text = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!focued_on_text && !absolute_focued_on_text)
|
||||
m_glcanvas.handle_sidebar_focus_event("", false);
|
||||
|
||||
float get_cur_y = ImGui::GetContentRegionMax().y + ImGui::GetFrameHeight() + y;
|
||||
float tip_caption_max = 0.f;
|
||||
float total_text_max = 0.f;
|
||||
|
|
|
@ -27,6 +27,8 @@ public:
|
|||
Vec3d position_rounded;
|
||||
Vec3d rotation;
|
||||
Vec3d rotation_rounded;
|
||||
Vec3d absolute_rotation;
|
||||
Vec3d absolute_rotation_rounded;
|
||||
Vec3d scale;
|
||||
Vec3d scale_rounded;
|
||||
Vec3d size;
|
||||
|
@ -72,11 +74,13 @@ public:
|
|||
std::string m_new_unit_string;
|
||||
Vec3d m_new_position;
|
||||
Vec3d m_new_rotation;
|
||||
Vec3d m_new_absolute_rotation;
|
||||
Vec3d m_new_scale;
|
||||
Vec3d m_new_size;
|
||||
Vec3d m_unscale_size;
|
||||
Vec3d m_buffered_position;
|
||||
Vec3d m_buffered_rotation;
|
||||
Vec3d m_buffered_absolute_rotation;
|
||||
Vec3d m_buffered_scale;
|
||||
Vec3d m_buffered_size;
|
||||
Vec3d cs_center;
|
||||
|
@ -89,6 +93,9 @@ public:
|
|||
bool m_show_clear_rotation { false };
|
||||
bool m_show_clear_scale { false };
|
||||
bool m_show_drop_to_bed { false };
|
||||
enum class RotateType { None, Relative, Absolute
|
||||
};
|
||||
RotateType m_last_rotate_type{RotateType::None}; // 0:no input 1:relative 2:absolute
|
||||
|
||||
protected:
|
||||
float last_move_input_window_width = 0.0f;
|
||||
|
@ -150,6 +157,7 @@ private:
|
|||
// change values
|
||||
void change_position_value(int axis, double value);
|
||||
void change_rotation_value(int axis, double value);
|
||||
void change_absolute_rotation_value(int axis, double value);
|
||||
void change_scale_value(int axis, double value);
|
||||
void change_size_value(int axis, double value);
|
||||
void do_scale(int axis, const Vec3d &scale) const;
|
||||
|
|
|
@ -2048,6 +2048,8 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field, bool unif
|
|||
render_sidebar_position_hints(sidebar_field);
|
||||
else if (boost::starts_with(sidebar_field, "rotation"))
|
||||
render_sidebar_rotation_hints(sidebar_field);
|
||||
else if (boost::starts_with(sidebar_field, "absolute_rotation"))
|
||||
render_sidebar_rotation_hints(sidebar_field);
|
||||
else if (boost::starts_with(sidebar_field, "scale") || boost::starts_with(sidebar_field, "size"))
|
||||
//BBS: GUI refactor: add uniform_scale from gizmo
|
||||
render_sidebar_scale_hints(sidebar_field, uniform_scale);
|
||||
|
|
Loading…
Reference in New Issue