WIP, non-uniform scaling in the world coordinate system:

Disable non-uniform scaling when switching to the World coordinate system
and the rotation is not multiples of ninety degrees.
Ask user whether to bake in the transformations into the meshes if
enabling the non-uniform scaling in that case.
This commit is contained in:
bubnikv 2019-04-25 09:24:33 +02:00
parent 2cc7b00a7d
commit f78c3a0f1b
2 changed files with 51 additions and 1 deletions

View file

@ -201,6 +201,18 @@ void ObjectManipulation::UpdateAndShow(const bool show)
OG_Settings::UpdateAndShow(show);
}
static bool is_rotation_ninety_degrees(const Vec3d &rotation)
{
// Is the angle close to a multiple of 90 degrees?
auto ninety_degrees = [](double a) {
a = fmod(std::abs(a), 0.5 * PI);
if (a > 0.25 * PI)
a = 0.5 * PI - a;
return a < 0.001;
};
return ninety_degrees(rotation.x()) && ninety_degrees(rotation.y()) && ninety_degrees(rotation.z());
}
void ObjectManipulation::update_settings_value(const Selection& selection)
{
m_new_move_label_string = L("Position");
@ -251,6 +263,18 @@ void ObjectManipulation::update_settings_value(const Selection& selection)
m_new_rotate_label_string = L("Rotate");
m_new_scale_label_string = L("Scale");
m_new_enabled = true;
if (selection.is_single_full_instance() && m_world_coordinates && ! m_uniform_scale) {
// Verify whether the instance rotation is multiples of 90 degrees, so that the scaling in world coordinates is possible.
// 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());
// Is the angle close to a multiple of 90 degrees?
if (! is_rotation_ninety_degrees(volume->get_instance_rotation())) {
// Manipulating an instance in the world coordinate system, rotation is not multiples of ninety degrees, therefore enforce uniform scaling.
m_uniform_scale = true;
m_lock_bnt->SetLock(true);
}
}
}
else if (selection.is_single_modifier() || selection.is_single_volume())
{
@ -541,5 +565,31 @@ void ObjectManipulation::on_fill_empty_value(const std::string& opt_key)
}
}
void ObjectManipulation::set_uniform_scaling(const bool new_value)
{
const Selection &selection = wxGetApp().plater()->canvas3D()->get_selection();
if (selection.is_single_full_instance() && m_world_coordinates && !new_value) {
// Verify whether the instance rotation is multiples of 90 degrees, so that the scaling in world coordinates is possible.
// 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());
// Is the angle close to a multiple of 90 degrees?
if (! is_rotation_ninety_degrees(volume->get_instance_rotation())) {
// Cannot apply scaling in the world coordinate system.
wxMessageDialog dlg(GUI::wxGetApp().mainframe,
_(L("Non-uniform scaling of tilted objects is not supported in the World coordinate system.\n"
"Do you want to rotate the mesh?")),
SLIC3R_APP_NAME,
wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION);
if (dlg.ShowModal() != wxID_YES) {
// Enforce uniform scaling.
m_lock_bnt->SetLock(true);
return;
}
// Bake the rotation into the meshes of the object.
}
}
m_uniform_scale = new_value;
}
} //namespace GUI
} //namespace Slic3r

View file

@ -103,7 +103,7 @@ public:
// Called from the App to update the UI if dirty.
void update_if_dirty();
void set_uniform_scaling(const bool uniform_scale) { m_uniform_scale = uniform_scale;}
void set_uniform_scaling(const bool uniform_scale);
bool get_uniform_scaling() const { return m_uniform_scale; }
// Does the object manipulation panel work in World or Local coordinates?
void set_world_coordinates(const bool world_coordinates) { m_world_coordinates = world_coordinates; this->UpdateAndShow(true); }