From 66a08be2090b189b51003cf9ccd8fec7997b1a85 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 23 Nov 2018 10:50:25 +0100 Subject: [PATCH] Fixed transformations when deleting second-to-last sub-volume of an object --- src/libslic3r/Model.cpp | 17 +++++++++ src/slic3r/GUI/GLCanvas3D.cpp | 72 ++++++++++++++++++++++++++++------- 2 files changed, 76 insertions(+), 13 deletions(-) diff --git a/src/libslic3r/Model.cpp b/src/libslic3r/Model.cpp index 6b9151ff8..c10e90bdb 100644 --- a/src/libslic3r/Model.cpp +++ b/src/libslic3r/Model.cpp @@ -661,6 +661,23 @@ void ModelObject::delete_volume(size_t idx) ModelVolumePtrs::iterator i = this->volumes.begin() + idx; delete *i; this->volumes.erase(i); + + if (this->volumes.size() == 1) + { + // only one volume left + // center it and update the instances accordingly + // rationale: the volume may be shifted with respect to the object center and this may lead to wrong rotation and scaling + // when modifying the instance matrix of the derived GLVolume + ModelVolume* v = this->volumes.front(); + v->center_geometry(); + const Vec3d& vol_offset = v->get_offset(); + for (ModelInstance* inst : this->instances) + { + inst->set_offset(inst->get_offset() + inst->get_matrix(true) * vol_offset); + } + v->set_offset(Vec3d::Zero()); + } + this->invalidate_bounding_box(); } diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index ba04a37ab..beef57c57 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1924,9 +1924,17 @@ void GLCanvas3D::Selection::_update_type() unsigned int volumes_count = (unsigned int)model_object->volumes.size(); unsigned int instances_count = (unsigned int)model_object->instances.size(); if (volumes_count * instances_count == 1) + { m_type = SingleFullObject; + // ensures the correct mode is selected + m_mode = Instance; + } else if (volumes_count == 1) // instances_count > 1 + { m_type = SingleFullInstance; + // ensures the correct mode is selected + m_mode = Instance; + } else { m_type = SingleVolume; @@ -1950,11 +1958,19 @@ void GLCanvas3D::Selection::_update_type() unsigned int instances_count = (unsigned int)model_object->instances.size(); unsigned int selected_instances_count = (unsigned int)m_cache.content.begin()->second.size(); if (volumes_count * instances_count == (unsigned int)m_list.size()) + { m_type = SingleFullObject; + // ensures the correct mode is selected + m_mode = Instance; + } else if (selected_instances_count == 1) { if (volumes_count == (unsigned int)m_list.size()) + { m_type = SingleFullInstance; + // ensures the correct mode is selected + m_mode = Instance; + } else { unsigned int modifiers_count = 0; @@ -1977,7 +1993,11 @@ void GLCanvas3D::Selection::_update_type() } } else if ((selected_instances_count > 1) && (selected_instances_count * volumes_count == (unsigned int)m_list.size())) + { m_type = MultipleFullInstance; + // ensures the correct mode is selected + m_mode = Instance; + } } else { @@ -1990,7 +2010,11 @@ void GLCanvas3D::Selection::_update_type() sels_cntr += volumes_count * instances_count; } if (sels_cntr == (unsigned int)m_list.size()) + { m_type = MultipleFullObject; + // ensures the correct mode is selected + m_mode = Instance; + } } } } @@ -2002,66 +2026,84 @@ void GLCanvas3D::Selection::_update_type() v->disabled = requires_disable ? (v->object_idx() != object_idx) || (v->instance_idx() != instance_idx) : false; } + std::cout << "Selection: "; + std::cout << "mode: "; + switch (m_mode) + { + case Volume: + { + std::cout << "Volume"; + break; + } + case Instance: + { + std::cout << "Instance"; + break; + } + } + + std::cout << " - type: "; + switch (m_type) { case Invalid: { - std::cout << "selection type: Invalid" << std::endl; + std::cout << "Invalid" << std::endl; break; } case Empty: { - std::cout << "selection type: Empty" << std::endl; + std::cout << "Empty" << std::endl; break; } case WipeTower: { - std::cout << "selection type: WipeTower" << std::endl; + std::cout << "WipeTower" << std::endl; break; } case SingleModifier: { - std::cout << "selection type: SingleModifier" << std::endl; + std::cout << "SingleModifier" << std::endl; break; } case MultipleModifier: { - std::cout << "selection type: MultipleModifier" << std::endl; + std::cout << "MultipleModifier" << std::endl; break; } case SingleVolume: { - std::cout << "selection type: SingleVolume" << std::endl; + std::cout << "SingleVolume" << std::endl; break; } case MultipleVolume: { - std::cout << "selection type: MultipleVolume" << std::endl; + std::cout << "MultipleVolume" << std::endl; break; } case SingleFullObject: { - std::cout << "selection type: SingleFullObject" << std::endl; + std::cout << "SingleFullObject" << std::endl; break; } case MultipleFullObject: { - std::cout << "selection type: MultipleFullObject" << std::endl; + std::cout << "MultipleFullObject" << std::endl; break; } case SingleFullInstance: { - std::cout << "selection type: SingleFullInstance" << std::endl; + std::cout << "SingleFullInstance" << std::endl; break; } case MultipleFullInstance: { - std::cout << "selection type: MultipleFullInstance" << std::endl; + std::cout << "MultipleFullInstance" << std::endl; break; } case Mixed: { - std::cout << "selection type: Mixed" << std::endl; + std::cout << "Mixed" << std::endl; break; } } @@ -3942,7 +3984,11 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re int extruder_id = mvs->model_volume->extruder_id(); if (extruder_id != -1) volume->extruder_id = extruder_id; - } + + // updates volumes transformations + volume->set_instance_transformation(mvs->model_volume->get_object()->instances[volume->instance_idx()]->get_transformation()); + volume->set_volume_transformation(mvs->model_volume->get_transformation()); + } } } }