Fix dragging of mixed instances plus volumes selections

This commit is contained in:
Enrico Turri 2019-04-01 13:53:48 +02:00
parent 9821814604
commit d4b22cfb87
2 changed files with 45 additions and 9 deletions

View file

@ -118,17 +118,17 @@ void Selection::add(unsigned int volume_idx, bool as_single_selection)
if (needs_reset)
clear();
if (volume->is_modifier)
m_mode = Volume;
else if (!contains_volume(volume_idx))
m_mode = Instance;
// else -> keep current mode
if (!contains_volume(volume_idx))
m_mode = volume->is_modifier ? Volume : Instance;
else
// keep current mode
return;
switch (m_mode)
{
case Volume:
{
if (volume->volume_idx() >= 0 && (is_empty() || (volume->instance_idx() == get_instance_idx())))
if ((volume->volume_idx() >= 0) && (is_empty() || (volume->instance_idx() == get_instance_idx())))
_add_volume(volume_idx);
break;
@ -439,6 +439,8 @@ void Selection::translate(const Vec3d& displacement, bool local)
if (!m_valid)
return;
EMode translation_type = m_mode;
for (unsigned int i : m_list)
{
if ((m_mode == Volume) || (*m_volumes)[i]->is_wipe_tower)
@ -452,13 +454,22 @@ void Selection::translate(const Vec3d& displacement, bool local)
}
}
else if (m_mode == Instance)
(*m_volumes)[i]->set_instance_offset(m_cache.volumes_data[i].get_instance_position() + displacement);
{
if (_is_from_fully_selected_instance(i))
(*m_volumes)[i]->set_instance_offset(m_cache.volumes_data[i].get_instance_position() + displacement);
else
{
Vec3d local_displacement = (m_cache.volumes_data[i].get_instance_rotation_matrix() * m_cache.volumes_data[i].get_instance_scale_matrix() * m_cache.volumes_data[i].get_instance_mirror_matrix()).inverse() * displacement;
(*m_volumes)[i]->set_volume_offset(m_cache.volumes_data[i].get_volume_position() + local_displacement);
translation_type = Volume;
}
}
}
#if !DISABLE_INSTANCES_SYNCH
if (m_mode == Instance)
if (translation_type == Instance)
_synchronize_unselected_instances(SYNC_ROTATION_NONE);
else if (m_mode == Volume)
else if (translation_type == Volume)
_synchronize_unselected_volumes();
#endif // !DISABLE_INSTANCES_SYNCH
@ -1683,5 +1694,29 @@ void Selection::_ensure_on_bed()
}
}
bool Selection::_is_from_fully_selected_instance(unsigned int volume_idx) const
{
struct SameInstance
{
int obj_idx;
int inst_idx;
GLVolumePtrs& volumes;
SameInstance(int obj_idx, int inst_idx, GLVolumePtrs& volumes) : obj_idx(obj_idx), inst_idx(inst_idx), volumes(volumes) {}
bool operator () (unsigned int i) { return (volumes[i]->object_idx() == obj_idx) && (volumes[i]->instance_idx() == inst_idx); }
};
if ((unsigned int)m_volumes->size() <= volume_idx)
return false;
GLVolume* volume = (*m_volumes)[volume_idx];
int object_idx = volume->object_idx();
if ((int)m_model->objects.size() <= object_idx)
return false;
unsigned int count = (unsigned int)std::count_if(m_list.begin(), m_list.end(), SameInstance(object_idx, volume->instance_idx(), *m_volumes));
return count == (unsigned int)m_model->objects[object_idx]->volumes.size();
}
} // namespace GUI
} // namespace Slic3r

View file

@ -297,6 +297,7 @@ private:
void _synchronize_unselected_instances(SyncRotationType sync_rotation_type);
void _synchronize_unselected_volumes();
void _ensure_on_bed();
bool _is_from_fully_selected_instance(unsigned int volume_idx) const;
};
} // namespace GUI