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-19 11:01:54 +0300
committerenricoturri1966 <enricoturri@seznam.cz>2022-06-06 13:38:20 +0300
commitb76f9fc2eef4776d1945727f0c860e26f6d0102e (patch)
tree1650c798e829a0992fd87f11df869d5a2a2d05c7
parent3b3edb5a9743c9597ecb894fe74bb5bd9c2852f0 (diff)
Tech ENABLE_TRANSFORMATIONS_BY_MATRICES - Scaling using object manipulator fields
Fixed conflicts during rebase with master
-rw-r--r--src/slic3r/GUI/GUI_ObjectList.cpp4
-rw-r--r--src/slic3r/GUI/GUI_ObjectManipulation.cpp5
-rw-r--r--src/slic3r/GUI/Selection.cpp147
-rw-r--r--src/slic3r/GUI/Selection.hpp46
4 files changed, 159 insertions, 43 deletions
diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp
index 73946786d..a8c9819a6 100644
--- a/src/slic3r/GUI/GUI_ObjectList.cpp
+++ b/src/slic3r/GUI/GUI_ObjectList.cpp
@@ -1585,8 +1585,8 @@ void ObjectList::load_modifier(const wxArrayString& input_files, ModelObject& mo
if (from_galery) {
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
- new_volume->set_transformation(v->get_instance_transformation().get_matrix_no_offset().inverse());
// Transform the new modifier to be aligned with the print bed.
+ new_volume->set_transformation(v->get_instance_transformation().get_matrix_no_offset().inverse());
const BoundingBoxf3 mesh_bb = new_volume->mesh().bounding_box();
#else
// Transform the new modifier to be aligned with the print bed.
@@ -1662,8 +1662,8 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode
// First (any) GLVolume of the selected instance. They all share the same instance matrix.
const GLVolume* v = selection.get_first_volume();
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
- new_volume->set_transformation(v->get_instance_transformation().get_matrix_no_offset().inverse());
// Transform the new modifier to be aligned with the print bed.
+ new_volume->set_transformation(v->get_instance_transformation().get_matrix_no_offset().inverse());
const BoundingBoxf3 mesh_bb = new_volume->mesh().bounding_box();
#else
// Transform the new modifier to be aligned with the print bed.
diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp
index 74cb64e9f..ff8fe940c 100644
--- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp
+++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp
@@ -1303,7 +1303,10 @@ void ObjectManipulation::do_scale(int axis, const Vec3d &scale) const
transformation_type.set_instance();
#if ENABLE_TRANSFORMATIONS_BY_MATRICES
- Vec3d scaling_factor = m_uniform_scale ? scale(axis) * Vec3d::Ones() : scale;
+ if (!selection.is_single_full_instance() && !selection.is_single_volume_or_modifier())
+ transformation_type.set_relative();
+
+ const Vec3d scaling_factor = m_uniform_scale ? scale(axis) * Vec3d::Ones() : scale;
#else
if (!is_local_coordinates())
transformation_type.set_relative();
diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp
index 4a60cbe63..be6abeee3 100644
--- a/src/slic3r/GUI/Selection.cpp
+++ b/src/slic3r/GUI/Selection.cpp
@@ -713,6 +713,8 @@ const BoundingBoxf3& Selection::get_bounding_box() const
const BoundingBoxf3& Selection::get_unscaled_instance_bounding_box() const
{
+ assert(is_single_full_instance());
+
if (!m_unscaled_instance_bounding_box.has_value()) {
std::optional<BoundingBoxf3>* bbox = const_cast<std::optional<BoundingBoxf3>*>(&m_unscaled_instance_bounding_box);
*bbox = BoundingBoxf3();
@@ -736,6 +738,8 @@ const BoundingBoxf3& Selection::get_unscaled_instance_bounding_box() const
const BoundingBoxf3& Selection::get_scaled_instance_bounding_box() const
{
+ assert(is_single_full_instance());
+
if (!m_scaled_instance_bounding_box.has_value()) {
std::optional<BoundingBoxf3>* bbox = const_cast<std::optional<BoundingBoxf3>*>(&m_scaled_instance_bounding_box);
*bbox = BoundingBoxf3();
@@ -753,6 +757,65 @@ const BoundingBoxf3& Selection::get_scaled_instance_bounding_box() const
return *m_scaled_instance_bounding_box;
}
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+const BoundingBoxf3& Selection::get_full_unscaled_instance_bounding_box() const
+{
+ assert(is_single_full_instance());
+
+ if (!m_full_unscaled_instance_bounding_box.has_value()) {
+ std::optional<BoundingBoxf3>* bbox = const_cast<std::optional<BoundingBoxf3>*>(&m_full_unscaled_instance_bounding_box);
+ *bbox = BoundingBoxf3();
+ if (m_valid) {
+ for (unsigned int i : m_list) {
+ const GLVolume& volume = *(*m_volumes)[i];
+ Transform3d trafo = volume.get_instance_transformation().get_matrix_no_scaling_factor() * volume.get_volume_transformation().get_matrix();
+ trafo.translation().z() += volume.get_sla_shift_z();
+ (*bbox)->merge(volume.transformed_convex_hull_bounding_box(trafo));
+ }
+ }
+ }
+ return *m_full_unscaled_instance_bounding_box;
+}
+
+const BoundingBoxf3& Selection::get_full_scaled_instance_bounding_box() const
+{
+ assert(is_single_full_instance());
+
+ if (!m_full_scaled_instance_bounding_box.has_value()) {
+ std::optional<BoundingBoxf3>* bbox = const_cast<std::optional<BoundingBoxf3>*>(&m_full_scaled_instance_bounding_box);
+ *bbox = BoundingBoxf3();
+ if (m_valid) {
+ for (unsigned int i : m_list) {
+ const GLVolume& volume = *(*m_volumes)[i];
+ Transform3d trafo = volume.get_instance_transformation().get_matrix() * volume.get_volume_transformation().get_matrix();
+ trafo.translation().z() += volume.get_sla_shift_z();
+ (*bbox)->merge(volume.transformed_convex_hull_bounding_box(trafo));
+ }
+ }
+ }
+ return *m_full_scaled_instance_bounding_box;
+}
+
+const BoundingBoxf3& Selection::get_full_unscaled_instance_local_bounding_box() const
+{
+ assert(is_single_full_instance());
+
+ if (!m_full_unscaled_instance_local_bounding_box.has_value()) {
+ std::optional<BoundingBoxf3>* bbox = const_cast<std::optional<BoundingBoxf3>*>(&m_full_unscaled_instance_local_bounding_box);
+ *bbox = BoundingBoxf3();
+ if (m_valid) {
+ for (unsigned int i : m_list) {
+ const GLVolume& volume = *(*m_volumes)[i];
+ Transform3d trafo = volume.get_volume_transformation().get_matrix();
+ trafo.translation().z() += volume.get_sla_shift_z();
+ (*bbox)->merge(volume.transformed_convex_hull_bounding_box(trafo));
+ }
+ }
+ }
+ return *m_full_unscaled_instance_local_bounding_box;
+}
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
+
void Selection::setup_cache()
{
if (!m_valid)
@@ -1350,54 +1413,66 @@ void Selection::scale_and_translate(const Vec3d& scale, const Vec3d& translation
if (!m_valid)
return;
+ Vec3d relative_scale = scale;
+
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.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()));
+
+ if (transformation_type.absolute()) {
+ // convert from absolute scaling to relative scaling
+ BoundingBoxf3 original_box;
+ if (m_mode == Instance) {
+ assert(is_from_fully_selected_instance(i));
+ if (transformation_type.world())
+ original_box = get_full_unscaled_instance_bounding_box();
+ else
+ original_box = get_full_unscaled_instance_local_bounding_box();
}
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);
- }
+ if (transformation_type.world())
+ original_box = v.transformed_convex_hull_bounding_box((volume_data.get_instance_transform() *
+ volume_data.get_volume_transform()).get_matrix_no_scaling_factor());
+ else if (transformation_type.instance())
+ original_box = v.transformed_convex_hull_bounding_box(volume_data.get_volume_transform().get_matrix_no_scaling_factor());
else
- assert(false);
+ original_box = v.bounding_box();
}
+
+ relative_scale = original_box.size().cwiseProduct(scale).cwiseQuotient(m_box.get_bounding_box().size());
}
- else {
- 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(), volume_trafo.get_rotation_matrix(),
- Geometry::scale_transform(scale), volume_trafo.get_mirror_matrix()));
+
+ if (m_mode == Instance) {
+ assert(is_from_fully_selected_instance(i));
+ if (transformation_type.world()) {
+ const Transform3d scale_matrix = Geometry::scale_transform(relative_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(relative_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
- transform_volume_relative(v, volume_data, transformation_type, Geometry::translation_transform(translation) * Geometry::scale_transform(scale));
+ assert(false);
}
+ else
+ transform_volume_relative(v, volume_data, transformation_type, Geometry::translation_transform(translation) * Geometry::scale_transform(relative_scale));
}
#if !DISABLE_INSTANCES_SYNCH
diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp
index c919927ea..a20e952f3 100644
--- a/src/slic3r/GUI/Selection.hpp
+++ b/src/slic3r/GUI/Selection.hpp
@@ -225,10 +225,24 @@ private:
Cache m_cache;
Clipboard m_clipboard;
std::optional<BoundingBoxf3> m_bounding_box;
- // Bounding box of a selection, with no instance scaling applied. This bounding box
- // is useful for absolute scaling of tilted objects in world coordinate space.
+ // Bounding box of a single full instance selection, in world coordinates, with no instance scaling applied.
+ // This bounding box is useful for absolute scaling of tilted objects in world coordinate space.
+ // Modifiers are NOT taken in account
std::optional<BoundingBoxf3> m_unscaled_instance_bounding_box;
+ // Bounding box of a single full instance selection, in world coordinates.
+ // Modifiers are NOT taken in account
std::optional<BoundingBoxf3> m_scaled_instance_bounding_box;
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ // Bounding box of a single full instance selection, in world coordinates, with no instance scaling applied.
+ // Modifiers are taken in account
+ std::optional<BoundingBoxf3> m_full_unscaled_instance_bounding_box;
+ // Bounding box of a single full instance selection, in world coordinates.
+ // Modifiers are taken in account
+ std::optional<BoundingBoxf3> m_full_scaled_instance_bounding_box;
+ // Bounding box of a single full instance selection, in local coordinates, with no instance scaling applied.
+ // Modifiers are taken in account
+ std::optional<BoundingBoxf3> m_full_unscaled_instance_local_bounding_box;
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
#if ENABLE_RENDER_SELECTION_CENTER
GLModel m_vbo_sphere;
@@ -355,10 +369,25 @@ public:
unsigned int volumes_count() const { return (unsigned int)m_list.size(); }
const BoundingBoxf3& get_bounding_box() const;
- // Bounding box of a selection, with no instance scaling applied. This bounding box
- // is useful for absolute scaling of tilted objects in world coordinate space.
+ // Bounding box of a single full instance selection, in world coordinates, with no instance scaling applied.
+ // This bounding box is useful for absolute scaling of tilted objects in world coordinate space.
+ // Modifiers are NOT taken in account
const BoundingBoxf3& get_unscaled_instance_bounding_box() const;
+ // Bounding box of a single full instance selection, in world coordinates.
+ // Modifiers are NOT taken in account
const BoundingBoxf3& get_scaled_instance_bounding_box() const;
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ // Bounding box of a single full instance selection, in world coordinates, with no instance scaling applied.
+ // Modifiers are taken in account
+ const BoundingBoxf3& get_full_unscaled_instance_bounding_box() const;
+ // Bounding box of a single full instance selection, in world coordinates.
+ // Modifiers are taken in account
+ const BoundingBoxf3& get_full_scaled_instance_bounding_box() const;
+
+ // Bounding box of a single full instance selection, in local coordinates, with no instance scaling applied.
+ // Modifiers are taken in account
+ const BoundingBoxf3& get_full_unscaled_instance_local_bounding_box() const;
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
void setup_cache();
@@ -429,7 +458,16 @@ private:
void do_remove_volume(unsigned int volume_idx);
void do_remove_instance(unsigned int object_idx, unsigned int instance_idx);
void do_remove_object(unsigned int object_idx);
+#if ENABLE_TRANSFORMATIONS_BY_MATRICES
+ void set_bounding_boxes_dirty() {
+ m_bounding_box.reset();
+ m_unscaled_instance_bounding_box.reset(); m_scaled_instance_bounding_box.reset();
+ m_full_unscaled_instance_bounding_box.reset(); m_full_scaled_instance_bounding_box.reset();
+ m_full_unscaled_instance_local_bounding_box.reset();;
+ }
+#else
void set_bounding_boxes_dirty() { m_bounding_box.reset(); m_unscaled_instance_bounding_box.reset(); m_scaled_instance_bounding_box.reset(); }
+#endif // ENABLE_TRANSFORMATIONS_BY_MATRICES
void render_synchronized_volumes();
#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_WORLD_COORDINATE