mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-07-31 04:01:59 +08:00
Fixed Rotate Gizmo orientation for mirrored objects + ensure that instances and volumes always rotate as rigid body
This commit is contained in:
parent
4ca48b2ab7
commit
dcec7a8ad4
@ -238,13 +238,7 @@ void GLGizmoRotate::init_data_from_selection(const Selection& selection)
|
||||
selection.get_bounding_box_in_reference_system(ECoordinatesType::Local) : selection.get_bounding_box_in_current_reference_system();
|
||||
m_bounding_box = box;
|
||||
m_center = box_trafo.translation();
|
||||
m_orient_matrix = Geometry::translation_transform(m_center);
|
||||
if (!wxGetApp().obj_manipul()->is_world_coordinates() || m_force_local_coordinate) {
|
||||
const GLVolume& v = *selection.get_first_volume();
|
||||
m_orient_matrix = m_orient_matrix * v.get_instance_transformation().get_rotation_matrix();
|
||||
if (selection.is_single_volume_or_modifier() && wxGetApp().obj_manipul()->is_local_coordinates() || m_force_local_coordinate)
|
||||
m_orient_matrix = m_orient_matrix * v.get_volume_transformation().get_rotation_matrix();
|
||||
}
|
||||
m_orient_matrix = box_trafo;
|
||||
|
||||
m_radius = Offset + m_bounding_box.radius();
|
||||
m_snap_coarse_in_radius = m_radius / 3.0f;
|
||||
|
@ -918,7 +918,7 @@ void Selection::translate(const Vec3d& displacement, TransformationType transfor
|
||||
v.set_instance_offset(inst_trafo.get_offset() + inst_trafo.get_rotation_matrix() * displacement);
|
||||
}
|
||||
else
|
||||
transform_instance_relative_world(v, volume_data, transformation_type, Geometry::translation_transform(displacement), m_cache.dragging_center);
|
||||
transform_instance_relative(v, volume_data, transformation_type, Geometry::translation_transform(displacement), m_cache.dragging_center);
|
||||
}
|
||||
else {
|
||||
if (transformation_type.local() && transformation_type.absolute()) {
|
||||
@ -998,24 +998,24 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_
|
||||
|
||||
assert(transformation_type.relative() || (transformation_type.absolute() && transformation_type.local()));
|
||||
|
||||
Transform3d rotation_matrix = Geometry::rotation_transform(rotation);
|
||||
|
||||
for (unsigned int i : m_list) {
|
||||
Transform3d rotation_matrix = Geometry::rotation_transform(rotation);
|
||||
GLVolume& v = *(*m_volumes)[i];
|
||||
const VolumeCache& volume_data = m_cache.volumes_data[i];
|
||||
const Geometry::Transformation& inst_trafo = volume_data.get_instance_transform();
|
||||
if (m_mode == Instance && !is_wipe_tower()) {
|
||||
assert(is_from_fully_selected_instance(i));
|
||||
if (transformation_type.instance()) {
|
||||
const Vec3d world_inst_pivot = m_cache.dragging_center - inst_trafo.get_offset();
|
||||
const Vec3d local_inst_pivot = inst_trafo.get_matrix_no_offset().inverse() * world_inst_pivot;
|
||||
Matrix3d inst_rotation, inst_scale;
|
||||
inst_trafo.get_matrix().computeRotationScaling(&inst_rotation, &inst_scale);
|
||||
const Transform3d trafo = inst_trafo.get_rotation_matrix() * rotation_matrix;
|
||||
v.set_instance_transformation(Geometry::translation_transform(world_inst_pivot) * inst_trafo.get_offset_matrix() * trafo * Transform3d(inst_scale) * Geometry::translation_transform(-local_inst_pivot));
|
||||
// ensure that the instance rotates as a rigid body
|
||||
const Transform3d inst_matrix_no_offset = inst_trafo.get_matrix_no_offset();
|
||||
const Transform3d inst_rotation_matrix = inst_trafo.get_rotation_matrix();
|
||||
rotation_matrix = inst_matrix_no_offset.inverse() * inst_rotation_matrix * rotation_matrix * inst_rotation_matrix.inverse() * inst_matrix_no_offset;
|
||||
|
||||
// rotate around selection center
|
||||
const Vec3d inst_pivot = inst_trafo.get_matrix_no_offset().inverse() * (m_cache.dragging_center - inst_trafo.get_offset());
|
||||
rotation_matrix = Geometry::translation_transform(inst_pivot) * rotation_matrix * Geometry::translation_transform(-inst_pivot);
|
||||
}
|
||||
else
|
||||
transform_instance_relative_world(v, volume_data, transformation_type, rotation_matrix, m_cache.dragging_center);
|
||||
transform_instance_relative(v, volume_data, transformation_type, rotation_matrix, m_cache.dragging_center);
|
||||
}
|
||||
else {
|
||||
if (!is_single_volume_or_modifier()) {
|
||||
@ -1024,27 +1024,19 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_
|
||||
}
|
||||
else {
|
||||
if (transformation_type.instance()) {
|
||||
// ensure proper sign of rotation for mirrored objects
|
||||
if (inst_trafo.is_left_handed() && !rotation.normalized().isApprox(Vec3d::UnitX()))
|
||||
rotation_matrix = rotation_matrix.inverse();
|
||||
|
||||
// ensure that the volume rotates as a rigid body
|
||||
const Transform3d inst_scale_matrix = inst_trafo.get_scaling_factor_matrix();
|
||||
rotation_matrix = inst_scale_matrix.inverse() * rotation_matrix * inst_scale_matrix;
|
||||
}
|
||||
else {
|
||||
if (transformation_type.local()) {
|
||||
const Geometry::Transformation& vol_trafo = volume_data.get_volume_transform();
|
||||
const Geometry::Transformation world_trafo = inst_trafo * vol_trafo;
|
||||
// ensure proper sign of rotation for mirrored objects
|
||||
if (world_trafo.is_left_handed() && !rotation.normalized().isApprox(Vec3d::UnitX()))
|
||||
rotation_matrix = rotation_matrix.inverse();
|
||||
|
||||
// ensure that the volume rotates as a rigid body
|
||||
if (Geometry::TransformationSVD(world_trafo).anisotropic_scale) {
|
||||
const Transform3d inst_scale_matrix = inst_trafo.get_scaling_factor_matrix();
|
||||
rotation_matrix = inst_scale_matrix.inverse() * rotation_matrix * inst_scale_matrix;
|
||||
}
|
||||
const Geometry::Transformation& vol_trafo = volume_data.get_volume_transform();
|
||||
const Transform3d vol_matrix_no_offset = vol_trafo.get_matrix_no_offset();
|
||||
const Transform3d inst_scale_matrix = inst_trafo.get_scaling_factor_matrix();
|
||||
const Transform3d vol_rotation_matrix = vol_trafo.get_rotation_matrix();
|
||||
rotation_matrix = vol_matrix_no_offset.inverse() * inst_scale_matrix.inverse() * vol_rotation_matrix * rotation_matrix *
|
||||
vol_rotation_matrix.inverse() * inst_scale_matrix * vol_matrix_no_offset;
|
||||
}
|
||||
}
|
||||
transform_volume_relative(v, volume_data, transformation_type, rotation_matrix, m_cache.dragging_center);
|
||||
@ -1458,7 +1450,7 @@ void Selection::scale_and_translate(const Vec3d& scale, const Vec3d& translation
|
||||
v.set_instance_transformation(Geometry::translation_transform(world_inst_pivot) * offset_trafo * Transform3d(inst_rotation) * scale_trafo * Geometry::translation_transform(-local_inst_pivot));
|
||||
}
|
||||
else
|
||||
transform_instance_relative_world(v, volume_data, transformation_type, Geometry::translation_transform(translation) * Geometry::scale_transform(relative_scale), m_cache.dragging_center);
|
||||
transform_instance_relative(v, volume_data, transformation_type, Geometry::translation_transform(translation) * Geometry::scale_transform(relative_scale), m_cache.dragging_center);
|
||||
}
|
||||
else {
|
||||
if (!is_single_volume_or_modifier()) {
|
||||
@ -3331,16 +3323,21 @@ void Selection::paste_objects_from_clipboard()
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void Selection::transform_instance_relative_world(GLVolume& volume, const VolumeCache& volume_data, TransformationType transformation_type,
|
||||
void Selection::transform_instance_relative(GLVolume& volume, const VolumeCache& volume_data, TransformationType transformation_type,
|
||||
const Transform3d& transform, const Vec3d& world_pivot)
|
||||
{
|
||||
assert(transformation_type.relative());
|
||||
assert(transformation_type.world());
|
||||
|
||||
const Geometry::Transformation& inst_trafo = volume_data.get_instance_transform();
|
||||
const Vec3d inst_pivot = transformation_type.independent() && !is_from_single_instance() ? inst_trafo.get_offset() : world_pivot;
|
||||
const Transform3d trafo = Geometry::translation_transform(inst_pivot) * transform * Geometry::translation_transform(-inst_pivot);
|
||||
volume.set_instance_transformation(trafo * inst_trafo.get_matrix());
|
||||
if (transformation_type.world()) {
|
||||
const Vec3d inst_pivot = transformation_type.independent() && !is_from_single_instance() ? inst_trafo.get_offset() : world_pivot;
|
||||
const Transform3d trafo = Geometry::translation_transform(inst_pivot) * transform * Geometry::translation_transform(-inst_pivot);
|
||||
volume.set_instance_transformation(trafo * inst_trafo.get_matrix());
|
||||
}
|
||||
else if (transformation_type.instance())
|
||||
volume.set_instance_transformation(inst_trafo.get_matrix() * transform);
|
||||
else
|
||||
assert(false);
|
||||
}
|
||||
|
||||
void Selection::transform_volume_relative(GLVolume& volume, const VolumeCache& volume_data, TransformationType transformation_type,
|
||||
|
@ -516,7 +516,7 @@ private:
|
||||
void paste_objects_from_clipboard();
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void transform_instance_relative_world(GLVolume& volume, const VolumeCache& volume_data, TransformationType transformation_type,
|
||||
void transform_instance_relative(GLVolume& volume, const VolumeCache& volume_data, TransformationType transformation_type,
|
||||
const Transform3d& transform, const Vec3d& world_pivot);
|
||||
void transform_volume_relative(GLVolume& volume, const VolumeCache& volume_data, TransformationType transformation_type,
|
||||
const Transform3d& transform, const Vec3d& world_pivot);
|
||||
|
Loading…
x
Reference in New Issue
Block a user