diff --git a/src/libslic3r/Geometry.cpp b/src/libslic3r/Geometry.cpp index 441825654..f7f6bb2f9 100644 --- a/src/libslic3r/Geometry.cpp +++ b/src/libslic3r/Geometry.cpp @@ -728,7 +728,7 @@ void Transformation::reset_skew() const double average_scale = std::cbrt(scale(0, 0) * scale(1, 1) * scale(2, 2)); - scale(0, 0) = average_scale; + scale(0, 0) = is_left_handed() ? -average_scale : average_scale; scale(1, 1) = average_scale; scale(2, 2) = average_scale; diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index d737a7be4..103198ca8 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -235,7 +235,11 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : add_label(&m_scale_Label, L("Scale"), v_sizer); wxStaticText* size_Label {nullptr}; - add_label(&size_Label, L("Size"), v_sizer); +#if ENABLE_WORLD_COORDINATE + add_label(&size_Label, L("Size [World]"), v_sizer); +#else + add_label(&size_Label, L("Size"), v_sizer); +#endif // ENABLE_WORLD_COORDINATE if (wxOSX) set_font_and_background_style(size_Label, wxGetApp().normal_font()); sizer->Add(v_sizer, 0, wxLEFT, border); @@ -479,11 +483,18 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : #if ENABLE_WORLD_COORDINATE GLCanvas3D* canvas = wxGetApp().plater()->canvas3D(); Selection& selection = canvas->get_selection(); - if (selection.is_single_volume_or_modifier()) + if (selection.is_single_volume_or_modifier()) { + const bool is_left_handed = selection.get_first_volume()->get_volume_transformation().is_left_handed(); const_cast(selection.get_first_volume())->set_volume_scaling_factor(Vec3d::Ones()); + if (is_left_handed) + const_cast(selection.get_first_volume())->set_volume_mirror({ -1.0 , 1.0, 1.0 }); + } else if (selection.is_single_full_instance()) { + const bool is_left_handed = selection.get_first_volume()->get_instance_transformation().is_left_handed(); for (unsigned int idx : selection.get_volume_idxs()) { const_cast(selection.get_volume(idx))->set_instance_scaling_factor(Vec3d::Ones()); + if (is_left_handed) + const_cast(selection.get_volume(idx))->set_instance_mirror({ -1.0 , 1.0, 1.0 }); } } else @@ -712,21 +723,21 @@ 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); m_new_size = selection.get_bounding_box_in_current_reference_system().first.size(); + m_new_scale = m_new_size.cwiseQuotient(selection.get_unscaled_instance_bounding_box().size()) * 100.0; + m_new_rotate_label_string = L("Rotate (relative)"); #else if (m_world_coordinates) { m_new_scale = m_new_size.cwiseQuotient(selection.get_unscaled_instance_bounding_box().size()) * 100.0; m_new_size = selection.get_scaled_instance_bounding_box().size(); -#endif // ENABLE_WORLD_COORDINATE m_new_rotate_label_string = L("Rotate"); +#endif // ENABLE_WORLD_COORDINATE m_new_rotation = Vec3d::Zero(); } else { #if ENABLE_WORLD_COORDINATE - m_new_move_label_string = L("Translate"); - m_new_rotate_label_string = L("Rotate"); + m_new_move_label_string = L("Translate (relative) [World]"); + m_new_rotate_label_string = L("Rotate (relative)"); m_new_position = Vec3d::Zero(); m_new_rotation = Vec3d::Zero(); m_new_scale = Vec3d(100.0, 100.0, 100.0); @@ -768,15 +779,15 @@ void ObjectManipulation::update_settings_value(const Selection& selection) const Vec3d& offset = trafo.get_offset(); m_new_position = offset; - m_new_rotate_label_string = L("Rotate"); + m_new_rotate_label_string = L("Rotate (relative)"); 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 = selection.get_bounding_box_in_current_reference_system().first.size(); } else if (is_local_coordinates()) { - m_new_move_label_string = L("Translate"); - m_new_rotate_label_string = L("Rotate"); + m_new_move_label_string = L("Translate (relative) [World]"); + m_new_rotate_label_string = L("Rotate (relative)"); m_new_position = Vec3d::Zero(); m_new_rotation = Vec3d::Zero(); m_new_scale = volume->get_volume_scaling_factor() * 100.0; @@ -785,7 +796,11 @@ void ObjectManipulation::update_settings_value(const Selection& selection) else { #endif // ENABLE_WORLD_COORDINATE m_new_position = volume->get_volume_offset(); +#if ENABLE_WORLD_COORDINATE + m_new_rotate_label_string = L("Rotate (relative)"); +#else m_new_rotate_label_string = L("Rotate"); +#endif // ENABLE_WORLD_COORDINATE m_new_rotation = Vec3d::Zero(); #if ENABLE_WORLD_COORDINATE m_new_scale_label_string = L("Scale"); @@ -1221,10 +1236,8 @@ void ObjectManipulation::change_scale_value(int axis, double value) scale = scale.cwiseQuotient(ref_scale); ref_scale = Vec3d::Ones(); } - else if (selection.is_single_full_instance()) { - scale = scale.cwiseQuotient(ref_scale); - ref_scale = Vec3d::Ones(); - } + else if (selection.is_single_full_instance()) + ref_scale = 100.0 * Vec3d::Ones(); this->do_scale(axis, scale.cwiseQuotient(ref_scale)); #else @@ -1276,9 +1289,9 @@ 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(); + ref_size = selection.get_full_unscaled_instance_bounding_box().size(); + else + ref_size = selection.get_full_unscaled_instance_local_bounding_box().size(); #else ref_size = m_world_coordinates ? selection.get_unscaled_instance_bounding_box().size() : @@ -1311,8 +1324,7 @@ 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()) && - !(selection.is_single_full_instance() && is_instance_coordinates())) + 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 5678008d3..072efc2d8 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -969,7 +969,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(v, volume_data, transformation_type, Geometry::translation_transform(displacement), m_cache.dragging_center); + transform_instance_relative_world(v, volume_data, transformation_type, Geometry::translation_transform(displacement), m_cache.dragging_center); } else { if (transformation_type.local() && transformation_type.absolute()) { @@ -1066,7 +1066,7 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_ 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)); } 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 { if (!is_single_volume_or_modifier()) { @@ -1471,6 +1471,29 @@ void Selection::scale_and_translate(const Vec3d& scale, const Vec3d& translation const VolumeCache& volume_data = m_cache.volumes_data[i]; const Geometry::Transformation& inst_trafo = volume_data.get_instance_transform(); + Vec3d relative_scale = scale; + + if (transformation_type.absolute()) { + if (m_mode == Instance) { + if (is_single_full_instance()) { + BoundingBoxf3 current_box = m_box.get_bounding_box(); + BoundingBoxf3 original_box; + if (transformation_type.world()) + original_box = get_full_unscaled_instance_bounding_box(); + else + original_box = get_full_unscaled_instance_local_bounding_box(); + + relative_scale = original_box.size().cwiseProduct(scale).cwiseQuotient(current_box.size()); + + std::cout << to_string(scale) << to_string(original_box.size()) << to_string(current_box.size()) << to_string(relative_scale) << "\n"; + + transformation_type.set_relative(); + } + } + else { + } + } + if (m_mode == Instance) { if (transformation_type.instance()) { const Vec3d world_inst_pivot = m_cache.dragging_center - inst_trafo.get_offset(); @@ -1478,11 +1501,11 @@ void Selection::scale_and_translate(const Vec3d& scale, const Vec3d& translation Matrix3d inst_rotation, inst_scale; inst_trafo.get_matrix().computeRotationScaling(&inst_rotation, &inst_scale); const Transform3d offset_trafo = Geometry::translation_transform(inst_trafo.get_offset() + inst_rotation * translation); - const Transform3d scale_trafo = Transform3d(inst_scale) * Geometry::scale_transform(scale); + const Transform3d scale_trafo = Transform3d(inst_scale) * Geometry::scale_transform(relative_scale); 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(v, volume_data, transformation_type, Geometry::translation_transform(translation) * Geometry::scale_transform(scale), m_cache.dragging_center); + transform_instance_relative_world(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()) { @@ -1509,9 +1532,9 @@ void Selection::scale_and_translate(const Vec3d& scale, const Vec3d& translation #if !DISABLE_INSTANCES_SYNCH if (m_mode == Instance) - synchronize_unselected_instances(SyncRotationType::NONE); + synchronize_unselected_instances(SyncRotationType::NONE); else if (m_mode == Volume) - synchronize_unselected_volumes(); + synchronize_unselected_volumes(); #endif // !DISABLE_INSTANCES_SYNCH ensure_on_bed(); @@ -3297,7 +3320,7 @@ void Selection::paste_objects_from_clipboard() } #if ENABLE_WORLD_COORDINATE -void Selection::transform_instance_relative(GLVolume& volume, const VolumeCache& volume_data, TransformationType transformation_type, +void Selection::transform_instance_relative_world(GLVolume& volume, const VolumeCache& volume_data, TransformationType transformation_type, const Transform3d& transform, const Vec3d& world_pivot) { assert(transformation_type.relative()); diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index 36f973839..29398eabf 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -514,7 +514,7 @@ private: void paste_objects_from_clipboard(); #if ENABLE_WORLD_COORDINATE - void transform_instance_relative(GLVolume& volume, const VolumeCache& volume_data, TransformationType transformation_type, + void transform_instance_relative_world(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);