diff --git a/ui/zenoedit/viewport/cameracontrol.cpp b/ui/zenoedit/viewport/cameracontrol.cpp index 5a84adf49a..149c3810c7 100644 --- a/ui/zenoedit/viewport/cameracontrol.cpp +++ b/ui/zenoedit/viewport/cameracontrol.cpp @@ -586,7 +586,18 @@ void CameraControl::fakeMouseReleaseEvent(QMouseEvent *event) { int y0 = m_boundRectStartPos.y(); int x1 = releasePos.x(); int y1 = releasePos.y(); - m_picker->pick(x0, y0, x1, y1); + zeno::SELECTION_MODE mode = zeno::SELECTION_MODE::NORMAL; + if (shift_pressed == false && ctrl_pressed == false) { + mode = zeno::SELECTION_MODE::NORMAL; + } + else if (shift_pressed == true && ctrl_pressed == false) { + mode = zeno::SELECTION_MODE::APPEND; + } + else if (shift_pressed == false && ctrl_pressed == true) { + mode = zeno::SELECTION_MODE::REMOVE; + } + + m_picker->pick(x0, y0, x1, y1, mode); m_picker->sync_to_scene(); if (scene->select_mode == zenovis::PICK_MODE::PICK_OBJECT) onPrimSelected(); @@ -637,6 +648,12 @@ void CameraControl::fakeMouseReleaseEvent(QMouseEvent *event) { } bool CameraControl::fakeKeyPressEvent(int uKey) { + if (uKey & Qt::SHIFT) { + shift_pressed = true; + } + if (uKey & Qt::CTRL) { + ctrl_pressed = true; + } if (!middle_button_pressed) { return false; } @@ -684,6 +701,15 @@ bool CameraControl::fakeKeyPressEvent(int uKey) { } } +bool CameraControl::fakeKeyReleaseEvent(int uKey) { + if (uKey == Qt::Key_Shift) { + shift_pressed = false; + } + if (uKey == Qt::Key_Control) { + ctrl_pressed = false; + } + return false; +} //void CameraControl::createPointNode(QPointF pnt) { //auto pModel = zenoApp->graphsManagment()->currentModel(); //ZASSERT_EXIT(pModel); diff --git a/ui/zenoedit/viewport/cameracontrol.h b/ui/zenoedit/viewport/cameracontrol.h index db3f10b544..da7798a816 100644 --- a/ui/zenoedit/viewport/cameracontrol.h +++ b/ui/zenoedit/viewport/cameracontrol.h @@ -39,6 +39,7 @@ class CameraControl : public QObject void setKeyFrame(); bool fakeKeyPressEvent(int uKey); + bool fakeKeyReleaseEvent(int uKey); void fakeMousePressEvent(QMouseEvent* event); void fakeMouseReleaseEvent(QMouseEvent* event); void fakeMouseMoveEvent(QMouseEvent* event); @@ -66,6 +67,8 @@ class CameraControl : public QObject Zenovis* m_zenovis; bool middle_button_pressed = false; + bool shift_pressed = false; + bool ctrl_pressed = false; }; diff --git a/ui/zenoedit/viewport/displaywidget.cpp b/ui/zenoedit/viewport/displaywidget.cpp index 6bdac8b03b..8c59fbbbcd 100644 --- a/ui/zenoedit/viewport/displaywidget.cpp +++ b/ui/zenoedit/viewport/displaywidget.cpp @@ -1217,7 +1217,7 @@ void DisplayWidget::onNodeSelected(const QModelIndex &subgIdx, const QModelIndex node_context += prim_name + ":" + e.toStdString() + " "; if (picker) - picker->load_from_str(node_context, scene->select_mode); + picker->load_from_str(node_context, scene->select_mode, zeno::SELECTION_MODE::NORMAL); } if (picker) { picker->sync_to_scene(); diff --git a/ui/zenoedit/viewport/viewportwidget.cpp b/ui/zenoedit/viewport/viewportwidget.cpp index 3aa0670736..ba4c758fb7 100644 --- a/ui/zenoedit/viewport/viewportwidget.cpp +++ b/ui/zenoedit/viewport/viewportwidget.cpp @@ -396,4 +396,9 @@ void ViewportWidget::keyPressEvent(QKeyEvent *event) void ViewportWidget::keyReleaseEvent(QKeyEvent *event) { _base::keyReleaseEvent(event); + int uKey = event->key(); + if (m_camera->fakeKeyReleaseEvent(uKey)) { + zenoApp->getMainWindow()->updateViewport(); + return; + } } diff --git a/ui/zenoedit/viewportinteraction/picker.cpp b/ui/zenoedit/viewportinteraction/picker.cpp index 481ec91965..2f9714d141 100644 --- a/ui/zenoedit/viewportinteraction/picker.cpp +++ b/ui/zenoedit/viewportinteraction/picker.cpp @@ -145,7 +145,7 @@ void Picker::pick(int x, int y) { // onPrimitiveSelected(); } -void Picker::pick(int x0, int y0, int x1, int y1) { +void Picker::pick(int x0, int y0, int x1, int y1, SELECTION_MODE mode) { auto scene = this->scene(); ZASSERT_EXIT(scene); auto selected = picker->getPicked(x0, y0, x1, y1); @@ -155,14 +155,10 @@ void Picker::pick(int x0, int y0, int x1, int y1) { selected_prims.clear(); return; } - load_from_str(selected, zenovis::PICK_MODE::PICK_OBJECT); + load_from_str(selected, zenovis::PICK_MODE::PICK_OBJECT, SELECTION_MODE::NORMAL); } else { - if (selected.empty()) { - selected_elements.clear(); - return; - } - load_from_str(selected, scene->select_mode); + load_from_str(selected, scene->select_mode, mode); if (picked_elems_callback) picked_elems_callback(selected_elements); } } @@ -201,7 +197,7 @@ void Picker::sync_to_scene() { } -void Picker::load_from_str(const string& str, zenovis::PICK_MODE mode) { +void Picker::load_from_str(const string& str, zenovis::PICK_MODE mode, SELECTION_MODE sel_mode) { if (str.empty()) return; // parse selected string std::regex reg(" "); @@ -215,6 +211,9 @@ void Picker::load_from_str(const string& str, zenovis::PICK_MODE mode) { } } else { + if (sel_mode == SELECTION_MODE::NORMAL) { + selected_elements.clear(); + } while (p != end) { string result = *p++; // qDebug() << result.c_str(); @@ -225,7 +224,7 @@ void Picker::load_from_str(const string& str, zenovis::PICK_MODE mode) { int elem_id; ss >> elem_id; if (selected_elements.find(obj_id) != selected_elements.end()) { auto &elements = selected_elements[obj_id]; - if (elements.count(elem_id) > 0) + if (sel_mode == SELECTION_MODE::REMOVE) elements.erase(elem_id); else elements.insert(elem_id); diff --git a/ui/zenoedit/viewportinteraction/picker.h b/ui/zenoedit/viewportinteraction/picker.h index ca60719185..3cf7bd4d26 100644 --- a/ui/zenoedit/viewportinteraction/picker.h +++ b/ui/zenoedit/viewportinteraction/picker.h @@ -16,6 +16,12 @@ class ViewportWidget; namespace zeno { +enum class SELECTION_MODE { + NORMAL, + APPEND, + REMOVE, +}; + std::optional ray_box_intersect( zeno::vec3f const &bmin, zeno::vec3f const &bmax, @@ -38,14 +44,14 @@ class Picker Picker(ViewportWidget* pViewport); void initialize(); void pick(int x, int y); - void pick(int x0, int y0, int x1, int y1); + void pick(int x0, int y0, int x1, int y1, SELECTION_MODE mode = SELECTION_MODE::NORMAL); void pick_depth(int x, int y); void add(const std::string& prim_name); std::string just_pick_prim(int x, int y); const std::unordered_set& get_picked_prims(); const std::unordered_map>& get_picked_elems(); void sync_to_scene(); - void load_from_str(const std::string& str, zenovis::PICK_MODE mode); + void load_from_str(const std::string& str, zenovis::PICK_MODE mode, SELECTION_MODE sel_mode); std::string save_to_str(zenovis::PICK_MODE mode); void save_context(); void load_context();