mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-07-12 06:01:48 +08:00
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
Fixed conflicts during rebase with master
This commit is contained in:
parent
558bccec48
commit
622796e9e3
@ -1412,9 +1412,11 @@ void ModelObject::bake_xy_rotation_into_meshes(size_t instance_idx)
|
|||||||
assert(instance_idx < this->instances.size());
|
assert(instance_idx < this->instances.size());
|
||||||
|
|
||||||
const Geometry::Transformation reference_trafo = this->instances[instance_idx]->get_transformation();
|
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()))
|
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.
|
// nothing to do, scaling in the world coordinate space is possible in the representation of Geometry::Transformation.
|
||||||
return;
|
return;
|
||||||
|
#endif // !ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||||
|
|
||||||
bool left_handed = reference_trafo.is_left_handed();
|
bool left_handed = reference_trafo.is_left_handed();
|
||||||
bool has_mirrorring = ! reference_trafo.get_mirror().isApprox(Vec3d(1., 1., 1.));
|
bool has_mirrorring = ! reference_trafo.get_mirror().isApprox(Vec3d(1., 1., 1.));
|
||||||
|
@ -77,6 +77,8 @@
|
|||||||
#define ENABLE_COORDINATE_DEPENDENT_SELECTION_BOX (1 && ENABLE_WORLD_COORDINATE)
|
#define ENABLE_COORDINATE_DEPENDENT_SELECTION_BOX (1 && ENABLE_WORLD_COORDINATE)
|
||||||
// Enable showing the axes of the current reference system when sidebar hints are active
|
// Enable showing the axes of the current reference system when sidebar hints are active
|
||||||
#define ENABLE_WORLD_COORDINATE_SHOW_AXES (1 && ENABLE_WORLD_COORDINATE)
|
#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)
|
||||||
// Enable modified camera control using mouse
|
// Enable modified camera control using mouse
|
||||||
#define ENABLE_NEW_CAMERA_MOVEMENTS (1 && ENABLE_2_5_0_ALPHA1)
|
#define ENABLE_NEW_CAMERA_MOVEMENTS (1 && ENABLE_2_5_0_ALPHA1)
|
||||||
// Enable modified rectangle selection
|
// Enable modified rectangle selection
|
||||||
|
@ -627,9 +627,16 @@ void ObjectManipulation::update_settings_value(const Selection& selection)
|
|||||||
if (m_world_coordinates) {
|
if (m_world_coordinates) {
|
||||||
#endif // ENABLE_WORLD_COORDINATE
|
#endif // ENABLE_WORLD_COORDINATE
|
||||||
m_new_rotate_label_string = L("Rotate");
|
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_rotation = Vec3d::Zero();
|
||||||
m_new_size = selection.get_scaled_instance_bounding_box().size();
|
m_new_size = selection.get_scaled_instance_bounding_box().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(selection.get_unscaled_instance_bounding_box().size().cwiseInverse()) * 100.0;
|
m_new_scale = m_new_size.cwiseProduct(selection.get_unscaled_instance_bounding_box().size().cwiseInverse()) * 100.0;
|
||||||
|
#endif // ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#if ENABLE_WORLD_COORDINATE
|
#if ENABLE_WORLD_COORDINATE
|
||||||
@ -672,9 +679,16 @@ void ObjectManipulation::update_settings_value(const Selection& selection)
|
|||||||
|
|
||||||
m_new_position = offset;
|
m_new_position = offset;
|
||||||
m_new_rotate_label_string = L("Rotate");
|
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_rotation = Vec3d::Zero();
|
||||||
m_new_size = volume->transformed_convex_hull_bounding_box(trafo.get_matrix()).size();
|
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;
|
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()) {
|
else if (is_local_coordinates()) {
|
||||||
m_new_move_label_string = L("Translate");
|
m_new_move_label_string = L("Translate");
|
||||||
@ -687,10 +701,17 @@ void ObjectManipulation::update_settings_value(const Selection& selection)
|
|||||||
#endif // ENABLE_WORLD_COORDINATE
|
#endif // ENABLE_WORLD_COORDINATE
|
||||||
m_new_position = volume->get_volume_offset();
|
m_new_position = volume->get_volume_offset();
|
||||||
m_new_rotate_label_string = L("Rotate");
|
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_rotation = Vec3d::Zero();
|
||||||
#if ENABLE_WORLD_COORDINATE
|
#if ENABLE_WORLD_COORDINATE
|
||||||
m_new_size = volume->transformed_convex_hull_bounding_box(volume->get_volume_transformation().get_matrix()).size();
|
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;
|
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
|
#else
|
||||||
m_new_scale = volume->get_volume_scaling_factor() * 100.0;
|
m_new_scale = volume->get_volume_scaling_factor() * 100.0;
|
||||||
@ -767,20 +788,26 @@ void ObjectManipulation::update_if_dirty()
|
|||||||
#else
|
#else
|
||||||
if (selection.requires_uniform_scale()) {
|
if (selection.requires_uniform_scale()) {
|
||||||
#endif // ENABLE_WORLD_COORDINATE
|
#endif // ENABLE_WORLD_COORDINATE
|
||||||
|
#if !ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||||
m_lock_bnt->SetLock(true);
|
m_lock_bnt->SetLock(true);
|
||||||
|
#endif // !ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||||
#if ENABLE_WORLD_COORDINATE
|
#if ENABLE_WORLD_COORDINATE
|
||||||
wxString tooltip;
|
wxString tooltip;
|
||||||
if (selection.is_single_volume_or_modifier()) {
|
if (selection.is_single_volume_or_modifier()) {
|
||||||
|
#if !ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||||
if (reason == Selection::EUniformScaleRequiredReason::VolumeNotAxisAligned_Instance)
|
if (reason == Selection::EUniformScaleRequiredReason::VolumeNotAxisAligned_Instance)
|
||||||
tooltip = _L("You cannot use non-uniform scaling mode for parts non aligned with the instance local axes");
|
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)
|
else if (reason == Selection::EUniformScaleRequiredReason::VolumeNotAxisAligned_World)
|
||||||
tooltip = _L("You cannot use non-uniform scaling mode for parts non aligned with the printer axes");
|
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()) {
|
else if (selection.is_single_full_instance()) {
|
||||||
|
#if !ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||||
if (reason == Selection::EUniformScaleRequiredReason::InstanceNotAxisAligned_World)
|
if (reason == Selection::EUniformScaleRequiredReason::InstanceNotAxisAligned_World)
|
||||||
tooltip = _L("You cannot use non-uniform scaling mode for instances non aligned with the printer axes");
|
tooltip = _L("You cannot use non-uniform scaling mode for instances non aligned with the printer axes");
|
||||||
else if (reason == Selection::EUniformScaleRequiredReason::VolumeNotAxisAligned_Instance)
|
else if (reason == Selection::EUniformScaleRequiredReason::VolumeNotAxisAligned_Instance)
|
||||||
tooltip = _L("You cannot use non-uniform scaling mode for instances containing non locally axis-aligned parts");
|
tooltip = _L("You cannot use non-uniform scaling mode for instances containing non locally axis-aligned parts");
|
||||||
|
#endif // !ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
tooltip = _L("You cannot use non-uniform scaling mode for multiple objects/parts selection");
|
tooltip = _L("You cannot use non-uniform scaling mode for multiple objects/parts selection");
|
||||||
@ -789,7 +816,9 @@ void ObjectManipulation::update_if_dirty()
|
|||||||
#else
|
#else
|
||||||
m_lock_bnt->SetToolTip(_L("You cannot use non-uniform scaling mode for multiple objects/parts selection"));
|
m_lock_bnt->SetToolTip(_L("You cannot use non-uniform scaling mode for multiple objects/parts selection"));
|
||||||
#endif // ENABLE_WORLD_COORDINATE
|
#endif // ENABLE_WORLD_COORDINATE
|
||||||
|
#if !ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||||
m_lock_bnt->disable();
|
m_lock_bnt->disable();
|
||||||
|
#endif // !ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_lock_bnt->SetLock(m_uniform_scale);
|
m_lock_bnt->SetLock(m_uniform_scale);
|
||||||
@ -1108,7 +1137,11 @@ void ObjectManipulation::change_size_value(int axis, double value)
|
|||||||
selection.get_unscaled_instance_bounding_box().size() :
|
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();
|
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));
|
this->do_scale(axis, size.cwiseQuotient(ref_size));
|
||||||
|
#endif // ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||||
|
|
||||||
m_cache.size = size;
|
m_cache.size = size;
|
||||||
m_cache.size_rounded(axis) = DBL_MAX;
|
m_cache.size_rounded(axis) = DBL_MAX;
|
||||||
@ -1124,8 +1157,18 @@ void ObjectManipulation::do_scale(int axis, const Vec3d &scale) const
|
|||||||
|
|
||||||
#if ENABLE_WORLD_COORDINATE
|
#if ENABLE_WORLD_COORDINATE
|
||||||
TransformationType transformation_type;
|
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())
|
if (!is_world_coordinates())
|
||||||
transformation_type.set_local();
|
transformation_type.set_local();
|
||||||
|
#endif // ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||||
|
|
||||||
bool uniform_scale = m_uniform_scale || selection.requires_uniform_scale();
|
bool uniform_scale = m_uniform_scale || selection.requires_uniform_scale();
|
||||||
Vec3d scaling_factor = uniform_scale ? scale(axis) * Vec3d::Ones() : scale;
|
Vec3d scaling_factor = uniform_scale ? scale(axis) * Vec3d::Ones() : scale;
|
||||||
@ -1156,6 +1199,36 @@ void ObjectManipulation::do_scale(int axis, const Vec3d &scale) const
|
|||||||
wxGetApp().plater()->canvas3D()->do_scale(L("Set Scale"));
|
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.setup_cache();
|
||||||
|
selection.scale(scaling_factor, transformation_type);
|
||||||
|
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)
|
void ObjectManipulation::on_change(const std::string& opt_key, int axis, double new_value)
|
||||||
{
|
{
|
||||||
if (!m_cache.is_valid())
|
if (!m_cache.is_valid())
|
||||||
@ -1190,13 +1263,29 @@ 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();
|
const Selection &selection = wxGetApp().plater()->canvas3D()->get_selection();
|
||||||
#if ENABLE_WORLD_COORDINATE
|
#if ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||||
if (selection.is_single_full_instance() && is_world_coordinates() && !new_value) {
|
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
|
#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
|
#endif // ENABLE_WORLD_COORDINATE
|
||||||
// Verify whether the instance rotation is multiples of 90 degrees, so that the scaling in world coordinates is possible.
|
// 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
|
// all volumes in the selection belongs to the same instance, any of them contains the needed instance data, so we take the first one
|
||||||
@ -1226,7 +1315,9 @@ void ObjectManipulation::set_uniform_scaling(const bool new_value)
|
|||||||
this->UpdateAndShow(true);
|
this->UpdateAndShow(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_uniform_scale = new_value;
|
|
||||||
|
m_uniform_scale = use_uniform_scale;
|
||||||
|
#endif // ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLE_WORLD_COORDINATE
|
#if ENABLE_WORLD_COORDINATE
|
||||||
|
@ -196,7 +196,7 @@ public:
|
|||||||
// Called from the App to update the UI if dirty.
|
// Called from the App to update the UI if dirty.
|
||||||
void update_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; }
|
bool get_uniform_scaling() const { return m_uniform_scale; }
|
||||||
#if ENABLE_WORLD_COORDINATE
|
#if ENABLE_WORLD_COORDINATE
|
||||||
void set_coordinates_type(ECoordinatesType type);
|
void set_coordinates_type(ECoordinatesType type);
|
||||||
@ -256,6 +256,9 @@ private:
|
|||||||
void change_scale_value(int axis, double value);
|
void change_scale_value(int axis, double value);
|
||||||
void change_size_value(int axis, double value);
|
void change_size_value(int axis, double value);
|
||||||
void do_scale(int axis, const Vec3d &scale) const;
|
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
|
#if ENABLE_WORLD_COORDINATE
|
||||||
void set_coordinates_type(const wxString& type_string);
|
void set_coordinates_type(const wxString& type_string);
|
||||||
|
@ -69,6 +69,12 @@ public:
|
|||||||
const Vec3d& get_scale() const { return m_scale; }
|
const Vec3d& get_scale() const { return m_scale; }
|
||||||
void set_scale(const Vec3d& scale) { m_starting.scale = scale; m_scale = 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;
|
std::string get_tooltip() const override;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -7,9 +7,15 @@
|
|||||||
#include "GUI.hpp"
|
#include "GUI.hpp"
|
||||||
#include "GUI_ObjectManipulation.hpp"
|
#include "GUI_ObjectManipulation.hpp"
|
||||||
#include "GUI_ObjectList.hpp"
|
#include "GUI_ObjectList.hpp"
|
||||||
#include "Gizmos/GLGizmoBase.hpp"
|
|
||||||
#include "Camera.hpp"
|
#include "Camera.hpp"
|
||||||
#include "Plater.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 "slic3r/Utils/UndoRedo.hpp"
|
||||||
|
|
||||||
#include "libslic3r/LocalesUtils.hpp"
|
#include "libslic3r/LocalesUtils.hpp"
|
||||||
@ -604,6 +610,9 @@ bool Selection::requires_uniform_scale() const
|
|||||||
#endif // ENABLE_WORLD_COORDINATE
|
#endif // ENABLE_WORLD_COORDINATE
|
||||||
{
|
{
|
||||||
#if ENABLE_WORLD_COORDINATE
|
#if ENABLE_WORLD_COORDINATE
|
||||||
|
if (is_empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
ECoordinatesType coord_type = wxGetApp().obj_manipul()->get_coordinates_type();
|
ECoordinatesType coord_type = wxGetApp().obj_manipul()->get_coordinates_type();
|
||||||
if (is_single_volume_or_modifier()) {
|
if (is_single_volume_or_modifier()) {
|
||||||
if (coord_type == ECoordinatesType::World) {
|
if (coord_type == ECoordinatesType::World) {
|
||||||
@ -638,7 +647,6 @@ bool Selection::requires_uniform_scale() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (unsigned int i : m_list) {
|
for (unsigned int i : m_list) {
|
||||||
@ -648,8 +656,8 @@ bool Selection::requires_uniform_scale() const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reason != nullptr)
|
if (reason != nullptr)
|
||||||
@ -1302,6 +1310,65 @@ void Selection::translate(unsigned int object_idx, unsigned int instance_idx, co
|
|||||||
this->set_bounding_boxes_dirty();
|
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()
|
void Selection::erase()
|
||||||
{
|
{
|
||||||
if (!m_valid)
|
if (!m_valid)
|
||||||
|
@ -366,6 +366,15 @@ public:
|
|||||||
void translate(unsigned int object_idx, const Vec3d& displacement);
|
void translate(unsigned int object_idx, const Vec3d& displacement);
|
||||||
void translate(unsigned int object_idx, unsigned int instance_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 erase();
|
||||||
|
|
||||||
void render(float scale_factor = 1.0);
|
void render(float scale_factor = 1.0);
|
||||||
|
@ -581,8 +581,12 @@ void LockButton::OnButton(wxCommandEvent& event)
|
|||||||
if (m_disabled)
|
if (m_disabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#if ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||||
|
SetLock(!m_is_pushed);
|
||||||
|
#else
|
||||||
m_is_pushed = !m_is_pushed;
|
m_is_pushed = !m_is_pushed;
|
||||||
update_button_bitmaps();
|
update_button_bitmaps();
|
||||||
|
#endif // ENABLE_WORLD_COORDINATE_SCALE_REVISITED
|
||||||
|
|
||||||
event.Skip();
|
event.Skip();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user