Fix dragging of mixed instances plus volumes selections
This commit is contained in:
parent
9821814604
commit
d4b22cfb87
2 changed files with 45 additions and 9 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue