mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-01 01:14:02 +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();
|
selection.get_bounding_box_in_reference_system(ECoordinatesType::Local) : selection.get_bounding_box_in_current_reference_system();
|
||||||
m_bounding_box = box;
|
m_bounding_box = box;
|
||||||
m_center = box_trafo.translation();
|
m_center = box_trafo.translation();
|
||||||
m_orient_matrix = Geometry::translation_transform(m_center);
|
m_orient_matrix = box_trafo;
|
||||||
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_radius = Offset + m_bounding_box.radius();
|
m_radius = Offset + m_bounding_box.radius();
|
||||||
m_snap_coarse_in_radius = m_radius / 3.0f;
|
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);
|
v.set_instance_offset(inst_trafo.get_offset() + inst_trafo.get_rotation_matrix() * displacement);
|
||||||
}
|
}
|
||||||
else
|
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 {
|
else {
|
||||||
if (transformation_type.local() && transformation_type.absolute()) {
|
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()));
|
assert(transformation_type.relative() || (transformation_type.absolute() && transformation_type.local()));
|
||||||
|
|
||||||
Transform3d rotation_matrix = Geometry::rotation_transform(rotation);
|
|
||||||
|
|
||||||
for (unsigned int i : m_list) {
|
for (unsigned int i : m_list) {
|
||||||
|
Transform3d rotation_matrix = Geometry::rotation_transform(rotation);
|
||||||
GLVolume& v = *(*m_volumes)[i];
|
GLVolume& v = *(*m_volumes)[i];
|
||||||
const VolumeCache& volume_data = m_cache.volumes_data[i];
|
const VolumeCache& volume_data = m_cache.volumes_data[i];
|
||||||
const Geometry::Transformation& inst_trafo = volume_data.get_instance_transform();
|
const Geometry::Transformation& inst_trafo = volume_data.get_instance_transform();
|
||||||
if (m_mode == Instance && !is_wipe_tower()) {
|
if (m_mode == Instance && !is_wipe_tower()) {
|
||||||
assert(is_from_fully_selected_instance(i));
|
assert(is_from_fully_selected_instance(i));
|
||||||
if (transformation_type.instance()) {
|
if (transformation_type.instance()) {
|
||||||
const Vec3d world_inst_pivot = m_cache.dragging_center - inst_trafo.get_offset();
|
// ensure that the instance rotates as a rigid body
|
||||||
const Vec3d local_inst_pivot = inst_trafo.get_matrix_no_offset().inverse() * world_inst_pivot;
|
const Transform3d inst_matrix_no_offset = inst_trafo.get_matrix_no_offset();
|
||||||
Matrix3d inst_rotation, inst_scale;
|
const Transform3d inst_rotation_matrix = inst_trafo.get_rotation_matrix();
|
||||||
inst_trafo.get_matrix().computeRotationScaling(&inst_rotation, &inst_scale);
|
rotation_matrix = inst_matrix_no_offset.inverse() * inst_rotation_matrix * rotation_matrix * inst_rotation_matrix.inverse() * inst_matrix_no_offset;
|
||||||
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));
|
// 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(v, volume_data, transformation_type, rotation_matrix, m_cache.dragging_center);
|
||||||
transform_instance_relative_world(v, volume_data, transformation_type, rotation_matrix, m_cache.dragging_center);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!is_single_volume_or_modifier()) {
|
if (!is_single_volume_or_modifier()) {
|
||||||
@ -1024,27 +1024,19 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (transformation_type.instance()) {
|
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
|
// ensure that the volume rotates as a rigid body
|
||||||
const Transform3d inst_scale_matrix = inst_trafo.get_scaling_factor_matrix();
|
const Transform3d inst_scale_matrix = inst_trafo.get_scaling_factor_matrix();
|
||||||
rotation_matrix = inst_scale_matrix.inverse() * rotation_matrix * inst_scale_matrix;
|
rotation_matrix = inst_scale_matrix.inverse() * rotation_matrix * inst_scale_matrix;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (transformation_type.local()) {
|
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
|
// ensure that the volume rotates as a rigid body
|
||||||
if (Geometry::TransformationSVD(world_trafo).anisotropic_scale) {
|
const Geometry::Transformation& vol_trafo = volume_data.get_volume_transform();
|
||||||
const Transform3d inst_scale_matrix = inst_trafo.get_scaling_factor_matrix();
|
const Transform3d vol_matrix_no_offset = vol_trafo.get_matrix_no_offset();
|
||||||
rotation_matrix = inst_scale_matrix.inverse() * rotation_matrix * inst_scale_matrix;
|
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);
|
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));
|
v.set_instance_transformation(Geometry::translation_transform(world_inst_pivot) * offset_trafo * Transform3d(inst_rotation) * scale_trafo * Geometry::translation_transform(-local_inst_pivot));
|
||||||
}
|
}
|
||||||
else
|
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 {
|
else {
|
||||||
if (!is_single_volume_or_modifier()) {
|
if (!is_single_volume_or_modifier()) {
|
||||||
@ -3331,16 +3323,21 @@ void Selection::paste_objects_from_clipboard()
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLE_WORLD_COORDINATE
|
#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)
|
const Transform3d& transform, const Vec3d& world_pivot)
|
||||||
{
|
{
|
||||||
assert(transformation_type.relative());
|
assert(transformation_type.relative());
|
||||||
assert(transformation_type.world());
|
|
||||||
|
|
||||||
const Geometry::Transformation& inst_trafo = volume_data.get_instance_transform();
|
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;
|
if (transformation_type.world()) {
|
||||||
const Transform3d trafo = Geometry::translation_transform(inst_pivot) * transform * Geometry::translation_transform(-inst_pivot);
|
const Vec3d inst_pivot = transformation_type.independent() && !is_from_single_instance() ? inst_trafo.get_offset() : world_pivot;
|
||||||
volume.set_instance_transformation(trafo * inst_trafo.get_matrix());
|
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,
|
void Selection::transform_volume_relative(GLVolume& volume, const VolumeCache& volume_data, TransformationType transformation_type,
|
||||||
|
@ -516,7 +516,7 @@ private:
|
|||||||
void paste_objects_from_clipboard();
|
void paste_objects_from_clipboard();
|
||||||
|
|
||||||
#if ENABLE_WORLD_COORDINATE
|
#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);
|
const Transform3d& transform, const Vec3d& world_pivot);
|
||||||
void transform_volume_relative(GLVolume& volume, const VolumeCache& volume_data, TransformationType transformation_type,
|
void transform_volume_relative(GLVolume& volume, const VolumeCache& volume_data, TransformationType transformation_type,
|
||||||
const Transform3d& transform, const Vec3d& world_pivot);
|
const Transform3d& transform, const Vec3d& world_pivot);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user