From b6005404119f1a47f84599d2e79a01f70f415996 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 23 Apr 2021 09:11:55 +0200 Subject: [PATCH] Tech ENABLE_ALLOW_NEGATIVE_Z -> Keep sinking instances as sinking after applying scale gizmo --- src/slic3r/GUI/GLCanvas3D.cpp | 49 +++++++++++++++++++-------- src/slic3r/GUI/Selection.cpp | 62 ++++++++++++++--------------------- 2 files changed, 59 insertions(+), 52 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 1513c5a39..f4a0d7412 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3660,10 +3660,13 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type) for (const std::pair& i : done) { ModelObject* m = m_model->objects[i.first]; #if ENABLE_ALLOW_NEGATIVE_Z + 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 >= 0.0) { + if (min_zs.empty() || min_zs.find({ i.first, i.second })->second >= 0.0 || shift_z > 0.0) { + Vec3d shift(0.0, 0.0, -shift_z); +#else + Vec3d shift(0.0, 0.0, -m->get_instance_min_z(i.second)); #endif // ENABLE_ALLOW_NEGATIVE_Z - Vec3d shift(0.0, 0.0, -m->get_instance_min_z(i.second)); m_selection.translate(i.first, i.second, shift); m->translate_instance(i.second, shift); #if ENABLE_ALLOW_NEGATIVE_Z @@ -3685,14 +3688,26 @@ void GLCanvas3D::do_scale(const std::string& snapshot_type) if (!snapshot_type.empty()) wxGetApp().plater()->take_snapshot(_(snapshot_type)); +#if ENABLE_ALLOW_NEGATIVE_Z + // stores current min_z of instances + std::map, double> min_zs; + if (!snapshot_type.empty()) { + for (int i = 0; i < static_cast(m_model->objects.size()); ++i) { + const ModelObject* obj = m_model->objects[i]; + for (int j = 0; j < static_cast(obj->instances.size()); ++j) { + min_zs[{ i, j }] = obj->instance_bounding_box(j).min(2); + } + } + } +#endif // ENABLE_ALLOW_NEGATIVE_Z + std::set> done; // keeps track of modified instances Selection::EMode selection_mode = m_selection.get_mode(); - for (const GLVolume* v : m_volumes.volumes) - { + for (const GLVolume* v : m_volumes.volumes) { int object_idx = v->object_idx(); - if ((object_idx < 0) || ((int)m_model->objects.size() <= object_idx)) + if (object_idx < 0 || (int)m_model->objects.size() <= object_idx) continue; int instance_idx = v->instance_idx(); @@ -3702,15 +3717,12 @@ void GLCanvas3D::do_scale(const std::string& snapshot_type) // Rotate instances/volumes ModelObject* model_object = m_model->objects[object_idx]; - if (model_object != nullptr) - { - if (selection_mode == Selection::Instance) - { + if (model_object != nullptr) { + if (selection_mode == Selection::Instance) { model_object->instances[instance_idx]->set_scaling_factor(v->get_instance_scaling_factor()); model_object->instances[instance_idx]->set_offset(v->get_instance_offset()); } - else if (selection_mode == Selection::Volume) - { + else if (selection_mode == Selection::Volume) { 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()); @@ -3720,16 +3732,25 @@ void GLCanvas3D::do_scale(const std::string& snapshot_type) } // Fixes sinking/flying instances - for (const std::pair& i : done) - { + for (const std::pair& i : done) { ModelObject* m = m_model->objects[i.first]; +#if ENABLE_ALLOW_NEGATIVE_Z + 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 >= 0.0 || shift_z > 0.0) { + Vec3d shift(0.0, 0.0, -shift_z); +#else Vec3d shift(0.0, 0.0, -m->get_instance_min_z(i.second)); +#endif // ENABLE_ALLOW_NEGATIVE_Z m_selection.translate(i.first, i.second, shift); m->translate_instance(i.second, shift); +#if ENABLE_ALLOW_NEGATIVE_Z + } +#endif // ENABLE_ALLOW_NEGATIVE_Z } if (!done.empty()) - post_event(SimpleEvent(EVT_GLCANVAS_INSTANCE_ROTATED)); + post_event(SimpleEvent(EVT_GLCANVAS_INSTANCE_SCALED)); m_dirty = true; } diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index 2acb8cb85..2da521d47 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -866,12 +866,10 @@ void Selection::scale(const Vec3d& scale, TransformationType transformation_type if (!m_valid) return; - for (unsigned int i : m_list) - { + for (unsigned int i : m_list) { GLVolume &volume = *(*m_volumes)[i]; if (is_single_full_instance()) { - if (transformation_type.relative()) - { + if (transformation_type.relative()) { Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), scale); Eigen::Matrix new_matrix = (m * m_cache.volumes_data[i].get_instance_scale_matrix()).matrix().block(0, 0, 3, 3); // extracts scaling factors from the composed transformation @@ -881,8 +879,7 @@ void Selection::scale(const Vec3d& scale, TransformationType transformation_type volume.set_instance_scaling_factor(new_scale); } - else - { + else { if (transformation_type.world() && (std::abs(scale.x() - scale.y()) > EPSILON || std::abs(scale.x() - scale.z()) > EPSILON)) { // Non-uniform scaling. Transform the scaling factors into the local coordinate system. // This is only possible, if the instance rotation is mulitples of ninety degrees. @@ -895,11 +892,9 @@ void Selection::scale(const Vec3d& scale, TransformationType transformation_type } else if (is_single_volume() || is_single_modifier()) volume.set_volume_scaling_factor(scale); - else - { + else { Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), scale); - if (m_mode == Instance) - { + if (m_mode == Instance) { Eigen::Matrix new_matrix = (m * m_cache.volumes_data[i].get_instance_scale_matrix()).matrix().block(0, 0, 3, 3); // extracts scaling factors from the composed transformation Vec3d new_scale(new_matrix.col(0).norm(), new_matrix.col(1).norm(), new_matrix.col(2).norm()); @@ -908,13 +903,11 @@ void Selection::scale(const Vec3d& scale, TransformationType transformation_type volume.set_instance_scaling_factor(new_scale); } - else if (m_mode == Volume) - { + else if (m_mode == Volume) { Eigen::Matrix new_matrix = (m * m_cache.volumes_data[i].get_volume_scale_matrix()).matrix().block(0, 0, 3, 3); // extracts scaling factors from the composed transformation Vec3d new_scale(new_matrix.col(0).norm(), new_matrix.col(1).norm(), new_matrix.col(2).norm()); - if (transformation_type.joint()) - { + if (transformation_type.joint()) { Vec3d offset = m * (m_cache.volumes_data[i].get_volume_position() + m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center); volume.set_volume_offset(m_cache.dragging_center - m_cache.volumes_data[i].get_instance_position() + offset); } @@ -930,34 +923,34 @@ void Selection::scale(const Vec3d& scale, TransformationType transformation_type synchronize_unselected_volumes(); #endif // !DISABLE_INSTANCES_SYNCH +#if !ENABLE_ALLOW_NEGATIVE_Z ensure_on_bed(); +#endif // !ENABLE_ALLOW_NEGATIVE_Z this->set_bounding_boxes_dirty(); } void Selection::scale_to_fit_print_volume(const DynamicPrintConfig& config) { - if (is_empty() || (m_mode == Volume)) + if (is_empty() || m_mode == Volume) return; // adds 1/100th of a mm on all sides to avoid false out of print volume detections due to floating-point roundings Vec3d box_size = get_bounding_box().size() + 0.01 * Vec3d::Ones(); const ConfigOptionPoints* opt = dynamic_cast(config.option("bed_shape")); - if (opt != nullptr) - { + if (opt != nullptr) { BoundingBox bed_box_2D = get_extents(Polygon::new_scale(opt->values)); - BoundingBoxf3 print_volume(Vec3d(unscale(bed_box_2D.min(0)), unscale(bed_box_2D.min(1)), 0.0), Vec3d(unscale(bed_box_2D.max(0)), unscale(bed_box_2D.max(1)), config.opt_float("max_print_height"))); + BoundingBoxf3 print_volume({ unscale(bed_box_2D.min(0)), unscale(bed_box_2D.min(1)), 0.0 }, { unscale(bed_box_2D.max(0)), unscale(bed_box_2D.max(1)), config.opt_float("max_print_height") }); Vec3d print_volume_size = print_volume.size(); double sx = (box_size(0) != 0.0) ? print_volume_size(0) / box_size(0) : 0.0; double sy = (box_size(1) != 0.0) ? print_volume_size(1) / box_size(1) : 0.0; double sz = (box_size(2) != 0.0) ? print_volume_size(2) / box_size(2) : 0.0; - if ((sx != 0.0) && (sy != 0.0) && (sz != 0.0)) + if (sx != 0.0 && sy != 0.0 && sz != 0.0) { double s = std::min(sx, std::min(sy, sz)); - if (s != 1.0) - { - wxGetApp().plater()->take_snapshot(_(L("Scale To Fit"))); + if (s != 1.0) { + wxGetApp().plater()->take_snapshot(_L("Scale To Fit")); TransformationType type; type.set_world(); @@ -987,8 +980,7 @@ void Selection::mirror(Axis axis) bool single_full_instance = is_single_full_instance(); - for (unsigned int i : m_list) - { + for (unsigned int i : m_list) { if (single_full_instance) (*m_volumes)[i]->set_instance_mirror(axis, -(*m_volumes)[i]->get_instance_mirror(axis)); else if (m_mode == Volume) @@ -1010,8 +1002,7 @@ void Selection::translate(unsigned int object_idx, const Vec3d& displacement) if (!m_valid) return; - for (unsigned int i : m_list) - { + for (unsigned int i : m_list) { GLVolume* v = (*m_volumes)[i]; if (v->object_idx() == (int)object_idx) v->set_instance_offset(v->get_instance_offset() + displacement); @@ -1020,8 +1011,7 @@ void Selection::translate(unsigned int object_idx, const Vec3d& displacement) std::set done; // prevent processing volumes twice done.insert(m_list.begin(), m_list.end()); - for (unsigned int i : m_list) - { + for (unsigned int i : m_list) { if (done.size() == m_volumes->size()) break; @@ -1030,8 +1020,7 @@ void Selection::translate(unsigned int object_idx, const Vec3d& displacement) continue; // Process unselected volumes of the object. - for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j) - { + for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j) { if (done.size() == m_volumes->size()) break; @@ -1055,18 +1044,16 @@ void Selection::translate(unsigned int object_idx, unsigned int instance_idx, co if (!m_valid) return; - for (unsigned int i : m_list) - { + for (unsigned int i : m_list) { GLVolume* v = (*m_volumes)[i]; - if ((v->object_idx() == (int)object_idx) && (v->instance_idx() == (int)instance_idx)) + if (v->object_idx() == (int)object_idx && v->instance_idx() == (int)instance_idx) v->set_instance_offset(v->get_instance_offset() + displacement); } std::set done; // prevent processing volumes twice done.insert(m_list.begin(), m_list.end()); - for (unsigned int i : m_list) - { + for (unsigned int i : m_list) { if (done.size() == m_volumes->size()) break; @@ -1075,8 +1062,7 @@ void Selection::translate(unsigned int object_idx, unsigned int instance_idx, co continue; // Process unselected volumes of the object. - for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j) - { + for (unsigned int j = 0; j < (unsigned int)m_volumes->size(); ++j) { if (done.size() == m_volumes->size()) break; @@ -1084,7 +1070,7 @@ void Selection::translate(unsigned int object_idx, unsigned int instance_idx, co continue; GLVolume* v = (*m_volumes)[j]; - if ((v->object_idx() != object_idx) || (v->instance_idx() != (int)instance_idx)) + if (v->object_idx() != object_idx || v->instance_idx() != (int)instance_idx) continue; v->set_instance_offset(v->get_instance_offset() + displacement);