Tech ENABLE_WORLD_COORDINATE_SCALE_REVISITED - Alternate implementation of manipulating scale for instances and volumes using gizmo scale and sidebar object manipulator fields - 1st installment
This commit is contained in:
parent
cf245a7995
commit
db852fe74f
@ -1412,9 +1412,11 @@ void ModelObject::bake_xy_rotation_into_meshes(size_t instance_idx)
|
||||
assert(instance_idx < this->instances.size());
|
||||
|
||||
const Geometry::Transformation reference_trafo = this->instances[instance_idx]->get_transformation();
|
||||
#if !ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
if (Geometry::is_rotation_ninety_degrees(reference_trafo.get_rotation()))
|
||||
// nothing to do, scaling in the world coordinate space is possible in the representation of Geometry::Transformation.
|
||||
return;
|
||||
#endif // !ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
|
||||
bool left_handed = reference_trafo.is_left_handed();
|
||||
bool has_mirrorring = ! reference_trafo.get_mirror().isApprox(Vec3d(1., 1., 1.));
|
||||
|
@ -86,6 +86,8 @@
|
||||
#define ENABLE_COORDINATE_DEPENDENT_SELECTION_BOX (1 && ENABLE_WORLD_COORDINATE)
|
||||
// Enable showing the axes of the current reference system when sidebar hints are active
|
||||
#define ENABLE_WORLD_COORDINATE_SHOW_AXES (1 && ENABLE_WORLD_COORDINATE)
|
||||
// Enable alternate implementation of manipulating scale for instances and volumes
|
||||
#define ENABLE_WORLD_COORDINATE_SCALE_REVISITED (1 && ENABLE_WORLD_COORDINATE)
|
||||
|
||||
|
||||
#endif // _prusaslicer_technologies_h_
|
||||
|
@ -627,10 +627,17 @@ void ObjectManipulation::update_settings_value(const Selection& selection)
|
||||
if (m_world_coordinates) {
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
m_new_rotate_label_string = L("Rotate");
|
||||
#if ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
m_new_scale_label_string = L("Scale");
|
||||
#endif // ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
m_new_rotation = Vec3d::Zero();
|
||||
m_new_size = selection.get_scaled_instance_bounding_box().size();
|
||||
m_new_scale = m_new_size.cwiseProduct(selection.get_unscaled_instance_bounding_box().size().cwiseInverse()) * 100.0;
|
||||
}
|
||||
#if ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
m_new_scale = Vec3d(100.0, 100.0, 100.0);
|
||||
#else
|
||||
m_new_scale = m_new_size.cwiseProduct(selection.get_unscaled_instance_bounding_box().size().cwiseInverse()) * 100.0;
|
||||
#endif // ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
}
|
||||
else {
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
m_new_move_label_string = L("Translate");
|
||||
@ -672,9 +679,16 @@ void ObjectManipulation::update_settings_value(const Selection& selection)
|
||||
|
||||
m_new_position = offset;
|
||||
m_new_rotate_label_string = L("Rotate");
|
||||
#if ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
m_new_scale_label_string = L("Scale");
|
||||
#endif // ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
m_new_rotation = Vec3d::Zero();
|
||||
m_new_size = volume->transformed_convex_hull_bounding_box(trafo.get_matrix()).size();
|
||||
#if ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
m_new_scale = Vec3d(100.0, 100.0, 100.0);
|
||||
#else
|
||||
m_new_scale = m_new_size.cwiseProduct(volume->transformed_convex_hull_bounding_box(volume->get_instance_transformation().get_matrix() * volume->get_volume_transformation().get_matrix(false, false, true, false)).size().cwiseInverse()) * 100.0;
|
||||
#endif // ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
}
|
||||
else if (is_local_coordinates()) {
|
||||
m_new_move_label_string = L("Translate");
|
||||
@ -687,10 +701,17 @@ void ObjectManipulation::update_settings_value(const Selection& selection)
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
m_new_position = volume->get_volume_offset();
|
||||
m_new_rotate_label_string = L("Rotate");
|
||||
#if ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
m_new_scale_label_string = L("Scale");
|
||||
#endif // ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
m_new_rotation = Vec3d::Zero();
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
m_new_size = volume->transformed_convex_hull_bounding_box(volume->get_volume_transformation().get_matrix()).size();
|
||||
#if ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
m_new_scale = Vec3d(100.0, 100.0, 100.0);
|
||||
#else
|
||||
m_new_scale = m_new_size.cwiseProduct(volume->transformed_convex_hull_bounding_box(volume->get_volume_transformation().get_matrix(false, false, true, false)).size().cwiseInverse()) * 100.0;
|
||||
#endif // ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
}
|
||||
#else
|
||||
m_new_scale = volume->get_volume_scaling_factor() * 100.0;
|
||||
@ -767,20 +788,26 @@ void ObjectManipulation::update_if_dirty()
|
||||
#else
|
||||
if (selection.requires_uniform_scale()) {
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
#if !ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
m_lock_bnt->SetLock(true);
|
||||
#endif // !ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
wxString tooltip;
|
||||
if (selection.is_single_volume_or_modifier()) {
|
||||
#if !ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
if (reason == Selection::EUniformScaleRequiredReason::VolumeNotAxisAligned_Instance)
|
||||
tooltip = _L("You cannot use non-uniform scaling mode for parts non aligned with the instance local axes");
|
||||
else if (reason == Selection::EUniformScaleRequiredReason::VolumeNotAxisAligned_World)
|
||||
tooltip = _L("You cannot use non-uniform scaling mode for parts non aligned with the printer axes");
|
||||
#endif // !ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
}
|
||||
else if (selection.is_single_full_instance()) {
|
||||
#if !ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
if (reason == Selection::EUniformScaleRequiredReason::InstanceNotAxisAligned_World)
|
||||
tooltip = _L("You cannot use non-uniform scaling mode for instances non aligned with the printer axes");
|
||||
else if (reason == Selection::EUniformScaleRequiredReason::VolumeNotAxisAligned_Instance)
|
||||
tooltip = _L("You cannot use non-uniform scaling mode for instances containing non locally axis-aligned parts");
|
||||
#endif // !ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
}
|
||||
else
|
||||
tooltip = _L("You cannot use non-uniform scaling mode for multiple objects/parts selection");
|
||||
@ -789,7 +816,9 @@ void ObjectManipulation::update_if_dirty()
|
||||
#else
|
||||
m_lock_bnt->SetToolTip(_L("You cannot use non-uniform scaling mode for multiple objects/parts selection"));
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
#if !ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
m_lock_bnt->disable();
|
||||
#endif // !ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
}
|
||||
else {
|
||||
m_lock_bnt->SetLock(m_uniform_scale);
|
||||
@ -1110,7 +1139,11 @@ void ObjectManipulation::change_size_value(int axis, double value)
|
||||
selection.get_unscaled_instance_bounding_box().size() :
|
||||
wxGetApp().model().objects[selection.get_volume(*selection.get_volume_idxs().begin())->object_idx()]->raw_mesh_bounding_box().size();
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
this->do_size(axis, size.cwiseQuotient(ref_size));
|
||||
#else
|
||||
this->do_scale(axis, size.cwiseQuotient(ref_size));
|
||||
#endif // ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
|
||||
m_cache.size = size;
|
||||
m_cache.size_rounded(axis) = DBL_MAX;
|
||||
@ -1126,8 +1159,18 @@ void ObjectManipulation::do_scale(int axis, const Vec3d &scale) const
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
TransformationType transformation_type;
|
||||
#if ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
if (is_local_coordinates())
|
||||
transformation_type.set_local();
|
||||
else if (is_instance_coordinates())
|
||||
transformation_type.set_instance();
|
||||
|
||||
if (!is_local_coordinates())
|
||||
transformation_type.set_relative();
|
||||
#else
|
||||
if (!is_world_coordinates())
|
||||
transformation_type.set_local();
|
||||
#endif // ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
|
||||
bool uniform_scale = m_uniform_scale || selection.requires_uniform_scale();
|
||||
Vec3d scaling_factor = uniform_scale ? scale(axis) * Vec3d::Ones() : scale;
|
||||
@ -1159,6 +1202,37 @@ void ObjectManipulation::do_scale(int axis, const Vec3d &scale) const
|
||||
wxGetApp().plater()->canvas3D()->do_scale(L("Set Scale"));
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
void ObjectManipulation::do_size(int axis, const Vec3d& scale) const
|
||||
{
|
||||
Selection& selection = wxGetApp().plater()->canvas3D()->get_selection();
|
||||
|
||||
TransformationType transformation_type;
|
||||
if (is_local_coordinates())
|
||||
transformation_type.set_local();
|
||||
else if (is_instance_coordinates())
|
||||
transformation_type.set_instance();
|
||||
|
||||
bool uniform_scale = m_uniform_scale || selection.requires_uniform_scale();
|
||||
Vec3d scaling_factor = uniform_scale ? scale(axis) * Vec3d::Ones() : scale;
|
||||
|
||||
if (!uniform_scale && is_world_coordinates()) {
|
||||
if (selection.is_single_full_instance())
|
||||
scaling_factor = (Geometry::assemble_transform(Vec3d::Zero(), selection.get_volume(*selection.get_volume_idxs().begin())->get_instance_rotation()).inverse() * scaling_factor).cwiseAbs();
|
||||
else if (selection.is_single_volume_or_modifier()) {
|
||||
const Transform3d mi = Geometry::assemble_transform(Vec3d::Zero(), selection.get_volume(*selection.get_volume_idxs().begin())->get_instance_rotation()).inverse();
|
||||
const Transform3d mv = Geometry::assemble_transform(Vec3d::Zero(), selection.get_volume(*selection.get_volume_idxs().begin())->get_volume_rotation()).inverse();
|
||||
scaling_factor = (mv * mi * scaling_factor).cwiseAbs();
|
||||
}
|
||||
}
|
||||
|
||||
selection.start_dragging();
|
||||
selection.scale(scaling_factor, transformation_type);
|
||||
selection.stop_dragging();
|
||||
wxGetApp().plater()->canvas3D()->do_scale(L("Set Size"));
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
|
||||
void ObjectManipulation::on_change(const std::string& opt_key, int axis, double new_value)
|
||||
{
|
||||
if (!m_cache.is_valid())
|
||||
@ -1193,21 +1267,37 @@ void ObjectManipulation::on_change(const std::string& opt_key, int axis, double
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectManipulation::set_uniform_scaling(const bool new_value)
|
||||
void ObjectManipulation::set_uniform_scaling(const bool use_uniform_scale)
|
||||
{
|
||||
const Selection &selection = wxGetApp().plater()->canvas3D()->get_selection();
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
if (selection.is_single_full_instance() && is_world_coordinates() && !new_value) {
|
||||
#if ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
if (!use_uniform_scale) {
|
||||
int res = selection.bake_transform_if_needed(false);
|
||||
if (res == -1) {
|
||||
// Enforce uniform scaling.
|
||||
m_lock_bnt->SetLock(true);
|
||||
return;
|
||||
}
|
||||
else if (res == 0) {
|
||||
// Recalculate cached values at this panel, refresh the screen.
|
||||
this->UpdateAndShow(true);
|
||||
}
|
||||
}
|
||||
|
||||
m_uniform_scale = use_uniform_scale;
|
||||
#else
|
||||
if (selection.is_single_full_instance() && m_world_coordinates && !new_value) {
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
if (selection.is_single_full_instance() && is_world_coordinates() && !use_uniform_scale) {
|
||||
#else
|
||||
if (selection.is_single_full_instance() && m_world_coordinates && !use_uniform_scale) {
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
// 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 (! Geometry::is_rotation_ninety_degrees(volume->get_instance_rotation())) {
|
||||
if (!Geometry::is_rotation_ninety_degrees(volume->get_instance_rotation())) {
|
||||
// Cannot apply scaling in the world coordinate system.
|
||||
//wxMessageDialog dlg(GUI::wxGetApp().mainframe,
|
||||
//wxMessageDialog dlg(GUI::wxGetApp().mainframe,
|
||||
MessageDialog dlg(GUI::wxGetApp().mainframe,
|
||||
_L("The currently manipulated object is tilted (rotation angles are not multiples of 90°).\n"
|
||||
"Non-uniform scaling of tilted objects is only possible in the World coordinate system,\n"
|
||||
@ -1215,7 +1305,7 @@ void ObjectManipulation::set_uniform_scaling(const bool new_value)
|
||||
_L("This operation is irreversible.\n"
|
||||
"Do you want to proceed?"),
|
||||
SLIC3R_APP_NAME,
|
||||
wxYES_NO | wxCANCEL | wxCANCEL_DEFAULT | wxICON_QUESTION);
|
||||
wxYES_NO | wxCANCEL | wxCANCEL_DEFAULT | wxICON_QUESTION);
|
||||
if (dlg.ShowModal() != wxID_YES) {
|
||||
// Enforce uniform scaling.
|
||||
m_lock_bnt->SetLock(true);
|
||||
@ -1229,7 +1319,9 @@ void ObjectManipulation::set_uniform_scaling(const bool new_value)
|
||||
this->UpdateAndShow(true);
|
||||
}
|
||||
}
|
||||
m_uniform_scale = new_value;
|
||||
|
||||
m_uniform_scale = use_uniform_scale;
|
||||
#endif // ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
|
@ -196,7 +196,7 @@ public:
|
||||
// Called from the App to update the UI if dirty.
|
||||
void update_if_dirty();
|
||||
|
||||
void set_uniform_scaling(const bool uniform_scale);
|
||||
void set_uniform_scaling(const bool use_uniform_scale);
|
||||
bool get_uniform_scaling() const { return m_uniform_scale; }
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void set_coordinates_type(ECoordinatesType type);
|
||||
@ -256,6 +256,9 @@ private:
|
||||
void change_scale_value(int axis, double value);
|
||||
void change_size_value(int axis, double value);
|
||||
void do_scale(int axis, const Vec3d &scale) const;
|
||||
#if ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
void do_size(int axis, const Vec3d& scale) const;
|
||||
#endif // ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
void set_coordinates_type(const wxString& type_string);
|
||||
|
@ -62,6 +62,10 @@ public:
|
||||
const Vec3d& get_scale() const { return m_scale; }
|
||||
void set_scale(const Vec3d& scale) { m_starting.scale = scale; m_scale = scale; }
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
const Vec3d& get_starting_scale() const { return m_starting.scale; }
|
||||
#endif // ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
|
||||
const Vec3d& get_offset() const { return m_offset; }
|
||||
|
||||
std::string get_tooltip() const override;
|
||||
|
@ -242,13 +242,17 @@ void GLGizmosManager::update_data()
|
||||
enable_grabber(Rotate, 1, !is_wipe_tower);
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
#if !ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
bool enable_scale_xyz = !selection.requires_uniform_scale();
|
||||
#endif // !ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
#else
|
||||
bool enable_scale_xyz = selection.is_single_full_instance() || selection.is_single_volume() || selection.is_single_modifier();
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
#if !ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
for (unsigned int i = 0; i < 6; ++i) {
|
||||
enable_grabber(Scale, i, enable_scale_xyz);
|
||||
}
|
||||
#endif // !ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
|
||||
if (m_common_gizmos_data)
|
||||
m_common_gizmos_data->update(get_current()
|
||||
@ -370,6 +374,16 @@ void GLGizmosManager::set_scale(const Vec3d& scale)
|
||||
dynamic_cast<GLGizmoScale3D*>(m_gizmos[Scale].get())->set_scale(scale);
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
Vec3d GLGizmosManager::get_starting_scale() const
|
||||
{
|
||||
if (!m_enabled)
|
||||
return Vec3d::Ones();
|
||||
|
||||
return dynamic_cast<GLGizmoScale3D*>(m_gizmos[Scale].get())->get_starting_scale();
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
|
||||
Vec3d GLGizmosManager::get_scale_offset() const
|
||||
{
|
||||
if (!m_enabled || m_gizmos.empty())
|
||||
@ -553,7 +567,8 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt)
|
||||
m_tooltip = update_hover_state(mouse_pos);
|
||||
if (m_current == MmuSegmentation || m_current == FdmSupports)
|
||||
gizmo_event(SLAGizmoEventType::Moving, mouse_pos, evt.ShiftDown(), evt.AltDown());
|
||||
} else if (evt.LeftUp()) {
|
||||
}
|
||||
else if (evt.LeftUp()) {
|
||||
if (m_mouse_capture.left) {
|
||||
processed = true;
|
||||
m_mouse_capture.left = false;
|
||||
@ -561,7 +576,30 @@ bool GLGizmosManager::on_mouse(wxMouseEvent& evt)
|
||||
else if (is_dragging()) {
|
||||
switch (m_current) {
|
||||
case Move: { m_parent.do_move(L("Gizmo-Move")); break; }
|
||||
#if ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
case Scale: {
|
||||
const Vec3d scale = get_scale();
|
||||
const Vec3d starting_scale = get_starting_scale();
|
||||
wxGetApp().CallAfter([this, &selection, scale, starting_scale]() {
|
||||
int res = 1;
|
||||
if (scale.x() != scale.y() || scale.x() != scale.z())
|
||||
res = selection.bake_transform_if_needed(L("Gizmo-Scale"));
|
||||
|
||||
if (res == 1)
|
||||
m_parent.do_scale(L("Gizmo-Scale"));
|
||||
else if (res == -1) {
|
||||
TransformationType transformation_type;
|
||||
if (!wxGetApp().obj_manipul()->is_world_coordinates())
|
||||
transformation_type.set_local();
|
||||
selection.scale(starting_scale, transformation_type);
|
||||
}
|
||||
}
|
||||
);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
case Scale: { m_parent.do_scale(L("Gizmo-Scale")); break; }
|
||||
#endif // ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
case Rotate: { m_parent.do_rotate(L("Gizmo-Rotate")); break; }
|
||||
default: break;
|
||||
}
|
||||
|
@ -209,7 +209,9 @@ public:
|
||||
|
||||
Vec3d get_scale() const;
|
||||
void set_scale(const Vec3d& scale);
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
Vec3d get_starting_scale() const;
|
||||
#endif // ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
Vec3d get_scale_offset() const;
|
||||
|
||||
Vec3d get_rotation() const;
|
||||
|
@ -7,9 +7,14 @@
|
||||
#include "GUI.hpp"
|
||||
#include "GUI_ObjectManipulation.hpp"
|
||||
#include "GUI_ObjectList.hpp"
|
||||
#include "Gizmos/GLGizmoBase.hpp"
|
||||
#include "Camera.hpp"
|
||||
#include "Plater.hpp"
|
||||
#if ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
#include "MsgDialog.hpp"
|
||||
#endif // ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
|
||||
#include "Gizmos/GLGizmoBase.hpp"
|
||||
|
||||
#include "slic3r/Utils/UndoRedo.hpp"
|
||||
|
||||
#include "libslic3r/LocalesUtils.hpp"
|
||||
@ -605,6 +610,9 @@ bool Selection::requires_uniform_scale() const
|
||||
#endif // ENABLE_WORLD_COORDINATE
|
||||
{
|
||||
#if ENABLE_WORLD_COORDINATE
|
||||
if (is_empty())
|
||||
return false;
|
||||
|
||||
ECoordinatesType coord_type = wxGetApp().obj_manipul()->get_coordinates_type();
|
||||
if (is_single_volume_or_modifier()) {
|
||||
if (coord_type == ECoordinatesType::World) {
|
||||
@ -639,7 +647,6 @@ bool Selection::requires_uniform_scale() const
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
for (unsigned int i : m_list) {
|
||||
@ -649,8 +656,8 @@ bool Selection::requires_uniform_scale() const
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (reason != nullptr)
|
||||
@ -1301,6 +1308,65 @@ void Selection::translate(unsigned int object_idx, unsigned int instance_idx, co
|
||||
this->set_bounding_boxes_dirty();
|
||||
}
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
int Selection::bake_transform_if_needed(bool apply_scale) const
|
||||
{
|
||||
if ((is_single_full_instance() && wxGetApp().obj_manipul()->is_world_coordinates()) ||
|
||||
(is_single_volume_or_modifier() && !wxGetApp().obj_manipul()->is_local_coordinates())) {
|
||||
// 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 = *get_volume(*get_volume_idxs().begin());
|
||||
bool needs_baking = false;
|
||||
if (is_single_full_instance()) {
|
||||
// Is the instance angle close to a multiple of 90 degrees?
|
||||
needs_baking |= !Geometry::is_rotation_ninety_degrees(volume.get_instance_rotation());
|
||||
// Are all volumes angles close to a multiple of 90 degrees?
|
||||
for (unsigned int id : get_volume_idxs()) {
|
||||
if (needs_baking)
|
||||
break;
|
||||
needs_baking |= !Geometry::is_rotation_ninety_degrees(get_volume(id)->get_volume_rotation());
|
||||
}
|
||||
}
|
||||
else if (is_single_volume_or_modifier()) {
|
||||
// is the volume angle close to a multiple of 90 degrees?
|
||||
needs_baking |= !Geometry::is_rotation_ninety_degrees(volume.get_volume_rotation());
|
||||
if (wxGetApp().obj_manipul()->is_world_coordinates())
|
||||
// Is the instance angle close to a multiple of 90 degrees?
|
||||
needs_baking |= !Geometry::is_rotation_ninety_degrees(volume.get_instance_rotation());
|
||||
}
|
||||
|
||||
if (needs_baking) {
|
||||
MessageDialog dlg((wxWindow*)wxGetApp().mainframe,
|
||||
_L("The currently manipulated object is tilted or contains tilted parts (rotation angles are not multiples of 90°). "
|
||||
"Non-uniform scaling of tilted objects is only possible in non-local coordinate systems, "
|
||||
"once the rotation is embedded into the object coordinates.") + "\n" +
|
||||
_L("This operation is irreversible.") + "\n" +
|
||||
_L("Do you want to proceed?"),
|
||||
SLIC3R_APP_NAME,
|
||||
wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION);
|
||||
if (dlg.ShowModal() != wxID_YES)
|
||||
return -1;
|
||||
|
||||
if (apply_scale) {
|
||||
wxGetApp().plater()->get_current_canvas3D()->do_scale(L("Scale + Bake transform"));
|
||||
Plater::SuppressSnapshots suppress(wxGetApp().plater());
|
||||
wxGetApp().plater()->take_snapshot(_("Bake transform"));
|
||||
}
|
||||
else
|
||||
wxGetApp().plater()->take_snapshot(_("Bake transform"));
|
||||
|
||||
// Bake the rotation into the meshes of the object.
|
||||
wxGetApp().model().objects[volume.composite_id.object_id]->bake_xy_rotation_into_meshes(volume.composite_id.instance_id);
|
||||
// Update the 3D scene, selections etc.
|
||||
wxGetApp().plater()->update();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif // ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
|
||||
void Selection::erase()
|
||||
{
|
||||
if (!m_valid)
|
||||
|
@ -369,6 +369,15 @@ public:
|
||||
void translate(unsigned int object_idx, const Vec3d& displacement);
|
||||
void translate(unsigned int object_idx, unsigned int instance_idx, const Vec3d& displacement);
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
// returns:
|
||||
// -1 if the user refused to proceed with baking when asked
|
||||
// 0 if the baking was performed
|
||||
// 1 if no baking was needed
|
||||
// if apply_scale == true the scaling of the current selection is applied
|
||||
int bake_transform_if_needed(bool apply_scale) const;
|
||||
#endif // ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
|
||||
void erase();
|
||||
|
||||
void render(float scale_factor = 1.0);
|
||||
|
@ -581,8 +581,12 @@ void LockButton::OnButton(wxCommandEvent& event)
|
||||
if (m_disabled)
|
||||
return;
|
||||
|
||||
#if ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
SetLock(!m_is_pushed);
|
||||
#else
|
||||
m_is_pushed = !m_is_pushed;
|
||||
update_button_bitmaps();
|
||||
#endif // ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user