From 7005877d7c70abb0e146a1c7f728c615d8e6eb6f Mon Sep 17 00:00:00 2001 From: WaffleBoyTom Date: Wed, 30 Oct 2024 17:30:09 -0400 Subject: [PATCH 1/9] Adding Shift C hotkey to create nodegraph from selected nodes --- source/MaterialXGraphEditor/Graph.cpp | 149 +++++++++++++++++++++++--- 1 file changed, 135 insertions(+), 14 deletions(-) diff --git a/source/MaterialXGraphEditor/Graph.cpp b/source/MaterialXGraphEditor/Graph.cpp index d09961d42f..279a5b79fb 100644 --- a/source/MaterialXGraphEditor/Graph.cpp +++ b/source/MaterialXGraphEditor/Graph.cpp @@ -1897,7 +1897,7 @@ void Graph::copyInputs() } } -void Graph::addNode(const std::string& category, const std::string& name, const std::string& type) +UiNodePtr Graph::addNode(const std::string& category, const std::string& name, const std::string& type) { mx::NodePtr node = nullptr; std::vector matchingNodeDefs; @@ -1913,7 +1913,7 @@ void Graph::addNode(const std::string& category, const std::string& name, const auto outputNode = std::make_shared(outName, int(++_graphTotalSize)); outputNode->setOutput(newOut); setUiNodeInfo(outputNode, type, category); - return; + return outputNode; } if (category == "input") { @@ -1927,7 +1927,7 @@ void Graph::addNode(const std::string& category, const std::string& name, const setDefaults(newIn); inputNode->setInput(newIn); setUiNodeInfo(inputNode, type, category); - return; + return inputNode; } else if (category == "group") { @@ -1939,7 +1939,7 @@ void Graph::addNode(const std::string& category, const std::string& name, const // Create ui portions of group node buildGroupNode(_graphNodes.back()); - return; + return groupNode; } else if (category == "nodegraph") { @@ -1952,7 +1952,7 @@ void Graph::addNode(const std::string& category, const std::string& name, const nodeGraphNode->setNodeGraph(_graphDoc->getNodeGraphs().back()); setUiNodeInfo(nodeGraphNode, type, "nodegraph"); - return; + return nodeGraphNode; } else { @@ -2008,7 +2008,9 @@ void Graph::addNode(const std::string& category, const std::string& name, const _graphNodes.push_back(std::move(newNode)); updateMaterials(); + return newNode; } + return nullptr; } int Graph::getNodeId(ed::PinId pinId) @@ -3240,15 +3242,6 @@ void Graph::graphButtons() ImGui::BeginChild("Selection", ImVec2(paneWidth, 0), false, windowFlags); ImVec2 windowPos = ImGui::GetWindowPos(); - // Update cursorInRenderView to account for other windows overlapping the Render View (e.g. Menu dropdown). - cursorInRenderView &= ImGui::IsWindowHovered(ImGuiHoveredFlags_None); - - // Update cursorInRenderView to account for visible scrollbar and scroll amount. - ImGuiContext* context = ImGui::GetCurrentContext(); - bool hasScrollbar = context->CurrentWindow->ScrollbarY; - cursorInRenderView &= hasScrollbar ? mousePos.x < (tempWindowPos.x + screenSize.x - ImGui::GetStyle().ScrollbarSize) : true; - cursorInRenderView &= hasScrollbar ? mousePos.y < (tempWindowPos.y + screenSize.y - ImGui::GetScrollY()) : true; - // RenderView window ImVec2 wsize = ImVec2((float) _renderer->getViewWidth(), (float) _renderer->getViewHeight()); _renderer->setViewWidth((int) screenSize[0]); @@ -4030,6 +4023,134 @@ void Graph::drawGraph(ImVec2 mousePos) } } + // shift + C is pressed + // build nodegraph from selected node + if (ImGui::IsKeyReleased(ImGuiKey_C) && + io2.KeyShift && + !io2.KeyCtrl) + { + // cut nodes + if (!readOnly()) + { + _copiedNodes.clear(); + + for (ed::NodeId selected : selectedNodes) + { + int pos = findNode((int) selected.Get()); + if (pos >= 0) + { + _copiedNodes.insert(std::pair(_graphNodes[pos], nullptr)); + } + } + } + else + { + _popup = true; + } + + // delete nodes we just copied + // _isCut did not seem to work + // this feels scuffed ? + + if (!readOnly()) + { + for (std::map::iterator iter = _copiedNodes.begin(); iter != _copiedNodes.end(); iter++) + { + UiNodePtr node = iter->first; + deleteNode(node); + } + } + + // create subgraph + + UiNodePtr nodegraphnodeptr = addNode("nodegraph", "", ""); + + _currUiNode = nodegraphnodeptr; + + ed::SetNodePosition(_currUiNode->getId(), mousePos); + + // dive inside + + if (_currUiNode != nullptr) + { + if (_currUiNode->getNode() != nullptr) + { + mx::InterfaceElementPtr impl = _currUiNode->getNode()->getImplementation(); + + // Only dive if current node is a node graph + if (impl && impl->isA()) + { + savePosition(); + _graphStack.push(_graphNodes); + _pinStack.push(_currPins); + _sizeStack.push(_graphTotalSize); + mx::NodeGraphPtr implGraph = impl->asA(); + _initial = true; + _graphNodes.clear(); + ed::DeselectNode(_currUiNode->getId()); + _currUiNode = nullptr; + _currGraphElem = implGraph; + if (readOnly()) + { + std::string graphName = implGraph->getName() + " (Read Only)"; + _currGraphName.push_back(graphName); + _popup = true; + } + else + { + + _currGraphName.push_back(implGraph->getName()); + } + buildUiNodeGraph(implGraph); + ed::NavigateToContent(); + } + } + else if (_currUiNode->getNodeGraph() != nullptr) + { + savePosition(); + _graphStack.push(_graphNodes); + _pinStack.push(_currPins); + _sizeStack.push(_graphTotalSize); + mx::NodeGraphPtr implGraph = _currUiNode->getNodeGraph(); + _initial = true; + _graphNodes.clear(); + _isNodeGraph = true; + setRenderMaterial(_currUiNode); + ed::DeselectNode(_currUiNode->getId()); + _currUiNode = nullptr; + _currGraphElem = implGraph; + if (readOnly()) + { + + std::string graphName = implGraph->getName() + " (Read Only)"; + _currGraphName.push_back(graphName); + _popup = true; + } + else + { + _currGraphName.push_back(implGraph->getName()); + } + buildUiNodeGraph(implGraph); + ed::NavigateToContent(); + } + } + + // paste + + if (!readOnly()) + { + for (std::map::iterator iter = _copiedNodes.begin(); iter != _copiedNodes.end(); iter++) + { + copyUiNode(iter->first); + } + _addNewNode = true; + } + else + { + _popup = true; + } + } + // Set y-position of first node std::vector outputNum = createNodes(_isNodeGraph); From 7ac994cf511b6c02c4decfbea697bd042af3fd2f Mon Sep 17 00:00:00 2001 From: WaffleBoyTom Date: Wed, 30 Oct 2024 17:30:15 -0400 Subject: [PATCH 2/9] Updating addNode function declaration --- source/MaterialXGraphEditor/Graph.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/MaterialXGraphEditor/Graph.h b/source/MaterialXGraphEditor/Graph.h index f225f5e686..fe334c6ec4 100644 --- a/source/MaterialXGraphEditor/Graph.h +++ b/source/MaterialXGraphEditor/Graph.h @@ -156,7 +156,7 @@ class Graph int findNode(const std::string& name, const std::string& type); // Add node to graphNodes based on nodedef information - void addNode(const std::string& category, const std::string& name, const std::string& type); + UiNodePtr addNode(const std::string& category, const std::string& name, const std::string& type); void deleteNode(UiNodePtr node); From 982def5eebc3893f6ed3d2e3940ed9b880c793eb Mon Sep 17 00:00:00 2001 From: WaffleBoyTom Date: Wed, 30 Oct 2024 17:30:17 -0400 Subject: [PATCH 3/9] Sync changes with main --- source/MaterialXGraphEditor/Graph.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/source/MaterialXGraphEditor/Graph.cpp b/source/MaterialXGraphEditor/Graph.cpp index 279a5b79fb..3f661794fa 100644 --- a/source/MaterialXGraphEditor/Graph.cpp +++ b/source/MaterialXGraphEditor/Graph.cpp @@ -3242,6 +3242,15 @@ void Graph::graphButtons() ImGui::BeginChild("Selection", ImVec2(paneWidth, 0), false, windowFlags); ImVec2 windowPos = ImGui::GetWindowPos(); + // Update cursorInRenderView to account for other windows overlapping the Render View (e.g. Menu dropdown). + cursorInRenderView &= ImGui::IsWindowHovered(ImGuiHoveredFlags_None); + + // Update cursorInRenderView to account for visible scrollbar and scroll amount. + ImGuiContext* context = ImGui::GetCurrentContext(); + bool hasScrollbar = context->CurrentWindow->ScrollbarY; + cursorInRenderView &= hasScrollbar ? mousePos.x < (tempWindowPos.x + screenSize.x - ImGui::GetStyle().ScrollbarSize) : true; + cursorInRenderView &= hasScrollbar ? mousePos.y < (tempWindowPos.y + screenSize.y - ImGui::GetScrollY()) : true; + // RenderView window ImVec2 wsize = ImVec2((float) _renderer->getViewWidth(), (float) _renderer->getViewHeight()); _renderer->setViewWidth((int) screenSize[0]); From 6b5ac80f9aacc7a95c9b2355cd41d7b679657dd3 Mon Sep 17 00:00:00 2001 From: WaffleBoyTom Date: Wed, 30 Oct 2024 17:30:18 -0400 Subject: [PATCH 4/9] Add checks to not allow creation of nodegraphs within nodegraphs --- source/MaterialXGraphEditor/Graph.cpp | 128 ++++++++++---------------- 1 file changed, 50 insertions(+), 78 deletions(-) diff --git a/source/MaterialXGraphEditor/Graph.cpp b/source/MaterialXGraphEditor/Graph.cpp index 3f661794fa..5a2b9bc486 100644 --- a/source/MaterialXGraphEditor/Graph.cpp +++ b/source/MaterialXGraphEditor/Graph.cpp @@ -4031,91 +4031,78 @@ void Graph::drawGraph(ImVec2 mousePos) } } } - + // shift + C is pressed - // build nodegraph from selected node + // build nodegraph from selected nodes + #include + if (ImGui::IsKeyReleased(ImGuiKey_C) && - io2.KeyShift && - !io2.KeyCtrl) + io2.KeyShift && + !io2.KeyCtrl && + _currUiNode != nullptr && + !readOnly()) { - // cut nodes - if (!readOnly()) + // cut nodes + _copiedNodes.clear(); + + // since we can't have a node graph inside a node graph + // we check if we are already inside one or if + // any of the selected nodes is a nodegraph + + bool isNodeGraph = _currUiNode->getNode() == nullptr; + + isNodeGraph |= _isNodeGraph; + + if (!isNodeGraph) { - _copiedNodes.clear(); + isNodeGraph |= _currUiNode->getNode()->getImplementation()->isA(); + for (ed::NodeId selected : selectedNodes) { int pos = findNode((int) selected.Get()); if (pos >= 0) { - _copiedNodes.insert(std::pair(_graphNodes[pos], nullptr)); + UiNodePtr node = _graphNodes[pos]; + + if (node->getNode() != nullptr) + { + isNodeGraph |= node->getNode()->getImplementation()->isA(); + } + + _copiedNodes.insert( + std::pair(_graphNodes[pos], + nullptr)); } } - } - else - { - _popup = true; + } // delete nodes we just copied - // _isCut did not seem to work - // this feels scuffed ? - - if (!readOnly()) + + if (!_copiedNodes.empty() && !isNodeGraph) + { + for (std::map::iterator iter = _copiedNodes.begin(); iter != _copiedNodes.end(); iter++) { UiNodePtr node = iter->first; deleteNode(node); } - } - - // create subgraph + + // create subgraph - UiNodePtr nodegraphnodeptr = addNode("nodegraph", "", ""); + UiNodePtr nodegraphnodeptr = addNode("nodegraph", "", ""); - _currUiNode = nodegraphnodeptr; + _currUiNode = nodegraphnodeptr; - ed::SetNodePosition(_currUiNode->getId(), mousePos); + ed::SetNodePosition(_currUiNode->getId(), mousePos); - // dive inside + // dive inside - if (_currUiNode != nullptr) - { - if (_currUiNode->getNode() != nullptr) - { - mx::InterfaceElementPtr impl = _currUiNode->getNode()->getImplementation(); - - // Only dive if current node is a node graph - if (impl && impl->isA()) - { - savePosition(); - _graphStack.push(_graphNodes); - _pinStack.push(_currPins); - _sizeStack.push(_graphTotalSize); - mx::NodeGraphPtr implGraph = impl->asA(); - _initial = true; - _graphNodes.clear(); - ed::DeselectNode(_currUiNode->getId()); - _currUiNode = nullptr; - _currGraphElem = implGraph; - if (readOnly()) - { - std::string graphName = implGraph->getName() + " (Read Only)"; - _currGraphName.push_back(graphName); - _popup = true; - } - else - { - - _currGraphName.push_back(implGraph->getName()); - } - buildUiNodeGraph(implGraph); - ed::NavigateToContent(); - } - } - else if (_currUiNode->getNodeGraph() != nullptr) + if (_currUiNode->getNodeGraph() != nullptr) { + savePosition(); _graphStack.push(_graphNodes); _pinStack.push(_currPins); @@ -4128,37 +4115,22 @@ void Graph::drawGraph(ImVec2 mousePos) ed::DeselectNode(_currUiNode->getId()); _currUiNode = nullptr; _currGraphElem = implGraph; - if (readOnly()) - { - - std::string graphName = implGraph->getName() + " (Read Only)"; - _currGraphName.push_back(graphName); - _popup = true; - } - else - { - _currGraphName.push_back(implGraph->getName()); - } + _currGraphName.push_back(implGraph->getName()); buildUiNodeGraph(implGraph); ed::NavigateToContent(); } - } - // paste + // paste - if (!readOnly()) - { for (std::map::iterator iter = _copiedNodes.begin(); iter != _copiedNodes.end(); iter++) { copyUiNode(iter->first); } _addNewNode = true; } - else - { - _popup = true; - } - } + + } + // Set y-position of first node std::vector outputNum = createNodes(_isNodeGraph); From aa448b7c80d7a9939bde766e040eb535438f7462 Mon Sep 17 00:00:00 2001 From: WaffleBoyTom Date: Sat, 16 Nov 2024 10:03:46 -0500 Subject: [PATCH 5/9] clear internally copied nodes --- source/MaterialXGraphEditor/Graph.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/MaterialXGraphEditor/Graph.cpp b/source/MaterialXGraphEditor/Graph.cpp index 5a2b9bc486..14a4743c3b 100644 --- a/source/MaterialXGraphEditor/Graph.cpp +++ b/source/MaterialXGraphEditor/Graph.cpp @@ -4034,7 +4034,6 @@ void Graph::drawGraph(ImVec2 mousePos) // shift + C is pressed // build nodegraph from selected nodes - #include if (ImGui::IsKeyReleased(ImGuiKey_C) && io2.KeyShift && @@ -4129,6 +4128,8 @@ void Graph::drawGraph(ImVec2 mousePos) _addNewNode = true; } + _copiedNodes.clear(); + } From b07faaa71970b83fb1868f8171c56529f72e8bb6 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Thu, 5 Dec 2024 20:18:05 -0800 Subject: [PATCH 6/9] Minor spacing fix Signed-off-by: Jonathan Stone --- source/MaterialXGraphEditor/Graph.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/MaterialXGraphEditor/Graph.cpp b/source/MaterialXGraphEditor/Graph.cpp index 14a4743c3b..54411e7379 100644 --- a/source/MaterialXGraphEditor/Graph.cpp +++ b/source/MaterialXGraphEditor/Graph.cpp @@ -2010,7 +2010,8 @@ UiNodePtr Graph::addNode(const std::string& category, const std::string& name, c updateMaterials(); return newNode; } - return nullptr; + + return nullptr; } int Graph::getNodeId(ed::PinId pinId) From 344e4290242b077877bf88dd3cd904cc358160f1 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Thu, 12 Dec 2024 16:45:57 -0800 Subject: [PATCH 7/9] Remove extra newlines Signed-off-by: Jonathan Stone --- source/MaterialXGraphEditor/Graph.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/source/MaterialXGraphEditor/Graph.cpp b/source/MaterialXGraphEditor/Graph.cpp index 8bbd890cf3..35fee41cc0 100644 --- a/source/MaterialXGraphEditor/Graph.cpp +++ b/source/MaterialXGraphEditor/Graph.cpp @@ -4075,12 +4075,9 @@ void Graph::drawGraph(ImVec2 mousePos) // any of the selected nodes is a nodegraph bool isNodeGraph = _currUiNode->getNode() == nullptr; - isNodeGraph |= _isNodeGraph; - if (!isNodeGraph) { - isNodeGraph |= _currUiNode->getNode()->getImplementation()->isA(); for (ed::NodeId selected : selectedNodes) @@ -4104,11 +4101,8 @@ void Graph::drawGraph(ImVec2 mousePos) } // delete nodes we just copied - if (!_copiedNodes.empty() && !isNodeGraph) - { - for (std::map::iterator iter = _copiedNodes.begin(); iter != _copiedNodes.end(); iter++) { UiNodePtr node = iter->first; @@ -4116,7 +4110,6 @@ void Graph::drawGraph(ImVec2 mousePos) } // create subgraph - UiNodePtr nodegraphnodeptr = addNode("nodegraph", "", ""); _currUiNode = nodegraphnodeptr; @@ -4124,7 +4117,6 @@ void Graph::drawGraph(ImVec2 mousePos) ed::SetNodePosition(_currUiNode->getId(), mousePos); // dive inside - if (_currUiNode->getNodeGraph() != nullptr) { @@ -4146,7 +4138,6 @@ void Graph::drawGraph(ImVec2 mousePos) } // paste - for (std::map::iterator iter = _copiedNodes.begin(); iter != _copiedNodes.end(); iter++) { copyUiNode(iter->first); From 57d738abc003a95c311d0785edb3e1c5cc3a8955 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Thu, 12 Dec 2024 17:11:17 -0800 Subject: [PATCH 8/9] Remove extra whitespace Signed-off-by: Jonathan Stone --- source/MaterialXGraphEditor/Graph.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/source/MaterialXGraphEditor/Graph.cpp b/source/MaterialXGraphEditor/Graph.cpp index 35fee41cc0..16495bad20 100644 --- a/source/MaterialXGraphEditor/Graph.cpp +++ b/source/MaterialXGraphEditor/Graph.cpp @@ -4060,14 +4060,13 @@ void Graph::drawGraph(ImVec2 mousePos) // shift + C is pressed // build nodegraph from selected nodes - if (ImGui::IsKeyReleased(ImGuiKey_C) && io2.KeyShift && !io2.KeyCtrl && _currUiNode != nullptr && !readOnly()) { - // cut nodes + // cut nodes _copiedNodes.clear(); // since we can't have a node graph inside a node graph @@ -4097,7 +4096,6 @@ void Graph::drawGraph(ImVec2 mousePos) nullptr)); } } - } // delete nodes we just copied @@ -4119,7 +4117,6 @@ void Graph::drawGraph(ImVec2 mousePos) // dive inside if (_currUiNode->getNodeGraph() != nullptr) { - savePosition(); _graphStack.push(_graphNodes); _pinStack.push(_currPins); From a5d9e3e932e70a6b1392785c9120a6c18d491fc3 Mon Sep 17 00:00:00 2001 From: Jonathan Stone Date: Thu, 12 Dec 2024 17:37:39 -0800 Subject: [PATCH 9/9] Minor clarifications Signed-off-by: Jonathan Stone --- source/MaterialXGraphEditor/Graph.cpp | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/source/MaterialXGraphEditor/Graph.cpp b/source/MaterialXGraphEditor/Graph.cpp index 16495bad20..251278c9c4 100644 --- a/source/MaterialXGraphEditor/Graph.cpp +++ b/source/MaterialXGraphEditor/Graph.cpp @@ -4058,23 +4058,19 @@ void Graph::drawGraph(ImVec2 mousePos) } } - // shift + C is pressed - // build nodegraph from selected nodes + // Build a nodegraph from the selected nodes. if (ImGui::IsKeyReleased(ImGuiKey_C) && io2.KeyShift && !io2.KeyCtrl && _currUiNode != nullptr && !readOnly()) { - // cut nodes + // Cut nodes _copiedNodes.clear(); - // since we can't have a node graph inside a node graph - // we check if we are already inside one or if - // any of the selected nodes is a nodegraph - - bool isNodeGraph = _currUiNode->getNode() == nullptr; - isNodeGraph |= _isNodeGraph; + // Since we can't have a node graph inside a node graph, we check if we are already + // inside one or if any of the selected nodes is a nodegraph. + bool isNodeGraph = !_currUiNode->getNode() || _isNodeGraph; if (!isNodeGraph) { isNodeGraph |= _currUiNode->getNode()->getImplementation()->isA(); @@ -4092,13 +4088,12 @@ void Graph::drawGraph(ImVec2 mousePos) } _copiedNodes.insert( - std::pair(_graphNodes[pos], - nullptr)); + std::pair(_graphNodes[pos], nullptr)); } } } - // delete nodes we just copied + // Delete nodes we just copied if (!_copiedNodes.empty() && !isNodeGraph) { for (std::map::iterator iter = _copiedNodes.begin(); iter != _copiedNodes.end(); iter++) @@ -4107,14 +4102,14 @@ void Graph::drawGraph(ImVec2 mousePos) deleteNode(node); } - // create subgraph + // Create subgraph UiNodePtr nodegraphnodeptr = addNode("nodegraph", "", ""); _currUiNode = nodegraphnodeptr; ed::SetNodePosition(_currUiNode->getId(), mousePos); - // dive inside + // Dive inside if (_currUiNode->getNodeGraph() != nullptr) { savePosition(); @@ -4134,7 +4129,7 @@ void Graph::drawGraph(ImVec2 mousePos) ed::NavigateToContent(); } - // paste + // Paste for (std::map::iterator iter = _copiedNodes.begin(); iter != _copiedNodes.end(); iter++) { copyUiNode(iter->first); @@ -4143,7 +4138,6 @@ void Graph::drawGraph(ImVec2 mousePos) } _copiedNodes.clear(); - }