Improved Selection from ObjectList side
This commit is contained in:
parent
a71f05cdc0
commit
8631cb006b
@ -1639,16 +1639,20 @@ void ObjectList::part_selection_changed()
|
||||
bool update_and_show_manipulations = false;
|
||||
bool update_and_show_settings = false;
|
||||
|
||||
if (multiple_selection()) {
|
||||
const auto item = GetSelection();
|
||||
|
||||
if ( multiple_selection() || item && m_objects_model->GetItemType(item) == itInstanceRoot )
|
||||
{
|
||||
og_name = _(L("Group manipulation"));
|
||||
update_and_show_manipulations = true;
|
||||
|
||||
const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection();
|
||||
// don't show manipulation panel for case of all Object's parts selection
|
||||
update_and_show_manipulations = !selection.is_single_full_instance();
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto item = GetSelection();
|
||||
if (item)
|
||||
{
|
||||
bool is_part = false;
|
||||
if (m_objects_model->GetParent(item) == wxDataViewItem(0)) {
|
||||
obj_idx = m_objects_model->GetIdByItem(item);
|
||||
og_name = _(L("Object manipulation"));
|
||||
@ -1666,7 +1670,6 @@ void ObjectList::part_selection_changed()
|
||||
}
|
||||
else {
|
||||
og_name = _(L("Part Settings to modify"));
|
||||
is_part = true;
|
||||
auto main_parent = m_objects_model->GetParent(parent);
|
||||
obj_idx = m_objects_model->GetIdByItem(main_parent);
|
||||
const auto volume_id = m_objects_model->GetVolumeIdByItem(parent);
|
||||
@ -1676,7 +1679,6 @@ void ObjectList::part_selection_changed()
|
||||
}
|
||||
else if (m_objects_model->GetItemType(item) == itVolume) {
|
||||
og_name = _(L("Part manipulation"));
|
||||
is_part = true;
|
||||
const auto volume_id = m_objects_model->GetVolumeIdByItem(item);
|
||||
m_config = &(*m_objects)[obj_idx]->volumes[volume_id]->config;
|
||||
update_and_show_manipulations = true;
|
||||
@ -1924,6 +1926,15 @@ bool ObjectList::multiple_selection() const
|
||||
return GetSelectedItemsCount() > 1;
|
||||
}
|
||||
|
||||
bool ObjectList::is_selected(const ItemType type) const
|
||||
{
|
||||
const wxDataViewItem& item = GetSelection();
|
||||
if (item)
|
||||
return m_objects_model->GetItemType(item) == type;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ObjectList::update_selections()
|
||||
{
|
||||
const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection();
|
||||
@ -1942,25 +1953,64 @@ void ObjectList::update_selections()
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (selection.is_single_full_object())
|
||||
// if (selection.is_single_full_object() && selection.get_instance_idx() != -1)
|
||||
// {
|
||||
// sels.Add(m_objects_model->GetItemById(selection.get_object_idx()));
|
||||
// }
|
||||
// else if (selection.is_single_volume() || selection.is_modifier() ||
|
||||
// selection.is_multiple_volume() || selection.is_multiple_full_object())
|
||||
// {
|
||||
// for (auto idx : selection.get_volume_idxs()) {
|
||||
// const auto gl_vol = selection.get_volume(idx);
|
||||
// if (selection.is_multiple_full_object())
|
||||
// sels.Add(m_objects_model->GetItemById(gl_vol->object_idx()));
|
||||
// else if (gl_vol->volume_idx() >= 0)
|
||||
// // Only add GLVolumes with non-negative volume_ids. GLVolumes with negative volume ids
|
||||
// // are not associated with ModelVolumes, but they are temporarily generated by the backend
|
||||
// // (for example, SLA supports or SLA pad).
|
||||
// sels.Add(m_objects_model->GetItemByVolumeId(gl_vol->object_idx(), gl_vol->volume_idx()));
|
||||
// }
|
||||
// }
|
||||
else if (selection.is_single_full_object() || selection.is_multiple_full_object())
|
||||
{
|
||||
sels.Add(m_objects_model->GetItemById(selection.get_object_idx()));
|
||||
const Selection::ObjectIdxsToInstanceIdxsMap& objects_content = selection.get_content();
|
||||
for (const auto& object : objects_content) {
|
||||
if (object.second.size() == 1) // object with 1 instance
|
||||
sels.Add(m_objects_model->GetItemById(object.first));
|
||||
else if (object.second.size() > 1) // object with several instances
|
||||
{
|
||||
wxDataViewItemArray current_sels;
|
||||
GetSelections(current_sels);
|
||||
const wxDataViewItem frst_inst_item = m_objects_model->GetItemByInstanceId(object.first, 0);
|
||||
|
||||
bool root_is_selected = false;
|
||||
for (const auto& item:current_sels)
|
||||
if (item == m_objects_model->GetParent(frst_inst_item)) {
|
||||
root_is_selected = true;
|
||||
break;
|
||||
}
|
||||
if (root_is_selected)
|
||||
continue;
|
||||
|
||||
const Selection::InstanceIdxsList& instances = object.second;
|
||||
for (const auto& inst : instances)
|
||||
sels.Add(m_objects_model->GetItemByInstanceId(object.first, inst));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (selection.is_single_volume() || selection.is_modifier() ||
|
||||
selection.is_multiple_volume() || selection.is_multiple_full_object()) {
|
||||
else if (selection.is_single_volume() || selection.is_modifier() || selection.is_multiple_volume())
|
||||
{
|
||||
for (auto idx : selection.get_volume_idxs()) {
|
||||
const auto gl_vol = selection.get_volume(idx);
|
||||
if (selection.is_multiple_full_object())
|
||||
sels.Add(m_objects_model->GetItemById(gl_vol->object_idx()));
|
||||
else if (gl_vol->volume_idx() >= 0)
|
||||
if (gl_vol->volume_idx() >= 0)
|
||||
// Only add GLVolumes with non-negative volume_ids. GLVolumes with negative volume ids
|
||||
// are not associated with ModelVolumes, but they are temporarily generated by the backend
|
||||
// (for example, SLA supports or SLA pad).
|
||||
sels.Add(m_objects_model->GetItemByVolumeId(gl_vol->object_idx(), gl_vol->volume_idx()));
|
||||
}
|
||||
}
|
||||
else if (selection.is_single_full_instance() || selection.is_multiple_full_instance()) {
|
||||
else if (selection.is_single_full_instance() || selection.is_multiple_full_instance())
|
||||
{
|
||||
for (auto idx : selection.get_instance_idxs()) {
|
||||
sels.Add(m_objects_model->GetItemByInstanceId(selection.get_object_idx(), idx));
|
||||
}
|
||||
@ -2137,11 +2187,25 @@ void ObjectList::fix_multiselection_conflicts()
|
||||
wxDataViewItemArray sels;
|
||||
GetSelections(sels);
|
||||
|
||||
for (auto item : sels) {
|
||||
if (m_objects_model->GetItemType(item) & (itSettings|itInstanceRoot))
|
||||
for (const auto item : sels) {
|
||||
if (!IsSelected(item)) // if this item is unselected now (from previous actions)
|
||||
continue;
|
||||
|
||||
if (m_objects_model->GetItemType(item) & itSettings) {
|
||||
Unselect(item);
|
||||
else if (m_objects_model->GetParent(item) != wxDataViewItem(0))
|
||||
Unselect(m_objects_model->GetParent(item));
|
||||
continue;
|
||||
}
|
||||
|
||||
const wxDataViewItem& parent = m_objects_model->GetParent(item);
|
||||
if (parent != wxDataViewItem(0) && IsSelected(parent))
|
||||
Unselect(parent);
|
||||
else
|
||||
{
|
||||
wxDataViewItemArray unsels;
|
||||
m_objects_model->GetAllChildren(item, unsels);
|
||||
for (const auto unsel_item : unsels)
|
||||
Unselect(unsel_item);
|
||||
}
|
||||
}
|
||||
|
||||
m_prevent_list_events = false;
|
||||
|
@ -251,6 +251,7 @@ public:
|
||||
|
||||
void init_objects();
|
||||
bool multiple_selection() const ;
|
||||
bool is_selected(const ItemType type) const;
|
||||
void update_selections();
|
||||
void update_selections_on_canvas();
|
||||
void select_item(const wxDataViewItem& item);
|
||||
|
@ -161,6 +161,8 @@ void ObjectManipulation::update_settings_value(const Selection& selection)
|
||||
m_new_move_label_string = L("Position");
|
||||
m_new_rotate_label_string = L("Rotation");
|
||||
m_new_scale_label_string = L("Scale factors");
|
||||
|
||||
ObjectList* obj_list = wxGetApp().obj_list();
|
||||
if (selection.is_single_full_instance())
|
||||
{
|
||||
// all volumes in the selection belongs to the same instance, any of them contains the needed instance data, so we take the first one
|
||||
@ -187,7 +189,7 @@ void ObjectManipulation::update_settings_value(const Selection& selection)
|
||||
|
||||
m_new_enabled = true;
|
||||
}
|
||||
else if (selection.is_single_full_object())
|
||||
else if (selection.is_single_full_object() && obj_list->is_selected(itObject))
|
||||
{
|
||||
m_cache.instance.reset();
|
||||
|
||||
@ -212,7 +214,7 @@ void ObjectManipulation::update_settings_value(const Selection& selection)
|
||||
m_new_size = (volume->get_volume_transformation().get_matrix(true, true) * volume->bounding_box.size()).cwiseAbs();
|
||||
m_new_enabled = true;
|
||||
}
|
||||
else if (wxGetApp().obj_list()->multiple_selection())
|
||||
else if (obj_list->multiple_selection() || obj_list->is_selected(itInstanceRoot))
|
||||
{
|
||||
reset_settings_value();
|
||||
m_new_move_label_string = L("Translate");
|
||||
|
@ -133,10 +133,12 @@ private:
|
||||
const Transform3d& get_instance_full_matrix() const { return m_instance.full_matrix; }
|
||||
};
|
||||
|
||||
public:
|
||||
typedef std::map<unsigned int, VolumeCache> VolumesCache;
|
||||
typedef std::set<int> InstanceIdxsList;
|
||||
typedef std::map<int, InstanceIdxsList> ObjectIdxsToInstanceIdxsMap;
|
||||
|
||||
private:
|
||||
struct Cache
|
||||
{
|
||||
// Cache of GLVolume derived transformation matrices, valid during mouse dragging.
|
||||
|
@ -1238,6 +1238,32 @@ unsigned int PrusaObjectDataViewModel::GetChildren(const wxDataViewItem &parent,
|
||||
return count;
|
||||
}
|
||||
|
||||
void PrusaObjectDataViewModel::GetAllChildren(const wxDataViewItem &parent, wxDataViewItemArray &array) const
|
||||
{
|
||||
PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)parent.GetID();
|
||||
if (!node) {
|
||||
for (auto object : m_objects)
|
||||
array.Add(wxDataViewItem((void*)object));
|
||||
}
|
||||
else if (node->GetChildCount() == 0)
|
||||
return;
|
||||
else {
|
||||
const size_t count = node->GetChildren().GetCount();
|
||||
for (size_t pos = 0; pos < count; pos++) {
|
||||
PrusaObjectDataViewModelNode *child = node->GetChildren().Item(pos);
|
||||
array.Add(wxDataViewItem((void*)child));
|
||||
}
|
||||
}
|
||||
|
||||
wxDataViewItemArray new_array = array;
|
||||
for (const auto item : new_array)
|
||||
{
|
||||
wxDataViewItemArray children;
|
||||
GetAllChildren(item, children);
|
||||
WX_APPEND_ARRAY(array, children);
|
||||
}
|
||||
}
|
||||
|
||||
ItemType PrusaObjectDataViewModel::GetItemType(const wxDataViewItem &item) const
|
||||
{
|
||||
if (!item.IsOk())
|
||||
|
@ -511,7 +511,7 @@ public:
|
||||
virtual bool IsContainer(const wxDataViewItem &item) const override;
|
||||
virtual unsigned int GetChildren(const wxDataViewItem &parent,
|
||||
wxDataViewItemArray &array) const override;
|
||||
|
||||
void GetAllChildren(const wxDataViewItem &parent,wxDataViewItemArray &array) const;
|
||||
// Is the container just a header or an item with all columns
|
||||
// In our case it is an item with all columns
|
||||
virtual bool HasContainerColumns(const wxDataViewItem& WXUNUSED(item)) const override { return true; }
|
||||
|
Loading…
Reference in New Issue
Block a user