Extended interface for selections

This commit is contained in:
Enrico Turri 2018-10-11 08:26:12 +02:00
parent 37dd32b62b
commit 3bccb3b97c
2 changed files with 150 additions and 64 deletions

View file

@ -1162,13 +1162,13 @@ GLCanvas3D::Selection::Selection()
void GLCanvas3D::Selection::set_volumes(GLVolumePtrs* volumes) void GLCanvas3D::Selection::set_volumes(GLVolumePtrs* volumes)
{ {
m_volumes = volumes; m_volumes = volumes;
update_valid(); _update_valid();
} }
void GLCanvas3D::Selection::set_model(Model* model) void GLCanvas3D::Selection::set_model(Model* model)
{ {
m_model = model; m_model = model;
update_valid(); _update_valid();
} }
void GLCanvas3D::Selection::add(unsigned int volume_idx, bool as_single_selection) void GLCanvas3D::Selection::add(unsigned int volume_idx, bool as_single_selection)
@ -1185,22 +1185,22 @@ void GLCanvas3D::Selection::add(unsigned int volume_idx, bool as_single_selectio
{ {
case Volume: case Volume:
{ {
add_volume(volume_idx); _add_volume(volume_idx);
break; break;
} }
case Instance: case Instance:
{ {
add_instance(volume_idx); _add_instance(volume->object_idx(), volume->instance_idx());
break; break;
} }
case Object: case Object:
{ {
add_object(volume_idx); _add_object(volume->object_idx());
break; break;
} }
} }
update_type(); _update_type();
m_bounding_box_dirty = true; m_bounding_box_dirty = true;
} }
@ -1209,26 +1209,116 @@ void GLCanvas3D::Selection::remove(unsigned int volume_idx)
if (!m_valid || ((unsigned int)m_volumes->size() <= volume_idx)) if (!m_valid || ((unsigned int)m_volumes->size() <= volume_idx))
return; return;
GLVolume* volume = (*m_volumes)[volume_idx];
switch (m_mode) switch (m_mode)
{ {
case Volume: case Volume:
{ {
remove_volume(volume_idx); _remove_volume(volume_idx);
break; break;
} }
case Instance: case Instance:
{ {
remove_instance(volume_idx); _remove_instance(volume->object_idx(), volume->instance_idx());
break; break;
} }
case Object: case Object:
{ {
remove_object(volume_idx); _remove_object(volume->object_idx());
break; break;
} }
} }
update_type(); _update_type();
m_bounding_box_dirty = true;
}
void GLCanvas3D::Selection::add_object(unsigned int object_idx, bool as_single_selection)
{
if (!m_valid)
return;
// resets the current list if needed
if (as_single_selection)
clear();
_add_object(object_idx);
_update_type();
m_bounding_box_dirty = true;
}
void GLCanvas3D::Selection::remove_object(unsigned int object_idx)
{
if (!m_valid)
return;
_remove_object(object_idx);
_update_type();
m_bounding_box_dirty = true;
}
void GLCanvas3D::Selection::add_instance(unsigned int object_idx, unsigned int instance_idx, bool as_single_selection)
{
if (!m_valid)
return;
// resets the current list if needed
if (as_single_selection)
clear();
_add_instance(object_idx, instance_idx);
_update_type();
m_bounding_box_dirty = true;
}
void GLCanvas3D::Selection::remove_instance(unsigned int object_idx, unsigned int instance_idx)
{
if (!m_valid)
return;
_remove_instance(object_idx, instance_idx);
_update_type();
m_bounding_box_dirty = true;
}
void GLCanvas3D::Selection::add_volume(unsigned int object_idx, unsigned int volume_idx, bool as_single_selection)
{
if (!m_valid)
return;
// resets the current list if needed
if (as_single_selection)
clear();
for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i)
{
GLVolume* v = (*m_volumes)[i];
if ((v->object_idx() == object_idx) && (v->volume_idx() == volume_idx))
_add_volume(i);
}
_update_type();
m_bounding_box_dirty = true;
}
void GLCanvas3D::Selection::remove_volume(unsigned int object_idx, unsigned int volume_idx)
{
if (!m_valid)
return;
for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i)
{
GLVolume* v = (*m_volumes)[i];
if ((v->object_idx() == object_idx) && (v->volume_idx() == volume_idx))
_remove_volume(i);
}
_update_type();
m_bounding_box_dirty = true; m_bounding_box_dirty = true;
} }
@ -1243,7 +1333,7 @@ void GLCanvas3D::Selection::clear()
} }
m_list.clear(); m_list.clear();
update_type(); _update_type();
m_bounding_box_dirty = true; m_bounding_box_dirty = true;
} }
@ -1287,7 +1377,7 @@ const GLVolume* GLCanvas3D::Selection::get_volume(unsigned int volume_idx) const
const BoundingBoxf3& GLCanvas3D::Selection::get_bounding_box() const const BoundingBoxf3& GLCanvas3D::Selection::get_bounding_box() const
{ {
if (m_bounding_box_dirty) if (m_bounding_box_dirty)
calc_bounding_box(); _calc_bounding_box();
return m_bounding_box; return m_bounding_box;
} }
@ -1297,7 +1387,7 @@ void GLCanvas3D::Selection::start_dragging()
if (!m_valid) if (!m_valid)
return; return;
set_caches(); _set_caches();
} }
void GLCanvas3D::Selection::translate(const Vec3d& displacement) void GLCanvas3D::Selection::translate(const Vec3d& displacement)
@ -1362,7 +1452,7 @@ void GLCanvas3D::Selection::rotate(const Vec3d& rotation)
} }
if (m_mode == Instance) if (m_mode == Instance)
synchronize_unselected_instances(); _synchronize_unselected_instances();
m_bounding_box_dirty = true; m_bounding_box_dirty = true;
} }
@ -1373,19 +1463,19 @@ void GLCanvas3D::Selection::render(bool show_indirect_selection) const
return; return;
// render cumulative bounding box of selected volumes // render cumulative bounding box of selected volumes
render_selected_volumes(); _render_selected_volumes();
// render bounding boxes of indirectly selected instances // render bounding boxes of indirectly selected instances
if (show_indirect_selection && (m_mode == Instance)) if (show_indirect_selection && (m_mode == Instance))
render_unselected_instances(); _render_unselected_instances();
} }
void GLCanvas3D::Selection::update_valid() void GLCanvas3D::Selection::_update_valid()
{ {
m_valid = (m_volumes != nullptr) && (m_model != nullptr); m_valid = (m_volumes != nullptr) && (m_model != nullptr);
} }
void GLCanvas3D::Selection::update_type() void GLCanvas3D::Selection::_update_type()
{ {
m_cache.content.clear(); m_cache.content.clear();
m_type = Mixed; m_type = Mixed;
@ -1481,7 +1571,7 @@ void GLCanvas3D::Selection::update_type()
} }
} }
void GLCanvas3D::Selection::set_caches() void GLCanvas3D::Selection::_set_caches()
{ {
m_cache.volumes_data.clear(); m_cache.volumes_data.clear();
for (unsigned int i : m_list) for (unsigned int i : m_list)
@ -1492,7 +1582,7 @@ void GLCanvas3D::Selection::set_caches()
m_cache.dragging_center = get_bounding_box().center(); m_cache.dragging_center = get_bounding_box().center();
} }
void GLCanvas3D::Selection::add_volume(unsigned int volume_idx) void GLCanvas3D::Selection::_add_volume(unsigned int volume_idx)
{ {
// check if the given idx is already selected // check if the given idx is already selected
if (m_list.find(volume_idx) != m_list.end()) if (m_list.find(volume_idx) != m_list.end())
@ -1502,34 +1592,27 @@ void GLCanvas3D::Selection::add_volume(unsigned int volume_idx)
(*m_volumes)[volume_idx]->selected = true; (*m_volumes)[volume_idx]->selected = true;
} }
void GLCanvas3D::Selection::add_instance(unsigned int volume_idx) void GLCanvas3D::Selection::_add_instance(unsigned int object_idx, unsigned int instance_idx)
{ {
GLVolume* volume = (*m_volumes)[volume_idx];
int object_idx = volume->object_idx();
int instance_idx = volume->instance_idx();
for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i)
{ {
GLVolume* v = (*m_volumes)[i]; GLVolume* v = (*m_volumes)[i];
if ((v->object_idx() == object_idx) && (v->instance_idx() == instance_idx)) if ((v->object_idx() == object_idx) && (v->instance_idx() == instance_idx))
add_volume(i); _add_volume(i);
} }
} }
void GLCanvas3D::Selection::add_object(unsigned int volume_idx) void GLCanvas3D::Selection::_add_object(unsigned int object_idx)
{ {
GLVolume* volume = (*m_volumes)[volume_idx];
int object_idx = volume->object_idx();
for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i)
{ {
GLVolume* v = (*m_volumes)[i]; GLVolume* v = (*m_volumes)[i];
if (v->object_idx() == object_idx) if (v->object_idx() == object_idx)
add_volume(i); _add_volume(i);
} }
} }
void GLCanvas3D::Selection::remove_volume(unsigned int volume_idx) void GLCanvas3D::Selection::_remove_volume(unsigned int volume_idx)
{ {
IndicesList::iterator v_it = m_list.find(volume_idx); IndicesList::iterator v_it = m_list.find(volume_idx);
if (v_it == m_list.end()) if (v_it == m_list.end())
@ -1540,34 +1623,27 @@ void GLCanvas3D::Selection::remove_volume(unsigned int volume_idx)
(*m_volumes)[volume_idx]->selected = false; (*m_volumes)[volume_idx]->selected = false;
} }
void GLCanvas3D::Selection::remove_instance(unsigned int volume_idx) void GLCanvas3D::Selection::_remove_instance(unsigned int object_idx, unsigned int instance_idx)
{ {
GLVolume* volume = (*m_volumes)[volume_idx];
int object_idx = volume->object_idx();
int instance_idx = volume->instance_idx();
for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i)
{ {
GLVolume* v = (*m_volumes)[i]; GLVolume* v = (*m_volumes)[i];
if ((v->object_idx() == object_idx) && (v->instance_idx() == instance_idx)) if ((v->object_idx() == object_idx) && (v->instance_idx() == instance_idx))
remove_volume(i); _remove_volume(i);
} }
} }
void GLCanvas3D::Selection::remove_object(unsigned int volume_idx) void GLCanvas3D::Selection::_remove_object(unsigned int object_idx)
{ {
GLVolume* volume = (*m_volumes)[volume_idx];
int object_idx = volume->object_idx();
for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i)
{ {
GLVolume* v = (*m_volumes)[i]; GLVolume* v = (*m_volumes)[i];
if (v->object_idx() == object_idx) if (v->object_idx() == object_idx)
remove_volume(i); _remove_volume(i);
} }
} }
void GLCanvas3D::Selection::calc_bounding_box() const void GLCanvas3D::Selection::_calc_bounding_box() const
{ {
m_bounding_box = BoundingBoxf3(); m_bounding_box = BoundingBoxf3();
if (m_valid) if (m_valid)
@ -1580,13 +1656,13 @@ void GLCanvas3D::Selection::calc_bounding_box() const
m_bounding_box_dirty = false; m_bounding_box_dirty = false;
} }
void GLCanvas3D::Selection::render_selected_volumes() const void GLCanvas3D::Selection::_render_selected_volumes() const
{ {
float color[3] = { 1.0f, 1.0f, 1.0f }; float color[3] = { 1.0f, 1.0f, 1.0f };
render_bounding_box(get_bounding_box(), color); _render_bounding_box(get_bounding_box(), color);
} }
void GLCanvas3D::Selection::render_unselected_instances() const void GLCanvas3D::Selection::_render_unselected_instances() const
{ {
std::set<unsigned int> done; // prevent processing volumes twice std::set<unsigned int> done; // prevent processing volumes twice
done.insert(m_list.begin(), m_list.end()); done.insert(m_list.begin(), m_list.end());
@ -1632,11 +1708,11 @@ void GLCanvas3D::Selection::render_unselected_instances() const
float color[3] = { 1.0f, 1.0f, 0.0f }; float color[3] = { 1.0f, 1.0f, 0.0f };
for (const InstanceToBoxMap::value_type& box : boxes) for (const InstanceToBoxMap::value_type& box : boxes)
{ {
render_bounding_box(box.second, color); _render_bounding_box(box.second, color);
} }
} }
void GLCanvas3D::Selection::render_bounding_box(const BoundingBoxf3& box, float* color) const void GLCanvas3D::Selection::_render_bounding_box(const BoundingBoxf3& box, float* color) const
{ {
if (color == nullptr) if (color == nullptr)
return; return;
@ -1686,7 +1762,7 @@ void GLCanvas3D::Selection::render_bounding_box(const BoundingBoxf3& box, float*
::glEnd(); ::glEnd();
} }
void GLCanvas3D::Selection::synchronize_unselected_instances() void GLCanvas3D::Selection::_synchronize_unselected_instances()
{ {
std::set<unsigned int> done; // prevent processing volumes twice std::set<unsigned int> done; // prevent processing volumes twice
done.insert(m_list.begin(), m_list.end()); done.insert(m_list.begin(), m_list.end());

View file

@ -455,6 +455,16 @@ public:
void add(unsigned int volume_idx, bool as_single_selection = true); void add(unsigned int volume_idx, bool as_single_selection = true);
void remove(unsigned int volume_idx); void remove(unsigned int volume_idx);
void add_object(unsigned int object_idx, bool as_single_selection = true);
void remove_object(unsigned int object_idx);
void add_instance(unsigned int object_idx, unsigned int instance_idx, bool as_single_selection = true);
void remove_instance(unsigned int object_idx, unsigned int instance_idx);
void add_volume(unsigned int object_idx, unsigned int volume_idx, bool as_single_selection = true);
void remove_volume(unsigned int object_idx, unsigned int volume_idx);
void clear(); void clear();
bool is_empty() const { return m_type == Empty; } bool is_empty() const { return m_type == Empty; }
@ -485,20 +495,20 @@ public:
void render(bool show_indirect_selection) const; void render(bool show_indirect_selection) const;
private: private:
void update_valid(); void _update_valid();
void update_type(); void _update_type();
void set_caches(); void _set_caches();
void add_volume(unsigned int volume_idx); void _add_volume(unsigned int volume_idx);
void add_instance(unsigned int volume_idx); void _add_instance(unsigned int object_idx, unsigned int instance_idx);
void add_object(unsigned int volume_idx); void _add_object(unsigned int object_idx);
void remove_volume(unsigned int volume_idx); void _remove_volume(unsigned int volume_idx);
void remove_instance(unsigned int volume_idx); void _remove_instance(unsigned int object_idx, unsigned int instance_idx);
void remove_object(unsigned int volume_idx); void _remove_object(unsigned int object_idx);
void calc_bounding_box() const; void _calc_bounding_box() const;
void render_selected_volumes() const; void _render_selected_volumes() const;
void render_unselected_instances() const; void _render_unselected_instances() const;
void render_bounding_box(const BoundingBoxf3& box, float* color) const; void _render_bounding_box(const BoundingBoxf3& box, float* color) const;
void synchronize_unselected_instances(); void _synchronize_unselected_instances();
}; };
private: private: