diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index ae43369d2..2d9078c6d 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -41,4 +41,8 @@ #define ENABLE_TEXTURES_FROM_SVG (1 && ENABLE_1_42_0_ALPHA7) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#define ENABLE_SELECTION_UNDO_REDO 1 +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + #endif // _technologies_h_ diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 38c0315ab..4f1279798 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1723,8 +1723,16 @@ void GLCanvas3D::select_all() void GLCanvas3D::deselect_all() { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SELECTION_UNDO_REDO + m_selection.remove_all(); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_selection.clear(); m_selection.set_mode(Selection::Instance); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ wxGetApp().obj_manipul()->set_dirty(); m_gizmos.reset_all_states(); m_gizmos.update_data(); @@ -5661,7 +5669,15 @@ void GLCanvas3D::_update_selection_from_hover() if (m_hover_volume_idxs.empty()) { if (!ctrl_pressed && (m_rectangle_selection.get_state() == GLSelectionRectangle::Select)) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SELECTION_UNDO_REDO + m_selection.remove_all(); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ m_selection.clear(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ return; } @@ -5678,6 +5694,55 @@ void GLCanvas3D::_update_selection_from_hover() } } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SELECTION_UNDO_REDO + bool selection_changed = false; + if (state == GLSelectionRectangle::Select) + { + bool contains_all = true; + for (int i : m_hover_volume_idxs) + { + if (!m_selection.contains_volume((unsigned int)i)) + { + contains_all = false; + break; + } + } + + // the selection is going to be modified (Add) + if (!contains_all) + { + wxGetApp().plater()->take_snapshot(_(L("Selection - Add - _update_selection_from_hover()"))); + selection_changed = true; + } + } + else + { + bool contains_any = false; + for (int i : m_hover_volume_idxs) + { + if (m_selection.contains_volume((unsigned int)i)) + { + contains_any = true; + break; + } + } + + // the selection is going to be modified (Remove) + if (contains_any) + { + wxGetApp().plater()->take_snapshot(_(L("Selection - Remove - _update_selection_from_hover()"))); + selection_changed = true; + } + } + + if (!selection_changed) + return; + + Plater::SuppressSnapshots suppress(wxGetApp().plater()); +#endif // ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + if ((state == GLSelectionRectangle::Select) && !ctrl_pressed) m_selection.clear(); diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index a2ddba376..882636f1c 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -2759,26 +2759,75 @@ void ObjectList::update_selections_on_canvas() const int sel_cnt = GetSelectedItemsCount(); if (sel_cnt == 0) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SELECTION_UNDO_REDO + selection.remove_all(); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ selection.clear(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ wxGetApp().plater()->canvas3D()->update_gizmos_on_off_state(); return; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SELECTION_UNDO_REDO + std::vector volume_idxs; + Selection::EMode mode = Selection::Volume; + auto add_to_selection = [this, &volume_idxs](const wxDataViewItem& item, const Selection& selection, int instance_idx, Selection::EMode& mode) +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ auto add_to_selection = [this](const wxDataViewItem& item, Selection& selection, int instance_idx, bool as_single_selection) +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ { const ItemType& type = m_objects_model->GetItemType(item); const int obj_idx = m_objects_model->GetObjectIdByItem(item); if (type == itVolume) { const int vol_idx = m_objects_model->GetVolumeIdByItem(item); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SELECTION_UNDO_REDO + std::vector idxs = selection.get_volume_idxs_from_volume(obj_idx, std::max(instance_idx, 0), vol_idx); + volume_idxs.insert(volume_idxs.end(), idxs.begin(), idxs.end()); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ selection.add_volume(obj_idx, vol_idx, std::max(instance_idx, 0), as_single_selection); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } else if (type == itInstance) { const int inst_idx = m_objects_model->GetInstanceIdByItem(item); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SELECTION_UNDO_REDO + mode = Selection::Instance; + std::vector idxs = selection.get_volume_idxs_from_instance(obj_idx, inst_idx); + volume_idxs.insert(volume_idxs.end(), idxs.begin(), idxs.end()); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ selection.add_instance(obj_idx, inst_idx, as_single_selection); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SELECTION_UNDO_REDO + { + mode = Selection::Instance; + std::vector idxs = selection.get_volume_idxs_from_object(obj_idx); + volume_idxs.insert(volume_idxs.end(), idxs.begin(), idxs.end()); + } +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ selection.add_object(obj_idx, as_single_selection); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ }; // stores current instance idx before to clear the selection @@ -2786,6 +2835,14 @@ void ObjectList::update_selections_on_canvas() if (sel_cnt == 1) { wxDataViewItem item = GetSelection(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SELECTION_UNDO_REDO + if (m_objects_model->GetItemType(item) & (itSettings | itInstanceRoot | itLayerRoot | itLayer)) + add_to_selection(m_objects_model->GetParent(item), selection, instance_idx, mode); + else + add_to_selection(item, selection, instance_idx, mode); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (m_objects_model->GetItemType(item) & (itSettings | itInstanceRoot | itLayerRoot | itLayer)) add_to_selection(m_objects_model->GetParent(item), selection, instance_idx, true); else @@ -2794,14 +2851,53 @@ void ObjectList::update_selections_on_canvas() wxGetApp().plater()->canvas3D()->update_gizmos_on_off_state(); wxGetApp().plater()->canvas3D()->render(); return; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } - +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SELECTION_UNDO_REDO + else + { + wxDataViewItemArray sels; + GetSelections(sels); + + for (auto item : sels) + { + add_to_selection(item, selection, instance_idx, mode); + } + } + + if (selection.contains_all_volumes(volume_idxs)) + { + // remove + volume_idxs = selection.get_missing_volume_idxs_from(volume_idxs); + if (volume_idxs.size() > 0) + { +// std::cout << "ObjectList- > Selection-Remove " << volume_idxs.size() << " volumes" << std::endl; + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("Selection - Remove - update_selections_on_canvas()"))); + selection.remove_volumes(mode, volume_idxs); + } + } + else + { + // add + volume_idxs = selection.get_unselected_volume_idxs_from(volume_idxs); +// std::cout << "ObjectList- > Selection-Add " << volume_idxs.size() << " volumes - mode: " << ((mode == Selection::Volume) ? "Volume" : "Instance") << std::endl; + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("Selection - Add - update_selections_on_canvas()"))); + selection.add_volumes(mode, volume_idxs, sel_cnt == 1); + } +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ wxDataViewItemArray sels; GetSelections(sels); selection.clear(); for (auto item: sels) add_to_selection(item, selection, instance_idx, false); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ wxGetApp().plater()->canvas3D()->update_gizmos_on_off_state(); wxGetApp().plater()->canvas3D()->render(); diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index b990f28b8..4dfe445cb 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -140,11 +140,26 @@ void Selection::add(unsigned int volume_idx, bool as_single_selection, bool chec needs_reset |= as_single_selection && !is_any_modifier() && volume->is_modifier; needs_reset |= is_any_modifier() && !volume->is_modifier; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (needs_reset) clear(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if (!already_contained || needs_reset) { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SELECTION_UNDO_REDO + wxGetApp().plater()->take_snapshot(_(L("Selection - Add - add()"))); + + if (needs_reset) + clear(); +#endif // ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + if (!keep_instance_mode) m_mode = volume->is_modifier ? Volume : Instance; } @@ -163,7 +178,16 @@ void Selection::add(unsigned int volume_idx, bool as_single_selection, bool chec } case Instance: { +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SELECTION_UNDO_REDO + Plater::SuppressSnapshots suppress(wxGetApp().plater()); + add_instance(volume->object_idx(), volume->instance_idx(), as_single_selection); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ do_add_instance(volume->object_idx(), volume->instance_idx()); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ break; } } @@ -177,6 +201,15 @@ void Selection::remove(unsigned int volume_idx) if (!m_valid || ((unsigned int)m_volumes->size() <= volume_idx)) return; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SELECTION_UNDO_REDO + if (!contains_volume(volume_idx)) + return; + + wxGetApp().plater()->take_snapshot(_(L("Selection - Remove - remove()"))); +#endif // ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + GLVolume* volume = (*m_volumes)[volume_idx]; switch (m_mode) @@ -202,13 +235,32 @@ void Selection::add_object(unsigned int object_idx, bool as_single_selection) if (!m_valid) return; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SELECTION_UNDO_REDO + std::vector volume_idxs = get_volume_idxs_from_object(object_idx); + if ((!as_single_selection && contains_all_volumes(volume_idxs)) || + (as_single_selection && matches(volume_idxs))) + return; + + wxGetApp().plater()->take_snapshot(_(L("Selection - Add - add_object()"))); +#endif // ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + // resets the current list if needed if (as_single_selection) clear(); m_mode = Instance; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SELECTION_UNDO_REDO + do_add_volumes(volume_idxs); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ do_add_object(object_idx); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ update_type(); this->set_bounding_boxes_dirty(); @@ -219,6 +271,12 @@ void Selection::remove_object(unsigned int object_idx) if (!m_valid) return; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SELECTION_UNDO_REDO + wxGetApp().plater()->take_snapshot(_(L("Selection - Remove - remove_object()"))); +#endif // ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + do_remove_object(object_idx); update_type(); @@ -230,13 +288,32 @@ void Selection::add_instance(unsigned int object_idx, unsigned int instance_idx, if (!m_valid) return; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SELECTION_UNDO_REDO + std::vector volume_idxs = get_volume_idxs_from_instance(object_idx, instance_idx); + if ((!as_single_selection && contains_all_volumes(volume_idxs)) || + (as_single_selection && matches(volume_idxs))) + return; + + wxGetApp().plater()->take_snapshot(_(L("Selection - Add - add_instance()"))); +#endif // ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + // resets the current list if needed if (as_single_selection) clear(); m_mode = Instance; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SELECTION_UNDO_REDO + do_add_volumes(volume_idxs); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ do_add_instance(object_idx, instance_idx); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ update_type(); this->set_bounding_boxes_dirty(); @@ -247,6 +324,12 @@ void Selection::remove_instance(unsigned int object_idx, unsigned int instance_i if (!m_valid) return; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SELECTION_UNDO_REDO + wxGetApp().plater()->take_snapshot(_(L("Selection - Remove - remove_instance()"))); +#endif // ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + do_remove_instance(object_idx, instance_idx); update_type(); @@ -258,12 +341,28 @@ void Selection::add_volume(unsigned int object_idx, unsigned int volume_idx, int if (!m_valid) return; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SELECTION_UNDO_REDO + std::vector volume_idxs = get_volume_idxs_from_volume(object_idx, instance_idx, volume_idx); + if ((!as_single_selection && contains_all_volumes(volume_idxs)) || + (as_single_selection && matches(volume_idxs))) + return; + + wxGetApp().plater()->take_snapshot(_(L("Selection - Add - add_volume()"))); +#endif // ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + // resets the current list if needed if (as_single_selection) clear(); m_mode = Volume; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SELECTION_UNDO_REDO + do_add_volumes(volume_idxs); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) { GLVolume* v = (*m_volumes)[i]; @@ -273,6 +372,9 @@ void Selection::add_volume(unsigned int object_idx, unsigned int volume_idx, int do_add_volume(i); } } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ update_type(); this->set_bounding_boxes_dirty(); @@ -283,6 +385,12 @@ void Selection::remove_volume(unsigned int object_idx, unsigned int volume_idx) if (!m_valid) return; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SELECTION_UNDO_REDO + wxGetApp().plater()->take_snapshot(_(L("Selection - Remove - remove_volume()"))); +#endif // ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) { GLVolume* v = (*m_volumes)[i]; @@ -294,11 +402,76 @@ void Selection::remove_volume(unsigned int object_idx, unsigned int volume_idx) this->set_bounding_boxes_dirty(); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SELECTION_UNDO_REDO +void Selection::add_volumes(EMode mode, const std::vector& volume_idxs, bool as_single_selection) +{ + if (!m_valid) + return; + + if ((!as_single_selection && contains_all_volumes(volume_idxs)) || + (as_single_selection && matches(volume_idxs))) + return; + + wxGetApp().plater()->take_snapshot(_(L("Selection - Add - add_volumes()"))); + + // resets the current list if needed + if (as_single_selection) + clear(); + + m_mode = mode; + for (unsigned int i : volume_idxs) + { + if (i < (unsigned int)m_volumes->size()) + do_add_volume(i); + } +// do_add_volumes(volume_idxs); + + update_type(); + this->set_bounding_boxes_dirty(); +} + +void Selection::remove_volumes(EMode mode, const std::vector& volume_idxs) +{ + if (!m_valid) + return; + + wxGetApp().plater()->take_snapshot(_(L("Selection - Remove - remove_volumes()"))); + + m_mode = mode; + for (unsigned int i : volume_idxs) + { + if (i < (unsigned int)m_volumes->size()) + do_remove_volume(i); + } + + update_type(); + this->set_bounding_boxes_dirty(); +} +#endif // ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + void Selection::add_all() { if (!m_valid) return; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SELECTION_UNDO_REDO + unsigned int count = 0; + for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) + { + if (!(*m_volumes)[i]->is_wipe_tower) + ++count; + } + + if ((unsigned int)m_list.size() == count) + return; + + wxGetApp().plater()->take_snapshot(_(L("Selection - Add - add_all()"))); +#endif // ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + m_mode = Instance; clear(); @@ -312,6 +485,24 @@ void Selection::add_all() this->set_bounding_boxes_dirty(); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SELECTION_UNDO_REDO +void Selection::remove_all() +{ + if (!m_valid) + return; + + if (is_empty()) + return; + + wxGetApp().plater()->take_snapshot(_(L("Selection - Remove - remove_all()"))); + + m_mode = Instance; + clear(); +} +#endif // ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + void Selection::set_deserialized(EMode mode, const std::vector> &volumes_and_instances) { if (! m_valid) @@ -439,6 +630,47 @@ bool Selection::is_sla_compliant() const return true; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SELECTION_UNDO_REDO +bool Selection::contains_all_volumes(const std::vector& volume_idxs) const +{ + for (unsigned int i : volume_idxs) + { + if (m_list.find(i) == m_list.end()) + return false; + } + + return true; +} + +bool Selection::contains_any_volume(const std::vector& volume_idxs) const +{ + for (unsigned int i : volume_idxs) + { + if (m_list.find(i) != m_list.end()) + return true; + } + + return false; +} + +bool Selection::matches(const std::vector& volume_idxs) const +{ + unsigned int count = 0; + + for (unsigned int i : volume_idxs) + { + if (m_list.find(i) != m_list.end()) + ++count; + else + return false; + } + + return count == (unsigned int)m_list.size(); +} +#endif // ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + bool Selection::requires_uniform_scale() const { if (is_single_full_instance() || is_single_modifier() || is_single_volume()) @@ -1253,6 +1485,81 @@ void Selection::paste_from_clipboard() } } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SELECTION_UNDO_REDO +std::vector Selection::get_volume_idxs_from_object(unsigned int object_idx) const +{ + std::vector idxs; + + for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) + { + if ((*m_volumes)[i]->object_idx() == object_idx) + idxs.push_back(i); + } + + return idxs; +} + +std::vector Selection::get_volume_idxs_from_instance(unsigned int object_idx, unsigned int instance_idx) const +{ + std::vector idxs; + + for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) + { + const GLVolume* v = (*m_volumes)[i]; + if ((v->object_idx() == object_idx) && (v->instance_idx() == instance_idx)) + idxs.push_back(i); + } + + return idxs; +} + +std::vector Selection::get_volume_idxs_from_volume(unsigned int object_idx, unsigned int instance_idx, unsigned int volume_idx) const +{ + std::vector idxs; + + for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) + { + const GLVolume* v = (*m_volumes)[i]; + if ((v->object_idx() == object_idx) && (v->volume_idx() == volume_idx)) + { + if ((instance_idx != -1) && (v->instance_idx() == instance_idx)) + idxs.push_back(i); + } + } + + return idxs; +} + +std::vector Selection::get_missing_volume_idxs_from(const std::vector& volume_idxs) const +{ + std::vector idxs; + + for (unsigned int i : m_list) + { + std::vector::const_iterator it = std::find(volume_idxs.begin(), volume_idxs.end(), i); + if (it == volume_idxs.end()) + idxs.push_back(i); + } + + return idxs; +} + +std::vector Selection::get_unselected_volume_idxs_from(const std::vector& volume_idxs) const +{ + std::vector idxs; + + for (unsigned int i : volume_idxs) + { + if (m_list.find(i) == m_list.end()) + idxs.push_back(i); + } + + return idxs; +} +#endif // ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + void Selection::update_valid() { m_valid = (m_volumes != nullptr) && (m_model != nullptr); @@ -1499,6 +1806,18 @@ void Selection::do_add_volume(unsigned int volume_idx) (*m_volumes)[volume_idx]->selected = true; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SELECTION_UNDO_REDO +void Selection::do_add_volumes(const std::vector& volume_idxs) +{ + for (unsigned int i : volume_idxs) + { + if (i < (unsigned int)m_volumes->size()) + do_add_volume(i); + } +} +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void Selection::do_add_instance(unsigned int object_idx, unsigned int instance_idx) { for (unsigned int i = 0; i < (unsigned int)m_volumes->size(); ++i) @@ -1518,6 +1837,9 @@ void Selection::do_add_object(unsigned int object_idx) do_add_volume(i); } } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void Selection::do_remove_volume(unsigned int volume_idx) { diff --git a/src/slic3r/GUI/Selection.hpp b/src/slic3r/GUI/Selection.hpp index 915a8c855..2a96985c3 100644 --- a/src/slic3r/GUI/Selection.hpp +++ b/src/slic3r/GUI/Selection.hpp @@ -235,7 +235,19 @@ public: void add_volume(unsigned int object_idx, unsigned int volume_idx, int instance_idx, bool as_single_selection = true); void remove_volume(unsigned int object_idx, unsigned int volume_idx); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SELECTION_UNDO_REDO + void add_volumes(EMode mode, const std::vector& volume_idxs, bool as_single_selection = true); + void remove_volumes(EMode mode, const std::vector& volume_idxs); +#endif // ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + void add_all(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SELECTION_UNDO_REDO + void remove_all(); +#endif // ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // To be called after Undo or Redo once the volumes are updated. void set_deserialized(EMode mode, const std::vector> &volumes_and_instances); @@ -265,6 +277,17 @@ public: bool is_sla_compliant() const; bool contains_volume(unsigned int volume_idx) const { return m_list.find(volume_idx) != m_list.end(); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SELECTION_UNDO_REDO + // returns true if the selection contains all the given indices + bool contains_all_volumes(const std::vector& volume_idxs) const; + // returns true if the selection contains at least one of the given indices + bool contains_any_volume(const std::vector& volume_idxs) const; + // returns true if the selection contains all and only the given indices + bool matches(const std::vector& volume_idxs) const; +#endif // ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + bool requires_uniform_scale() const; // Returns the the object id if the selection is from a single object, otherwise is -1 @@ -314,13 +337,36 @@ public: const Clipboard& get_clipboard() const { return m_clipboard; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SELECTION_UNDO_REDO + // returns the list of idxs of the volumes contained into the object with the given idx + std::vector get_volume_idxs_from_object(unsigned int object_idx) const; + // returns the list of idxs of the volumes contained into the instance with the given idxs + std::vector get_volume_idxs_from_instance(unsigned int object_idx, unsigned int instance_idx) const; + // returns the idx of the volume corresponding to the volume with the given idxs + std::vector get_volume_idxs_from_volume(unsigned int object_idx, unsigned int instance_idx, unsigned int volume_idx) const; + // returns the list of idxs of the volumes contained in the selection but not in the given list + std::vector get_missing_volume_idxs_from(const std::vector& volume_idxs) const; + // returns the list of idxs of the volumes contained in the given list but not in the selection + std::vector get_unselected_volume_idxs_from(const std::vector& volume_idxs) const; +#endif // ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + private: void update_valid(); void update_type(); void set_caches(); void do_add_volume(unsigned int volume_idx); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_SELECTION_UNDO_REDO + void do_add_volumes(const std::vector& volume_idxs); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void do_add_instance(unsigned int object_idx, unsigned int instance_idx); void do_add_object(unsigned int object_idx); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_SELECTION_UNDO_REDO +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void do_remove_volume(unsigned int volume_idx); void do_remove_instance(unsigned int object_idx, unsigned int instance_idx); void do_remove_object(unsigned int object_idx);