diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp
index 5dd6f8a8e..103af9a03 100644
--- a/src/libslic3r/Format/3mf.cpp
+++ b/src/libslic3r/Format/3mf.cpp
@@ -1329,6 +1329,14 @@ namespace Slic3r {
 
     void _3MF_Importer::_apply_transform(ModelInstance& instance, const Transform3d& transform)
     {
+#if ENABLE_MODELVOLUME_TRANSFORM
+        Slic3r::Geometry::Transformation t(transform);
+        // invalid scale value, return
+        if (!t.get_scaling_factor().all())
+            return;
+
+        instance.set_transformation(t);
+#else
         // translation
         Vec3d offset = transform.matrix().block(0, 3, 3, 1);
 
@@ -1363,6 +1371,7 @@ namespace Slic3r {
         instance.set_scaling_factor(scale);
         instance.set_rotation(rotation);
         instance.set_mirror(mirror);
+#endif // ENABLE_MODELVOLUME_TRANSFORM
     }
 
     bool _3MF_Importer::_handle_start_config(const char** attributes, unsigned int num_attributes)
diff --git a/src/libslic3r/Geometry.cpp b/src/libslic3r/Geometry.cpp
index 9f23f73f2..256f48e85 100644
--- a/src/libslic3r/Geometry.cpp
+++ b/src/libslic3r/Geometry.cpp
@@ -1245,6 +1245,11 @@ Transformation::Transformation()
 {
 }
 
+Transformation::Transformation(const Transform3d& transform)
+{
+    set_from_transform(transform);
+}
+
 void Transformation::set_offset(const Vec3d& offset)
 {
     set_offset(X, offset(0));
@@ -1317,6 +1322,45 @@ void Transformation::set_mirror(Axis axis, double mirror)
     }
 }
 
+void Transformation::set_from_transform(const Transform3d& transform)
+{
+    // offset
+    set_offset(transform.matrix().block(0, 3, 3, 1));
+
+    Eigen::Matrix<double, 3, 3, Eigen::DontAlign> m3x3 = transform.matrix().block(0, 0, 3, 3);
+
+    // mirror
+    // it is impossible to reconstruct the original mirroring factors from a matrix,
+    // we can only detect if the matrix contains a left handed reference system
+    // in which case we reorient it back to right handed by mirroring the x axis
+    Vec3d mirror = Vec3d::Ones();
+    if (m3x3.col(0).dot(m3x3.col(1).cross(m3x3.col(2))) < 0.0)
+    {
+        mirror(0) = -1.0;
+        // remove mirror
+        m3x3.col(0) *= -1.0;
+    }
+    set_mirror(mirror);
+
+    // scale
+    set_scaling_factor(Vec3d(m3x3.col(0).norm(), m3x3.col(1).norm(), m3x3.col(2).norm()));
+
+    // remove scale
+    m3x3.col(0).normalize();
+    m3x3.col(1).normalize();
+    m3x3.col(2).normalize();
+
+    // rotation
+    set_rotation(extract_euler_angles(m3x3));
+
+    // forces matrix recalculation matrix
+    m_matrix = get_matrix();
+
+//    // debug check
+//    if (!m_matrix.isApprox(transform))
+//        std::cout << "something went wrong in extracting data from matrix" << std::endl;
+}
+
 const Transform3d& Transformation::get_matrix(bool dont_translate, bool dont_rotate, bool dont_scale, bool dont_mirror) const
 {
     if (m_dirty || m_flags.needs_update(dont_translate, dont_rotate, dont_scale, dont_mirror))
@@ -1335,6 +1379,10 @@ const Transform3d& Transformation::get_matrix(bool dont_translate, bool dont_rot
     return m_matrix;
 }
 
+Transformation Transformation::operator * (const Transformation& other) const
+{
+    return Transformation(get_matrix() * other.get_matrix());
+}
 #endif // ENABLE_MODELVOLUME_TRANSFORM
 
 } }
diff --git a/src/libslic3r/Geometry.hpp b/src/libslic3r/Geometry.hpp
index fd3560b7b..c21c3946d 100644
--- a/src/libslic3r/Geometry.hpp
+++ b/src/libslic3r/Geometry.hpp
@@ -217,13 +217,14 @@ class Transformation
     Vec3d m_rotation;            // Rotation around the three axes, in radians around mesh center point
     Vec3d m_scaling_factor;      // Scaling factors along the three axes
     Vec3d m_mirror;              // Mirroring along the three axes
-    mutable Transform3d m_matrix;
 
+    mutable Transform3d m_matrix;
     mutable Flags m_flags;
     mutable bool m_dirty;
 
 public:
     Transformation();
+    explicit Transformation(const Transform3d& transform);
 
     const Vec3d& get_offset() const { return m_offset; }
     double get_offset(Axis axis) const { return m_offset(axis); }
@@ -249,7 +250,11 @@ public:
     void set_mirror(const Vec3d& mirror);
     void set_mirror(Axis axis, double mirror);
 
+    void set_from_transform(const Transform3d& transform);
+
     const Transform3d& get_matrix(bool dont_translate = false, bool dont_rotate = false, bool dont_scale = false, bool dont_mirror = false) const;
+
+    Transformation operator * (const Transformation& other) const;
 };
 #endif // ENABLE_MODELVOLUME_TRANSFORM
 
diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp
index 73d342f08..819366146 100644
--- a/src/libslic3r/Technologies.hpp
+++ b/src/libslic3r/Technologies.hpp
@@ -1,16 +1,16 @@
 #ifndef _technologies_h_
 #define _technologies_h_
 
-//==============
+//============
 // debug techs
-//==============
+//============
 
 // Shows camera target in the 3D scene
 #define ENABLE_SHOW_CAMERA_TARGET 1
 
-//==============
+//=============
 // 1.42.0 techs
-//==============
+//=============
 #define ENABLE_1_42_0 1
 
 // Add double click on gizmo grabbers to reset transformation components to their default value