diff options
author | enricoturri1966 <enricoturri@seznam.cz> | 2022-05-19 11:01:54 +0300 |
---|---|---|
committer | enricoturri1966 <enricoturri@seznam.cz> | 2022-06-06 13:38:20 +0300 |
commit | b76f9fc2eef4776d1945727f0c860e26f6d0102e (patch) | |
tree | 1650c798e829a0992fd87f11df869d5a2a2d05c7 | |
parent | 3b3edb5a9743c9597ecb894fe74bb5bd9c2852f0 (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.cpp | 4 | ||||
-rw-r--r-- | src/slic3r/GUI/GUI_ObjectManipulation.cpp | 5 | ||||
-rw-r--r-- | src/slic3r/GUI/Selection.cpp | 147 | ||||
-rw-r--r-- | src/slic3r/GUI/Selection.hpp | 46 |
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 |