Fixed synchronization of instances/volumes after resetting skew

This commit is contained in:
enricoturri1966 2023-02-23 14:16:55 +01:00
parent 5d38d3363c
commit b92735ac36
2 changed files with 40 additions and 5 deletions

View file

@ -3746,12 +3746,22 @@ void GLCanvas3D::do_reset_skew(const std::string& snapshot_type)
if (!snapshot_type.empty())
wxGetApp().plater()->take_snapshot(_(snapshot_type));
// stores current min_z of instances
std::map<std::pair<int, int>, double> min_zs;
if (!snapshot_type.empty()) {
for (int i = 0; i < static_cast<int>(m_model->objects.size()); ++i) {
const ModelObject* obj = m_model->objects[i];
for (int j = 0; j < static_cast<int>(obj->instances.size()); ++j) {
min_zs[{ i, j }] = obj->instance_bounding_box(j).min.z();
}
}
}
std::set<std::pair<int, int>> done; // keeps track of modified instances
const Selection::IndicesList& idxs = m_selection.get_volume_idxs();
Selection::EMode selection_mode = m_selection.get_mode();
for (unsigned int id : idxs) {
const GLVolume* v = m_volumes.volumes[id];
for (const GLVolume* v : m_volumes.volumes) {
int object_idx = v->object_idx();
if (object_idx < 0 || (int)m_model->objects.size() <= object_idx)
continue;
@ -3761,14 +3771,30 @@ void GLCanvas3D::do_reset_skew(const std::string& snapshot_type)
done.insert(std::pair<int, int>(object_idx, instance_idx));
// Mirror instances/volumes
ModelObject* model_object = m_model->objects[object_idx];
if (model_object != nullptr) {
model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation());
model_object->volumes[volume_idx]->set_transformation(v->get_volume_transformation());
if (selection_mode == Selection::Instance)
model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation());
else if (selection_mode == Selection::Volume)
model_object->volumes[volume_idx]->set_transformation(v->get_volume_transformation());
model_object->invalidate_bounding_box();
}
}
// Fixes sinking/flying instances
for (const std::pair<int, int>& i : done) {
ModelObject* m = m_model->objects[i.first];
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 >= SINKING_Z_THRESHOLD || shift_z > SINKING_Z_THRESHOLD) {
Vec3d shift(0.0, 0.0, -shift_z);
m_selection.translate(i.first, i.second, shift);
m->translate_instance(i.second, shift);
}
wxGetApp().obj_list()->update_info_items(static_cast<size_t>(i.first));
}
post_event(SimpleEvent(EVT_GLCANVAS_RESET_SKEW));
m_dirty = true;

View file

@ -1543,6 +1543,15 @@ void Selection::reset_skew()
}
}
#if !DISABLE_INSTANCES_SYNCH
if (m_mode == Instance)
// even if there is no rotation, we pass SyncRotationType::GENERAL to force
// synchronize_unselected_instances() to remove skew from the other instances
synchronize_unselected_instances(SyncRotationType::GENERAL);
else if (m_mode == Volume)
synchronize_unselected_volumes();
#endif // !DISABLE_INSTANCES_SYNCH
ensure_on_bed();
set_bounding_boxes_dirty();
wxGetApp().plater()->canvas3D()->requires_check_outside_state();