Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorenricoturri1966 <enricoturri@seznam.cz>2022-05-11 11:54:42 +0300
committerenricoturri1966 <enricoturri@seznam.cz>2022-06-06 10:54:19 +0300
commit88ce6ccdef5f680709ea8b676688784a7af287dd (patch)
tree07b98235844e1369648e592a5886bb4abefdeddd
parentb5d366d385a8f0f9e44f08470ee1910051fcf0fa (diff)
Tech ENABLE_TRANSFORMATIONS_BY_MATRICES - Reworked method void Selection::scale(const Vec3d& scale, TransformationType transformation_type) to use matrix multiplication
Fixed conflicts during rebase with master
-rw-r--r--src/libslic3r/Geometry.cpp32
-rw-r--r--src/libslic3r/Geometry.hpp12
-rw-r--r--src/slic3r/GUI/GLCanvas3D.cpp31
-rw-r--r--src/slic3r/GUI/GUI_ObjectManipulation.cpp40
-rw-r--r--src/slic3r/GUI/Gizmos/GLGizmoBase.cpp35
-rw-r--r--src/slic3r/GUI/Gizmos/GLGizmoBase.hpp5
-rw-r--r--src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp2
-rw-r--r--src/slic3r/GUI/Gizmos/GLGizmoMove.cpp12
-rw-r--r--src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp2
-rw-r--r--src/slic3r/GUI/Gizmos/GLGizmoScale.cpp154
-rw-r--r--src/slic3r/GUI/Gizmos/GLGizmoScale.hpp4
-rw-r--r--src/slic3r/GUI/Plater.cpp2
-rw-r--r--src/slic3r/GUI/Selection.cpp217
-rw-r--r--src/slic3r/GUI/Selection.hpp14
14 files changed, 464 insertions, 98 deletions
diff --git a/src/libslic3r/Geometry.cpp b/src/libslic3r/Geometry.cpp
index 031e489f7..61217f4a1 100644
--- a/src/libslic3r/Geometry.cpp
+++ b/src/libslic3r/Geometry.cpp
@@ -313,7 +313,6 @@ Transform3d assemble_transform(const Vec3d& translation, const Vec3d& rotation,
return transform;
}
-#if ENABLE_TRANSFORMATIONS_BY_MATRICES
void assemble_transform(Transform3d& transform, const Transform3d& translation, const Transform3d& rotation, const Transform3d& scale, const Transform3d& mirror)
{
transform = translation * rotation * scale * mirror;
@@ -326,6 +325,19 @@ Transform3d assemble_transform(const Transform3d& translation, const Transform3d
return transform;
}
+void translation_transform(Transform3d& transform, const Vec3d& translation)
+{
+ transform = Transform3d::Identity();
+ transform.translate(translation);
+}
+
+Transform3d translation_transform(const Vec3d& translation)
+{
+ Transform3d transform;
+ translation_transform(transform, translation);
+ return transform;
+}
+
void rotation_transform(Transform3d& transform, const Vec3d& rotation)
{
transform = Transform3d::Identity();
@@ -351,7 +363,6 @@ Transform3d scale_transform(const Vec3d& scale)
scale_transform(transform, scale);
return transform;
}
-#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
Vec3d extract_euler_angles(const Eigen::Matrix<double, 3, 3, Eigen::DontAlign>& rotation_matrix)
{
@@ -433,6 +444,14 @@ static std::pair<Transform3d, Transform3d> extract_rotation_scale(const Transfor
return { Transform3d(rotation), Transform3d(scale) };
}
+static bool contains_skew(const Transform3d& trafo)
+{
+ Matrix3d rotation;
+ Matrix3d scale;
+ trafo.computeRotationScaling(&rotation, &scale);
+ return !scale.isDiagonal();
+}
+
Vec3d Transformation::get_rotation() const
{
return extract_euler_angles(extract_rotation(m_matrix));
@@ -623,7 +642,12 @@ void Transformation::set_mirror(Axis axis, double mirror)
#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
}
-#if !ENABLE_TRANSFORMATIONS_BY_MATRICES
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+bool Transformation::has_skew() const
+{
+ return contains_skew(m_matrix);
+}
+#else
void Transformation::set_from_transform(const Transform3d& transform)
{
// offset
@@ -661,7 +685,7 @@ void Transformation::set_from_transform(const Transform3d& transform)
// if (!m_matrix.isApprox(transform))
// std::cout << "something went wrong in extracting data from matrix" << std::endl;
}
-#endif // !ENABLE_TRANSFORMATIONS_BY_MATRICES
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
void Transformation::reset()
{
diff --git a/src/libslic3r/Geometry.hpp b/src/libslic3r/Geometry.hpp
index c55867023..bbca3a5e3 100644
--- a/src/libslic3r/Geometry.hpp
+++ b/src/libslic3r/Geometry.hpp
@@ -336,7 +336,6 @@ void assemble_transform(Transform3d& transform, const Vec3d& translation = Vec3d
Transform3d assemble_transform(const Vec3d& translation = Vec3d::Zero(), const Vec3d& rotation = Vec3d::Zero(),
const Vec3d& scale = Vec3d::Ones(), const Vec3d& mirror = Vec3d::Ones());
-#if ENABLE_TRANSFORMATIONS_BY_MATRICES
// Sets the given transform by multiplying the given transformations in the following order:
// T = translation * rotation * scale * mirror
void assemble_transform(Transform3d& transform, const Transform3d& translation = Transform3d::Identity(),
@@ -348,6 +347,12 @@ void assemble_transform(Transform3d& transform, const Transform3d& translation =
Transform3d assemble_transform(const Transform3d& translation = Transform3d::Identity(), const Transform3d& rotation = Transform3d::Identity(),
const Transform3d& scale = Transform3d::Identity(), const Transform3d& mirror = Transform3d::Identity());
+// Sets the given transform by assembling the given translation
+void translation_transform(Transform3d& transform, const Vec3d& translation);
+
+// Returns the transform obtained by assembling the given translation
+Transform3d translation_transform(const Vec3d& translation);
+
// Sets the given transform by assembling the given rotations in the following order:
// 1) rotate X
// 2) rotate Y
@@ -365,7 +370,6 @@ void scale_transform(Transform3d& transform, const Vec3d& scale);
// Returns the transform obtained by assembling the given scale factors
Transform3d scale_transform(const Vec3d& scale);
-#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
// Returns the euler angles extracted from the given rotation matrix
// Warning -> The matrix should not contain any scale or shear !!!
@@ -478,6 +482,10 @@ public:
void set_mirror(const Vec3d& mirror);
void set_mirror(Axis axis, double mirror);
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ bool has_skew() const;
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
+
#if !ENABLE_TRANSFORMATIONS_BY_MATRICES
void set_from_transform(const Transform3d& transform);
#endif // !ENABLE_TRANSFORMATIONS_BY_MATRICES
diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp
index f3ba04c50..8a2599866 100644
--- a/src/slic3r/GUI/GLCanvas3D.cpp
+++ b/src/slic3r/GUI/GLCanvas3D.cpp
@@ -2914,7 +2914,13 @@ void GLCanvas3D::on_key(wxKeyEvent& evt)
else
displacement = multiplier * direction;
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ TransformationType trafo_type;
+ trafo_type.set_relative();
+ m_selection.translate(displacement, trafo_type);
+#else
m_selection.translate(displacement);
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
m_dirty = true;
}
);
@@ -3579,7 +3585,13 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
}
}
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ TransformationType trafo_type;
+ trafo_type.set_relative();
+ m_selection.translate(cur_pos - m_mouse.drag.start_position_3D, trafo_type);
+#else
m_selection.translate(cur_pos - m_mouse.drag.start_position_3D);
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
if (current_printer_technology() == ptFFF && fff_print()->config().complete_objects)
update_sequential_clearance();
wxGetApp().obj_manipul()->set_dirty();
@@ -3996,12 +4008,12 @@ void GLCanvas3D::do_scale(const std::string& snapshot_type)
Selection::EMode selection_mode = m_selection.get_mode();
for (const GLVolume* v : m_volumes.volumes) {
- int object_idx = v->object_idx();
+ const int object_idx = v->object_idx();
if (object_idx < 0 || (int)m_model->objects.size() <= object_idx)
continue;
- int instance_idx = v->instance_idx();
- int volume_idx = v->volume_idx();
+ const int instance_idx = v->instance_idx();
+ const int volume_idx = v->volume_idx();
done.insert(std::pair<int, int>(object_idx, instance_idx));
@@ -4009,13 +4021,22 @@ void GLCanvas3D::do_scale(const std::string& snapshot_type)
ModelObject* model_object = m_model->objects[object_idx];
if (model_object != nullptr) {
if (selection_mode == Selection::Instance) {
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation());
+#else
model_object->instances[instance_idx]->set_scaling_factor(v->get_instance_scaling_factor());
model_object->instances[instance_idx]->set_offset(v->get_instance_offset());
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
}
else if (selection_mode == Selection::Volume) {
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation());
+ model_object->volumes[volume_idx]->set_transformation(v->get_volume_transformation());
+#else
model_object->instances[instance_idx]->set_offset(v->get_instance_offset());
model_object->volumes[volume_idx]->set_scaling_factor(v->get_volume_scaling_factor());
model_object->volumes[volume_idx]->set_offset(v->get_volume_offset());
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
}
model_object->invalidate_bounding_box();
}
@@ -4024,10 +4045,10 @@ void GLCanvas3D::do_scale(const std::string& snapshot_type)
// Fixes sinking/flying instances
for (const std::pair<int, int>& i : done) {
ModelObject* m = m_model->objects[i.first];
- double shift_z = m->get_instance_min_z(i.second);
+ const double shift_z = m->get_instance_min_z(i.second);
// leave sinking instances as sinking
if (min_zs.empty() || min_zs.find({ i.first, i.second })->second >= SINKING_Z_THRESHOLD || shift_z > SINKING_Z_THRESHOLD) {
- Vec3d shift(0.0, 0.0, -shift_z);
+ const Vec3d shift(0.0, 0.0, -shift_z);
m_selection.translate(i.first, i.second, shift);
m->translate_instance(i.second, shift);
}
diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp
index 9b892eb53..871c90c51 100644
--- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp
+++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp
@@ -461,9 +461,16 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
m_reset_scale_button->SetToolTip(_L("Reset scale"));
m_reset_scale_button->Bind(wxEVT_BUTTON, [this](wxCommandEvent& e) {
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Reset scale"));
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ bool old_uniform = m_uniform_scale;
+ m_uniform_scale = true;
+ change_scale_value(0, 100.0);
+ m_uniform_scale = old_uniform;
+#else
change_scale_value(0, 100.);
change_scale_value(1, 100.);
change_scale_value(2, 100.);
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
});
editors_grid_sizer->Add(m_reset_scale_button);
@@ -616,6 +623,7 @@ void ObjectManipulation::update_settings_value(const Selection& selection)
m_new_position = volume->get_instance_offset();
#endif // !ENABLE_WORLD_COORDINATE
+#if !ENABLE_TRANSFORMATIONS_BY_MATRICES
// Verify whether the instance rotation is multiples of 90 degrees, so that the scaling in world coordinates is possible.
#if ENABLE_WORLD_COORDINATE
if (is_world_coordinates() && !m_uniform_scale &&
@@ -627,6 +635,7 @@ void ObjectManipulation::update_settings_value(const Selection& selection)
m_uniform_scale = true;
m_lock_bnt->SetLock(true);
}
+#endif // !ENABLE_TRANSFORMATIONS_BY_MATRICES
#if ENABLE_WORLD_COORDINATE
if (is_world_coordinates()) {
@@ -790,6 +799,7 @@ void ObjectManipulation::update_if_dirty()
update(m_cache.rotation, m_cache.rotation_rounded, meRotation, m_new_rotation);
}
+#if !ENABLE_TRANSFORMATIONS_BY_MATRICES
#if ENABLE_WORLD_COORDINATE
Selection::EUniformScaleRequiredReason reason;
if (selection.requires_uniform_scale(&reason)) {
@@ -829,10 +839,13 @@ void ObjectManipulation::update_if_dirty()
#endif // !ENABLE_WORLD_COORDINATE_SCALE_REVISITED
}
else {
+#endif // !ENABLE_TRANSFORMATIONS_BY_MATRICES
m_lock_bnt->SetLock(m_uniform_scale);
m_lock_bnt->SetToolTip(wxEmptyString);
m_lock_bnt->enable();
+#if !ENABLE_TRANSFORMATIONS_BY_MATRICES
}
+#endif // !ENABLE_TRANSFORMATIONS_BY_MATRICES
#if !ENABLE_WORLD_COORDINATE
{
@@ -1048,7 +1061,19 @@ void ObjectManipulation::change_position_value(int axis, double value)
Selection& selection = canvas->get_selection();
selection.setup_cache();
#if ENABLE_WORLD_COORDINATE
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ TransformationType trafo_type;
+ trafo_type.set_relative();
+ switch (get_coordinates_type())
+ {
+ case ECoordinatesType::Instance: { trafo_type.set_instance(); break; }
+ case ECoordinatesType::Local: { trafo_type.set_local(); break; }
+ default: { break; }
+ }
+ selection.translate(position - m_cache.position, trafo_type);
+#else
selection.translate(position - m_cache.position, get_coordinates_type());
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
#else
selection.translate(position - m_cache.position, selection.requires_local_axes());
#endif // ENABLE_WORLD_COORDINATE
@@ -1191,6 +1216,9 @@ void ObjectManipulation::do_scale(int axis, const Vec3d &scale) const
transformation_type.set_local();
#endif // ENABLE_WORLD_COORDINATE_SCALE_REVISITED
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ Vec3d scaling_factor = m_uniform_scale ? scale(axis) * Vec3d::Ones() : scale;
+#else
bool uniform_scale = m_uniform_scale || selection.requires_uniform_scale();
Vec3d scaling_factor = uniform_scale ? scale(axis) * Vec3d::Ones() : scale;
@@ -1203,6 +1231,7 @@ void ObjectManipulation::do_scale(int axis, const Vec3d &scale) const
scaling_factor = (mv * mi * scaling_factor).cwiseAbs();
}
}
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
#else
TransformationType transformation_type(TransformationType::World_Relative_Joint);
if (selection.is_single_full_instance()) {
@@ -1231,6 +1260,12 @@ void ObjectManipulation::do_size(int axis, const Vec3d& scale) const
else if (is_instance_coordinates())
transformation_type.set_instance();
+ if (!is_local_coordinates())
+ transformation_type.set_relative();
+
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ Vec3d scaling_factor = m_uniform_scale ? scale(axis) * Vec3d::Ones() : scale;
+#else
bool uniform_scale = m_uniform_scale || selection.requires_uniform_scale();
Vec3d scaling_factor = uniform_scale ? scale(axis) * Vec3d::Ones() : scale;
@@ -1243,6 +1278,7 @@ void ObjectManipulation::do_size(int axis, const Vec3d& scale) const
scaling_factor = (mv * mi * scaling_factor).cwiseAbs();
}
}
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
selection.setup_cache();
selection.scale(scaling_factor, transformation_type);
@@ -1303,6 +1339,10 @@ void ObjectManipulation::set_uniform_scaling(const bool use_uniform_scale)
}
m_uniform_scale = use_uniform_scale;
+
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ set_dirty();
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
#else
#if ENABLE_WORLD_COORDINATE
if (selection.is_single_full_instance() && is_world_coordinates() && !use_uniform_scale) {
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp
index 1e0ff6c9e..bee57ec6e 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp
@@ -333,7 +333,11 @@ bool GLGizmoBase::use_grabbers(const wxMouseEvent &mouse_event) {
wxGetApp().obj_manipul()->set_dirty();
m_parent.set_as_dirty();
return true;
- } else if (mouse_event.LeftUp() || is_leaving || is_dragging_finished) {
+ }
+ else if (mouse_event.LeftUp() || is_leaving || is_dragging_finished) {
+#if ENABLE_WORLD_COORDINATE_SCALE_REVISITED
+ do_stop_dragging(is_leaving);
+#else
for (auto &grabber : m_grabbers) grabber.dragging = false;
m_dragging = false;
@@ -356,12 +360,41 @@ bool GLGizmoBase::use_grabbers(const wxMouseEvent &mouse_event) {
m_parent.post_event(SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED));
// updates camera target constraints
m_parent.refresh_camera_scene_box();
+#endif // ENABLE_WORLD_COORDINATE_SCALE_REVISITED
return true;
}
}
return false;
}
+#if ENABLE_WORLD_COORDINATE_SCALE_REVISITED
+void GLGizmoBase::do_stop_dragging(bool perform_mouse_cleanup)
+{
+ for (auto& grabber : m_grabbers) grabber.dragging = false;
+ m_dragging = false;
+
+ // NOTE: This should be part of GLCanvas3D
+ // Reset hover_id when leave window
+ if (perform_mouse_cleanup) m_parent.mouse_up_cleanup();
+
+ on_stop_dragging();
+
+ // There is prediction that after draggign, data are changed
+ // Data are updated twice also by canvas3D::reload_scene.
+ // Should be fixed.
+ m_parent.get_gizmos_manager().update_data();
+
+ wxGetApp().obj_manipul()->set_dirty();
+
+ // Let the plater know that the dragging finished, so a delayed
+ // refresh of the scene with the background processing data should
+ // be performed.
+ m_parent.post_event(SimpleEvent(EVT_GLCANVAS_MOUSE_DRAGGING_FINISHED));
+ // updates camera target constraints
+ m_parent.refresh_camera_scene_box();
+}
+#endif // ENABLE_WORLD_COORDINATE_SCALE_REVISITED
+
std::string GLGizmoBase::format(float value, unsigned int decimals) const
{
return Slic3r::string_printf("%.*f", decimals, value);
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp
index f61654183..fff699479 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp
@@ -227,6 +227,11 @@ protected:
/// <param name="mouse_event">Keep information about mouse click</param>
/// <returns>same as on_mouse</returns>
bool use_grabbers(const wxMouseEvent &mouse_event);
+
+#if ENABLE_WORLD_COORDINATE
+ void do_stop_dragging(bool perform_mouse_cleanup);
+#endif // ENABLE_WORLD_COORDINATE
+
private:
// Flag for dirty visible state of Gizmo
// When True then need new rendering
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp
index 15030a0fa..8ef23d538 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp
@@ -126,7 +126,7 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking)
#else
const Transform3d instance_scaling_matrix_inverse = vol->get_instance_transformation().get_matrix(true, true, false, true).inverse();
#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
- const Transform3d instance_matrix = Geometry::assemble_transform(m_c->selection_info()->get_sla_shift() * Vec3d::UnitZ()) * trafo.get_matrix();
+ const Transform3d instance_matrix = Geometry::translation_transform(m_c->selection_info()->get_sla_shift() * Vec3d::UnitZ()) * trafo.get_matrix();
const Camera& camera = wxGetApp().plater()->get_camera();
const Transform3d& view_matrix = camera.get_view_matrix();
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp
index afb0b9140..19422e167 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp
@@ -141,7 +141,19 @@ void GLGizmoMove3D::on_dragging(const UpdateData& data)
Selection &selection = m_parent.get_selection();
#if ENABLE_WORLD_COORDINATE
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ TransformationType trafo_type;
+ trafo_type.set_relative();
+ switch (wxGetApp().obj_manipul()->get_coordinates_type())
+ {
+ case ECoordinatesType::Instance: { trafo_type.set_instance(); break; }
+ case ECoordinatesType::Local: { trafo_type.set_local(); break; }
+ default: { break; }
+ }
+ selection.translate(m_displacement, trafo_type);
+#else
selection.translate(m_displacement, wxGetApp().obj_manipul()->get_coordinates_type());
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
#else
selection.translate(m_displacement);
#endif // ENABLE_WORLD_COORDINATE
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp
index a89173460..b72c6761f 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp
@@ -787,7 +787,7 @@ Transform3d GLGizmoRotate::local_transform(const Selection& selection) const
}
#if ENABLE_WORLD_COORDINATE
- return Geometry::assemble_transform(m_center) * m_orient_matrix * ret;
+ return Geometry::translation_transform(m_center) * m_orient_matrix * ret;
#else
if (selection.is_single_volume() || selection.is_single_modifier() || selection.requires_local_axes())
ret = selection.get_first_volume()->get_instance_transformation().get_matrix(true, false, true, true) * ret;
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp
index 061361e40..af5b3adb2 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp
@@ -41,6 +41,9 @@ GLGizmoScale3D::GLGizmoScale3D(GLCanvas3D& parent, const std::string& icon_filen
std::string GLGizmoScale3D::get_tooltip() const
{
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ const Vec3d scale = 100.0 * m_scale;
+#else
const Selection& selection = m_parent.get_selection();
Vec3d scale = 100.0 * Vec3d::Ones();
@@ -52,6 +55,7 @@ std::string GLGizmoScale3D::get_tooltip() const
else if (selection.is_single_modifier() || selection.is_single_volume())
#endif // ENABLE_WORLD_COORDINATE
scale = 100.0 * selection.get_first_volume()->get_volume_scaling_factor();
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
if (m_hover_id == 0 || m_hover_id == 1 || m_grabbers[0].dragging || m_grabbers[1].dragging)
return "X: " + format(scale.x(), 4) + "%";
@@ -89,32 +93,65 @@ bool GLGizmoScale3D::on_mouse(const wxMouseEvent &mouse_event)
#endif // ENABLE_WORLD_COORDINATE_SCALE_REVISITED
#endif // !ENABLE_TRANSFORMATIONS_BY_MATRICES
// Apply new temporary scale factors
- TransformationType transformation_type(TransformationType::Local_Absolute_Joint);
- if (mouse_event.AltDown()) transformation_type.set_independent();
+#if ENABLE_WORLD_COORDINATE
+ TransformationType transformation_type;
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ if (wxGetApp().obj_manipul()->is_local_coordinates())
+ transformation_type.set_local();
+ else if (wxGetApp().obj_manipul()->is_instance_coordinates())
+ transformation_type.set_instance();
+
+ transformation_type.set_relative();
+#else
+ if (!wxGetApp().obj_manipul()->is_world_coordinates())
+ transformation_type.set_local();
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
+#else
+ TransformationType transformation_type(TransformationType::Local_Absolute_Joint);
+#endif // ENABLE_WORLD_COORDINATE
+ if (mouse_event.AltDown()) transformation_type.set_independent();
- Selection &selection = m_parent.get_selection();
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ m_parent.get_selection().scale_and_translate(m_scale, m_offset, transformation_type);
+#else
+ Selection& selection = m_parent.get_selection();
selection.scale(m_scale, transformation_type);
#if ENABLE_WORLD_COORDINATE
if (mouse_event.CmdDown()) selection.translate(m_offset, wxGetApp().obj_manipul()->get_coordinates_type());
#else
if (mouse_event.CmdDown()) selection.translate(m_offset, true);
#endif // ENABLE_WORLD_COORDINATE
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
#if !ENABLE_TRANSFORMATIONS_BY_MATRICES
#if ENABLE_WORLD_COORDINATE_SCALE_REVISITED
}
#endif // ENABLE_WORLD_COORDINATE_SCALE_REVISITED
#endif // !ENABLE_TRANSFORMATIONS_BY_MATRICES
- }
+ }
}
return use_grabbers(mouse_event);
}
void GLGizmoScale3D::data_changed()
{
- const Selection &selection = m_parent.get_selection();
+#if !ENABLE_TRANSFORMATIONS_BY_MATRICES
+ const Selection &selection = m_parent.get_selection();
+#endif // !ENABLE_TRANSFORMATIONS_BY_MATRICES
+#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_TRANSFORMATIONS_BY_MATRICES
+ set_scale(Vec3d::Ones());
+#else
+#if ENABLE_WORLD_COORDINATE_SCALE_REVISITED
+ if (selection.is_single_full_instance() || selection.is_single_volume_or_modifier()) {
+#else
for (unsigned int i = 0; i < 6; ++i)
m_grabbers[i].enabled = enable_scale_xyz;
@@ -129,6 +166,8 @@ void GLGizmoScale3D::data_changed()
}
else
set_scale(Vec3d::Ones());
+#endif // ENABLE_WORLD_COORDINATE_SCALE_REVISITED
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
}
bool GLGizmoScale3D::on_init()
@@ -251,7 +290,7 @@ void GLGizmoScale3D::on_render()
#if ENABLE_WORLD_COORDINATE
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
const Transform3d inst_trafo = v.get_instance_transformation().get_matrix_no_scaling_factor();
- m_grabbers_transform = inst_trafo * Geometry::assemble_transform(m_bounding_box.center());
+ m_grabbers_transform = inst_trafo * Geometry::translation_transform(m_bounding_box.center());
m_center = inst_trafo * m_bounding_box.center();
#else
m_grabbers_transform = v.get_instance_transformation().get_matrix(false, false, true) * Geometry::assemble_transform(m_bounding_box.center());
@@ -677,6 +716,58 @@ void GLGizmoScale3D::render_grabbers_connection(unsigned int id_1, unsigned int
}
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+void GLGizmoScale3D::do_scale_along_axis(Axis axis, const UpdateData& data)
+{
+ double ratio = calc_ratio(data);
+ if (ratio > 0.0) {
+ Vec3d curr_scale = m_scale;
+ Vec3d starting_scale = m_starting.scale;
+ const Selection& selection = m_parent.get_selection();
+ const ECoordinatesType coordinates_type = wxGetApp().obj_manipul()->get_coordinates_type();
+
+ curr_scale(axis) = starting_scale(axis) * ratio;
+ m_scale = curr_scale;
+
+ if (m_starting.ctrl_down && (selection.is_single_full_instance() || selection.is_single_volume_or_modifier())) {
+ double local_offset = 0.5 * (ratio - 1.0) * m_starting.box.size()(axis);
+
+ if (m_hover_id == 2 * axis)
+ local_offset *= -1.0;
+
+ Vec3d center_offset = m_starting.instance_center - m_starting.center; // world coordinates (== Vec3d::Zero() for single volume selection)
+ if (selection.is_single_full_instance() && coordinates_type == ECoordinatesType::Local)
+ // from world coordinates to instance coordinates
+ center_offset = selection.get_first_volume()->get_instance_transformation().get_rotation_matrix().inverse() * center_offset;
+
+ local_offset += (ratio - 1.0) * center_offset(axis);
+
+ switch (axis)
+ {
+ case X: { m_offset = local_offset * Vec3d::UnitX(); break; }
+ case Y: { m_offset = local_offset * Vec3d::UnitY(); break; }
+ case Z: { m_offset = local_offset * Vec3d::UnitZ(); break; }
+ default: { m_offset = Vec3d::Zero(); break; }
+ }
+
+ if (selection.is_single_full_instance() && coordinates_type == ECoordinatesType::Local)
+ // from instance coordinates to world coordinates
+ m_offset = selection.get_first_volume()->get_instance_transformation().get_rotation_matrix() * m_offset;
+
+ if (selection.is_single_volume_or_modifier()) {
+ if (coordinates_type == ECoordinatesType::Instance)
+ m_offset = selection.get_first_volume()->get_instance_transformation().get_scaling_factor_matrix().inverse() * m_offset;
+ else if (coordinates_type == ECoordinatesType::Local) {
+ m_offset = selection.get_first_volume()->get_instance_transformation().get_scaling_factor_matrix().inverse() *
+ selection.get_first_volume()->get_volume_transformation().get_rotation_matrix() * m_offset;
+ }
+ }
+ }
+ else
+ m_offset = Vec3d::Zero();
+ }
+}
+#else
void GLGizmoScale3D::do_scale_along_axis(Axis axis, const UpdateData& data)
{
#if ENABLE_WORLD_COORDINATE
@@ -721,6 +812,7 @@ void GLGizmoScale3D::do_scale_along_axis(Axis axis, const UpdateData& data)
if (ratio > 0.0) {
m_scale(axis) = m_starting.scale(axis) * ratio;
#endif // ENABLE_WORLD_COORDINATE
+
if (m_starting.ctrl_down) {
#if ENABLE_WORLD_COORDINATE
double local_offset = 0.5 * (ratio - 1.0) * m_starting.box.size()(axis);
@@ -734,7 +826,7 @@ void GLGizmoScale3D::do_scale_along_axis(Axis axis, const UpdateData& data)
#if ENABLE_WORLD_COORDINATE
Vec3d center_offset = m_starting.instance_center - m_starting.center;
if (selection.is_single_full_instance() && coordinates_type != ECoordinatesType::World) {
- const Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), selection.get_first_volume()->get_instance_rotation()).inverse();
+ const Transform3d m = Geometry::rotation_transform(selection.get_first_volume()->get_instance_rotation()).inverse();
center_offset = m * center_offset;
}
@@ -764,12 +856,57 @@ void GLGizmoScale3D::do_scale_along_axis(Axis axis, const UpdateData& data)
m_offset = Vec3d::Zero();
}
}
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
+
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+void GLGizmoScale3D::do_scale_uniform(const UpdateData & data)
+{
+ const double ratio = calc_ratio(data);
+ if (ratio > 0.0) {
+ m_scale = m_starting.scale * ratio;
+ const Selection& selection = m_parent.get_selection();
+ const ECoordinatesType coordinates_type = wxGetApp().obj_manipul()->get_coordinates_type();
+ if (m_starting.ctrl_down && (selection.is_single_full_instance() || selection.is_single_volume_or_modifier())) {
+ m_offset = 0.5 * (ratio - 1.0) * m_starting.box.size();
+
+ if (m_hover_id == 6 || m_hover_id == 9)
+ m_offset.x() *= -1.0;
+ if (m_hover_id == 6 || m_hover_id == 7)
+ m_offset.y() *= -1.0;
+
+ Vec3d center_offset = m_starting.instance_center - m_starting.center; // world coordinates (== Vec3d::Zero() for single volume selection)
+
+ if (selection.is_single_full_instance() && coordinates_type == ECoordinatesType::Local)
+ // from world coordinates to instance coordinates
+ center_offset = selection.get_first_volume()->get_instance_transformation().get_rotation_matrix().inverse() * center_offset;
+
+ m_offset += (ratio - 1.0) * center_offset;
+
+ if (selection.is_single_full_instance() && coordinates_type == ECoordinatesType::Local)
+ // from instance coordinates to world coordinates
+ m_offset = selection.get_first_volume()->get_instance_transformation().get_rotation_matrix() * m_offset;
+
+ if (selection.is_single_volume_or_modifier()) {
+ if (coordinates_type == ECoordinatesType::Instance)
+ m_offset = selection.get_first_volume()->get_instance_transformation().get_scaling_factor_matrix().inverse() * m_offset;
+ else if (coordinates_type == ECoordinatesType::Local) {
+ m_offset = selection.get_first_volume()->get_instance_transformation().get_scaling_factor_matrix().inverse() *
+ selection.get_first_volume()->get_volume_transformation().get_rotation_matrix() * m_offset;
+ }
+ }
+ }
+ else
+ m_offset = Vec3d::Zero();
+ }
+}
+#else
void GLGizmoScale3D::do_scale_uniform(const UpdateData& data)
{
const double ratio = calc_ratio(data);
if (ratio > 0.0) {
m_scale = m_starting.scale * ratio;
+
#if ENABLE_WORLD_COORDINATE
if (m_starting.ctrl_down) {
m_offset = 0.5 * (ratio - 1.0) * m_starting.box.size();
@@ -783,7 +920,7 @@ void GLGizmoScale3D::do_scale_uniform(const UpdateData& data)
Vec3d center_offset = m_starting.instance_center - m_starting.center;
if (selection.is_single_full_instance() && !wxGetApp().obj_manipul()->is_world_coordinates()) {
- const Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), selection.get_first_volume()->get_instance_rotation()).inverse();
+ const Transform3d m = Geometry::rotation_transform(selection.get_first_volume()->get_instance_rotation()).inverse();
center_offset = m * center_offset;
}
@@ -794,6 +931,7 @@ void GLGizmoScale3D::do_scale_uniform(const UpdateData& data)
m_offset = Vec3d::Zero();
}
}
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
double GLGizmoScale3D::calc_ratio(const UpdateData& data) const
{
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp b/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp
index b8001d7a9..754b588b4 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp
@@ -67,7 +67,11 @@ public:
void set_snap_step(double step) { m_snap_step = step; }
const Vec3d& get_scale() const { return m_scale; }
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ void set_scale(const Vec3d& scale) { m_starting.scale = scale; m_scale = scale; m_offset = Vec3d::Zero(); }
+#else
void set_scale(const Vec3d& scale) { m_starting.scale = scale; m_scale = scale; }
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
#if ENABLE_WORLD_COORDINATE_SCALE_REVISITED
const Vec3d& get_starting_scale() const { return m_starting.scale; }
diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp
index e50676ee1..c7ddf8f78 100644
--- a/src/slic3r/GUI/Plater.cpp
+++ b/src/slic3r/GUI/Plater.cpp
@@ -3852,7 +3852,7 @@ void Plater::priv::reload_from_disk()
new_volume->set_type(old_volume->type());
new_volume->set_material_id(old_volume->material_id());
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
- new_volume->set_transformation(Geometry::assemble_transform(old_volume->source.transform.get_offset()) *
+ new_volume->set_transformation(Geometry::translation_transform(old_volume->source.transform.get_offset()) *
old_volume->get_transformation().get_matrix_no_offset() * old_volume->source.transform.get_matrix_no_offset());
new_volume->translate(new_volume->get_transformation().get_matrix_no_offset() * (new_volume->source.mesh_offset - old_volume->source.mesh_offset));
#else
diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp
index a3bf2bf7b..33ecd2412 100644
--- a/src/slic3r/GUI/Selection.cpp
+++ b/src/slic3r/GUI/Selection.cpp
@@ -599,6 +599,7 @@ bool Selection::matches(const std::vector<unsigned int>& volume_idxs) const
return count == (unsigned int)m_list.size();
}
+#if !ENABLE_TRANSFORMATIONS_BY_MATRICES
#if ENABLE_WORLD_COORDINATE
bool Selection::requires_uniform_scale(EUniformScaleRequiredReason* reason) const
#else
@@ -667,6 +668,7 @@ bool Selection::requires_uniform_scale() const
return true;
#endif // ENABLE_WORLD_COORDINATE
}
+#endif // !ENABLE_TRANSFORMATIONS_BY_MATRICES
int Selection::get_object_idx() const
{
@@ -760,58 +762,29 @@ void Selection::setup_cache()
}
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
-void Selection::translate(const Vec3d& displacement, ECoordinatesType type)
+void Selection::translate(const Vec3d& displacement, TransformationType transformation_type)
{
if (!m_valid)
return;
+ assert(transformation_type.relative());
+
for (unsigned int i : m_list) {
GLVolume& v = *(*m_volumes)[i];
const VolumeCache& volume_data = m_cache.volumes_data[i];
if (m_mode == Instance && !is_wipe_tower()) {
assert(is_from_fully_selected_instance(i));
- switch (type)
- {
- case ECoordinatesType::World:
- {
- v.set_instance_transformation(Geometry::assemble_transform(displacement) * volume_data.get_instance_full_matrix());
- break;
- }
- case ECoordinatesType::Local:
- {
- const Vec3d world_displacemet = volume_data.get_instance_rotation_matrix() * displacement;
- v.set_instance_transformation(Geometry::assemble_transform(world_displacemet) * volume_data.get_instance_full_matrix());
- break;
- }
- default: { assert(false); break; }
- }
- }
- else {
- switch (type)
- {
- case ECoordinatesType::World:
- {
- const Transform3d inst_matrix_no_offset = volume_data.get_instance_rotation_matrix() * volume_data.get_instance_scale_matrix();
- const Vec3d inst_displacement = inst_matrix_no_offset.inverse() * displacement;
- v.set_volume_transformation(Geometry::assemble_transform(inst_displacement) * volume_data.get_volume_full_matrix());
- break;
- }
- case ECoordinatesType::Instance:
- {
- const Vec3d inst_displacement = volume_data.get_instance_scale_matrix().inverse() * displacement;
- v.set_volume_transformation(Geometry::assemble_transform(inst_displacement) * volume_data.get_volume_full_matrix());
- break;
- }
- case ECoordinatesType::Local:
- {
- const Vec3d inst_displacement = volume_data.get_instance_scale_matrix().inverse() *
- volume_data.get_volume_rotation_matrix() * displacement;
- v.set_volume_transformation(Geometry::assemble_transform(inst_displacement) * volume_data.get_volume_full_matrix());
- break;
- }
- default: { assert(false); break; }
+ if (transformation_type.world())
+ v.set_instance_transformation(Geometry::translation_transform(displacement) * volume_data.get_instance_full_matrix());
+ else if (transformation_type.local()) {
+ const Vec3d world_displacement = volume_data.get_instance_rotation_matrix() * displacement;
+ v.set_instance_transformation(Geometry::translation_transform(world_displacement) * volume_data.get_instance_full_matrix());
}
+ else
+ assert(false);
}
+ else
+ transform_volume_relative(v, volume_data, transformation_type, Geometry::translation_transform(displacement));
}
#if !DISABLE_INSTANCES_SYNCH
@@ -914,51 +887,35 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_
for (unsigned int i : m_list) {
GLVolume& v = *(*m_volumes)[i];
const VolumeCache& volume_data = m_cache.volumes_data[i];
+ const Geometry::Transformation& inst_trafo = volume_data.get_instance_transform();
if (m_mode == Instance && !is_wipe_tower()) {
assert(is_from_fully_selected_instance(i));
- const Geometry::Transformation& old_trafo = volume_data.get_instance_transform();
Transform3d new_rotation_matrix = Transform3d::Identity();
if (transformation_type.absolute())
new_rotation_matrix = rotation_matrix;
else {
if (transformation_type.world())
- new_rotation_matrix = rotation_matrix * old_trafo.get_rotation_matrix();
+ new_rotation_matrix = rotation_matrix * inst_trafo.get_rotation_matrix();
else if (transformation_type.local())
- new_rotation_matrix = old_trafo.get_rotation_matrix() * rotation_matrix;
+ new_rotation_matrix = inst_trafo.get_rotation_matrix() * rotation_matrix;
else
assert(false);
}
- const Vec3d new_offset = transformation_type.independent() ? old_trafo.get_offset() :
- m_cache.dragging_center + new_rotation_matrix * old_trafo.get_rotation_matrix().inverse() *
- (old_trafo.get_offset() - m_cache.dragging_center);
- v.set_instance_transformation(Geometry::assemble_transform(Geometry::assemble_transform(new_offset), new_rotation_matrix,
- old_trafo.get_scaling_factor_matrix(), old_trafo.get_mirror_matrix()));
+ const Vec3d new_offset = transformation_type.independent() ? inst_trafo.get_offset() :
+ m_cache.dragging_center + new_rotation_matrix * inst_trafo.get_rotation_matrix().inverse() *
+ (inst_trafo.get_offset() - m_cache.dragging_center);
+ v.set_instance_transformation(Geometry::assemble_transform(Geometry::translation_transform(new_offset), new_rotation_matrix,
+ inst_trafo.get_scaling_factor_matrix(), inst_trafo.get_mirror_matrix()));
}
else {
- const Geometry::Transformation& old_trafo = volume_data.get_volume_transform();
- Transform3d new_rotation_matrix = Transform3d::Identity();
-
- if (transformation_type.absolute())
- new_rotation_matrix = rotation_matrix;
- else {
- if (transformation_type.world()) {
- const Transform3d inst_rotation_matrix = volume_data.get_instance_transform().get_rotation_matrix();
- new_rotation_matrix = inst_rotation_matrix.inverse() * rotation_matrix * inst_rotation_matrix * old_trafo.get_rotation_matrix();
- }
- else if (transformation_type.instance())
- new_rotation_matrix = rotation_matrix * old_trafo.get_rotation_matrix();
- else if (transformation_type.local())
- new_rotation_matrix = old_trafo.get_rotation_matrix() * rotation_matrix;
- else
- assert(false);
+ if (transformation_type.absolute()) {
+ const Geometry::Transformation& volume_trafo = volume_data.get_volume_transform();
+ v.set_volume_transformation(Geometry::assemble_transform(volume_trafo.get_offset_matrix(), Geometry::rotation_transform(rotation),
+ volume_trafo.get_scaling_factor_matrix(), volume_trafo.get_mirror_matrix()));
}
-
- const Vec3d new_offset = !is_wipe_tower() ? old_trafo.get_offset() :
- m_cache.dragging_center + new_rotation_matrix * old_trafo.get_rotation_matrix().inverse() *
- (old_trafo.get_offset() - m_cache.dragging_center);
- v.set_volume_transformation(Geometry::assemble_transform(Geometry::assemble_transform(new_offset), new_rotation_matrix,
- old_trafo.get_scaling_factor_matrix(), old_trafo.get_mirror_matrix()));
+ else
+ transform_volume_relative(v, volume_data, transformation_type, Geometry::rotation_transform(rotation));
}
}
@@ -1185,6 +1142,12 @@ void Selection::flattening_rotate(const Vec3d& normal)
this->set_bounding_boxes_dirty();
}
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+void Selection::scale(const Vec3d& scale, TransformationType transformation_type)
+{
+ scale_and_translate(scale, Vec3d::Zero(), transformation_type);
+}
+#else
void Selection::scale(const Vec3d& scale, TransformationType transformation_type)
{
if (!m_valid)
@@ -1259,6 +1222,7 @@ void Selection::scale(const Vec3d& scale, TransformationType transformation_type
set_bounding_boxes_dirty();
wxGetApp().plater()->canvas3D()->requires_check_outside_state();
}
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
void Selection::scale_to_fit_print_volume(const BuildVolume& volume)
{
@@ -1281,7 +1245,13 @@ void Selection::scale_to_fit_print_volume(const BuildVolume& volume)
// center selection on print bed
setup_cache();
offset.z() = -get_bounding_box().min.z();
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ TransformationType trafo_type;
+ trafo_type.set_relative();
+ translate(offset, trafo_type);
+#else
translate(offset);
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
wxGetApp().plater()->canvas3D()->do_move(""); // avoid storing another snapshot
wxGetApp().obj_manipul()->set_dirty();
@@ -1371,7 +1341,78 @@ void Selection::mirror(Axis axis)
set_bounding_boxes_dirty();
}
-#if !ENABLE_TRANSFORMATIONS_BY_MATRICES
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+void Selection::scale_and_translate(const Vec3d& scale, const Vec3d& translation, TransformationType transformation_type)
+{
+ if (!m_valid)
+ return;
+
+ std::cout << "Selection::scale_and_translate: " << to_string(scale) << " - " << to_string(translation) << "\n";
+
+ for (unsigned int i : m_list) {
+ GLVolume& v = *(*m_volumes)[i];
+ const VolumeCache& volume_data = m_cache.volumes_data[i];
+ const Geometry::Transformation& inst_trafo = volume_data.get_instance_transform();
+ if (m_mode == Instance) {
+ assert(is_from_fully_selected_instance(i));
+ if (transformation_type.absolute()) {
+ assert(transformation_type.local());
+ assert(transformation_type.joint());
+ v.set_instance_transformation(Geometry::assemble_transform(inst_trafo.get_offset_matrix(), inst_trafo.get_rotation_matrix(),
+ Geometry::scale_transform(scale), inst_trafo.get_mirror_matrix()));
+ }
+ else {
+ if (transformation_type.world()) {
+ const Transform3d scale_matrix = Geometry::scale_transform(scale);
+ const Transform3d offset_matrix = (transformation_type.joint() && translation.isApprox(Vec3d::Zero())) ?
+ // non-constrained scaling - add offset to scale around selection center
+ Geometry::translation_transform(m_cache.dragging_center + scale_matrix * (inst_trafo.get_offset() - m_cache.dragging_center)) :
+ // constrained scaling - add offset to keep constraint
+ Geometry::translation_transform(translation) * inst_trafo.get_offset_matrix();
+ v.set_instance_transformation(offset_matrix * scale_matrix * inst_trafo.get_matrix_no_offset());
+ }
+ else if (transformation_type.local()) {
+ const Transform3d scale_matrix = Geometry::scale_transform(scale);
+ Vec3d offset;
+ if (transformation_type.joint() && translation.isApprox(Vec3d::Zero())) {
+ // non-constrained scaling - add offset to scale around selection center
+ offset = inst_trafo.get_matrix_no_offset().inverse() * (inst_trafo.get_offset() - m_cache.dragging_center);
+ offset = inst_trafo.get_matrix_no_offset() * (scale_matrix * offset - offset);
+ }
+ else
+ // constrained scaling - add offset to keep constraint
+ offset = translation;
+
+ v.set_instance_transformation(Geometry::translation_transform(offset) * inst_trafo.get_matrix() * scale_matrix);
+ }
+ else
+ assert(false);
+ }
+ }
+ else {
+ if (transformation_type.absolute()) {
+ assert(transformation_type.local());
+ const Geometry::Transformation& volume_trafo = volume_data.get_volume_transform();
+ v.set_volume_transformation(Geometry::assemble_transform(volume_trafo.get_offset_matrix(), volume_trafo.get_rotation_matrix(),
+ Geometry::scale_transform(scale), volume_trafo.get_mirror_matrix()));
+ }
+ else
+ transform_volume_relative(v, volume_data, transformation_type, Geometry::translation_transform(translation) * Geometry::scale_transform(scale));
+ }
+ }
+
+#if !DISABLE_INSTANCES_SYNCH
+ if (m_mode == Instance)
+ synchronize_unselected_instances(SyncRotationType::NONE);
+ else if (m_mode == Volume)
+ synchronize_unselected_volumes();
+#endif // !DISABLE_INSTANCES_SYNCH
+
+ ensure_on_bed();
+ set_bounding_boxes_dirty();
+ wxGetApp().plater()->canvas3D()->requires_check_outside_state();
+}
+#else
void Selection::translate(unsigned int object_idx, const Vec3d& displacement)
{
if (!m_valid)
@@ -1420,7 +1461,7 @@ void Selection::translate(unsigned int object_idx, const Vec3d& displacement)
this->set_bounding_boxes_dirty();
}
-#endif // !ENABLE_TRANSFORMATIONS_BY_MATRICES
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
void Selection::translate(unsigned int object_idx, unsigned int instance_idx, const Vec3d& displacement)
{
@@ -1431,7 +1472,7 @@ void Selection::translate(unsigned int object_idx, unsigned int instance_idx, co
GLVolume& v = *(*m_volumes)[i];
if (v.object_idx() == (int)object_idx && v.instance_idx() == (int)instance_idx)
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
- v.set_instance_transformation(Geometry::assemble_transform(displacement) * v.get_instance_transformation().get_matrix());
+ v.set_instance_transformation(Geometry::translation_transform(displacement) * v.get_instance_transformation().get_matrix());
#else
v.set_instance_offset(v.get_instance_offset() + displacement);
#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
@@ -1468,7 +1509,7 @@ void Selection::translate(unsigned int object_idx, unsigned int instance_idx, co
continue;
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
- v.set_instance_transformation(Geometry::assemble_transform(displacement) * v.get_instance_transformation().get_matrix());
+ v.set_instance_transformation(Geometry::translation_transform(displacement) * v.get_instance_transformation().get_matrix());
#else
v.set_instance_offset(v.get_instance_offset() + displacement);
#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
@@ -2770,7 +2811,11 @@ void Selection::render_sidebar_scale_hints(const std::string& sidebar_field, GLS
void Selection::render_sidebar_scale_hints(const std::string& sidebar_field)
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
{
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ const bool uniform_scale = wxGetApp().obj_manipul()->get_uniform_scaling();
+#else
const bool uniform_scale = requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling();
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
#if ENABLE_GL_SHADERS_ATTRIBUTES
auto render_sidebar_scale_hint = [this, uniform_scale](Axis axis, GLShaderProgram& shader, const Transform3d& matrix) {
@@ -3380,5 +3425,27 @@ void Selection::paste_objects_from_clipboard()
#endif /* _DEBUG */
}
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+void Selection::transform_volume_relative(GLVolume& volume, const VolumeCache& volume_data, TransformationType transformation_type,
+ const Transform3d& transform)
+{
+ const Geometry::Transformation& inst_trafo = volume_data.get_instance_transform();
+ const Geometry::Transformation& volume_trafo = volume_data.get_volume_transform();
+ if (transformation_type.world()) {
+ const Transform3d inst_matrix_no_offset = inst_trafo.get_matrix_no_offset();
+ const Transform3d new_volume_matrix = inst_matrix_no_offset.inverse() * transform * inst_matrix_no_offset;
+ volume.set_volume_transformation(volume_trafo.get_offset_matrix() * new_volume_matrix * volume_trafo.get_matrix_no_offset());
+ }
+ else if (transformation_type.instance())
+ volume.set_volume_transformation(volume_trafo.get_offset_matrix() * transform * volume_trafo.get_matrix_no_offset());
+ else if (transformation_type.local()) {
+ const Geometry::Transformation trafo(transform);
+ volume.set_volume_transformation(trafo.get_offset_matrix() * volume_trafo.get_matrix() * trafo.get_matrix_no_offset());
+ }
+ else
+ assert(false);
+}
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
+
} // namespace GUI
} // namespace Slic3r
diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp
index c9f0eb7c6..bd9c9216c 100644
--- a/src/slic3r/GUI/Selection.hpp
+++ b/src/slic3r/GUI/Selection.hpp
@@ -336,7 +336,9 @@ public:
VolumeNotAxisAligned_Instance,
MultipleSelection,
};
+#if !ENABLE_TRANSFORMATIONS_BY_MATRICES
bool requires_uniform_scale(EUniformScaleRequiredReason* reason = nullptr) const;
+#endif // !ENABLE_TRANSFORMATIONS_BY_MATRICES
#else
bool requires_uniform_scale() const;
#endif // ENABLE_WORLD_COORDINATE
@@ -365,7 +367,11 @@ public:
void setup_cache();
#if ENABLE_WORLD_COORDINATE
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ void translate(const Vec3d& displacement, TransformationType transformation_type);
+#else
void translate(const Vec3d& displacement, ECoordinatesType type = ECoordinatesType::World);
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
#else
void translate(const Vec3d& displacement, bool local = false);
#endif // ENABLE_WORLD_COORDINATE
@@ -374,6 +380,9 @@ public:
void scale(const Vec3d& scale, TransformationType transformation_type);
void scale_to_fit_print_volume(const BuildVolume& volume);
void mirror(Axis axis);
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ void scale_and_translate(const Vec3d& scale, const Vec3d& translation, TransformationType transformation_type);
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
#if !ENABLE_TRANSFORMATIONS_BY_MATRICES
void translate(unsigned int object_idx, const Vec3d& displacement);
@@ -468,6 +477,11 @@ private:
void paste_volumes_from_clipboard();
void paste_objects_from_clipboard();
+
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ void transform_volume_relative(GLVolume& volume, const VolumeCache& volume_data, TransformationType transformation_type,
+ const Transform3d& transform);
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
};
} // namespace GUI