diff --git a/src/libslic3r/Geometry.cpp b/src/libslic3r/Geometry.cpp index 9b80149176..cb2918cd9d 100644 --- a/src/libslic3r/Geometry.cpp +++ b/src/libslic3r/Geometry.cpp @@ -1211,7 +1211,7 @@ Transform3d assemble_transform(const Vec3d& translation, const Vec3d& rotation, Vec3d extract_euler_angles(const Eigen::Matrix& rotation_matrix) { - // reference: http://www.gregslabaugh.net/publications/euler.pdf + // 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) diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index d8cdb515b3..fc5bc1c7ba 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -82,6 +82,8 @@ #define ENABLE_MODIFIERS_ALWAYS_TRANSPARENT (1 && ENABLE_2_4_0_ALPHA4) // Enable editing volumes transformation in world coordinates and instances in local coordinates #define ENABLE_WORLD_COORDINATE (1 && ENABLE_2_4_0_ALPHA4) +// Enable showing world coordinates of volumes' offset relative to the instance containing them +#define ENABLE_WORLD_COORDINATE_VOLUMES_LOCAL_OFFSET (1 && ENABLE_WORLD_COORDINATE) #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index cf3d962453..be036714d4 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -620,13 +620,17 @@ void ObjectManipulation::update_settings_value(const Selection& selection) if (m_world_coordinates) { const Geometry::Transformation trafo(volume->world_matrix()); +#if ENABLE_WORLD_COORDINATE_VOLUMES_LOCAL_OFFSET + const Vec3d offset = trafo.get_offset() - volume->get_instance_offset(); +#else const Vec3d& offset = trafo.get_offset(); const Vec3d& rotation = trafo.get_rotation(); +#endif // ENABLE_WORLD_COORDINATE_VOLUMES_LOCAL_OFFSET const Vec3d& scaling_factor = trafo.get_scaling_factor(); // const Vec3d& mirror = trafo.get_mirror(); m_new_position = offset; - m_new_rotation = rotation * (180.0 / M_PI); + m_new_rotation = Vec3d::Zero(); m_new_scale = scaling_factor * 100.0; m_new_size = volume->bounding_box().size().cwiseProduct(scaling_factor); } @@ -774,7 +778,7 @@ void ObjectManipulation::update_reset_buttons_visibility() show_rotation = !rotation.isApprox(Vec3d::Zero()); show_scale = !scale.isApprox(Vec3d::Ones()); #if ENABLE_WORLD_COORDINATE - show_drop_to_bed = min_z < SINKING_Z_THRESHOLD; + show_drop_to_bed = std::abs(min_z) > EPSILON; #else show_drop_to_bed = std::abs(min_z) > SINKING_Z_THRESHOLD; #endif // ENABLE_WORLD_COORDINATE @@ -920,6 +924,16 @@ void ObjectManipulation::change_rotation_value(int axis, double value) Selection& selection = canvas->get_selection(); TransformationType transformation_type(TransformationType::World_Relative_Joint); +#if ENABLE_WORLD_COORDINATE + if (selection.is_single_full_instance()) + transformation_type.set_independent(); + + if (!m_world_coordinates) { + //FIXME Selection::rotate() does not process absolute rotations correctly: It does not recognize the axis index, which was changed. + // transformation_type.set_absolute(); + transformation_type.set_local(); + } +#else if (selection.is_single_full_instance() || selection.requires_local_axes()) transformation_type.set_independent(); if (selection.is_single_full_instance() && ! m_world_coordinates) { @@ -927,6 +941,7 @@ void ObjectManipulation::change_rotation_value(int axis, double value) // transformation_type.set_absolute(); transformation_type.set_local(); } +#endif // ENABLE_WORLD_COORDINATE selection.start_dragging(); selection.rotate( diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index d86ea5c137..dcdd062f67 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -827,13 +827,25 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_ if (is_single_full_instance()) rotate_instance(v, i); else if (is_single_volume() || is_single_modifier()) { - if (transformation_type.independent()) - v.set_volume_rotation(v.get_volume_rotation() + rotation); +#if ENABLE_WORLD_COORDINATE + if (transformation_type.local()) + v.set_volume_rotation(m_cache.volumes_data[i].get_volume_rotation() + rotation); else { - const Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), rotation); - const Vec3d new_rotation = Geometry::extract_euler_angles(m * m_cache.volumes_data[i].get_volume_rotation_matrix()); - v.set_volume_rotation(new_rotation); + Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), rotation); + m = m * m_cache.volumes_data[i].get_instance_rotation_matrix(); + m = m * m_cache.volumes_data[i].get_volume_rotation_matrix(); + m = m_cache.volumes_data[i].get_instance_rotation_matrix().inverse() * m; + v.set_volume_rotation(Geometry::extract_euler_angles(m)); } +#else + if (transformation_type.independent()) + v.set_volume_rotation(v.get_volume_rotation() + rotation); + else { + const Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), rotation); + const Vec3d new_rotation = Geometry::extract_euler_angles(m * m_cache.volumes_data[i].get_volume_rotation_matrix()); + v.set_volume_rotation(new_rotation); + } +#endif // ENABLE_WORLD_COORDINATE } else { if (m_mode == Instance)