diff --git a/source/MaterialXGraphEditor/Graph.cpp b/source/MaterialXGraphEditor/Graph.cpp index d0602e45ec..e404e039b3 100644 --- a/source/MaterialXGraphEditor/Graph.cpp +++ b/source/MaterialXGraphEditor/Graph.cpp @@ -1907,7 +1907,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; @@ -1923,7 +1923,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") { @@ -1937,7 +1937,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") { @@ -1949,7 +1949,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") { @@ -1962,7 +1962,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 { @@ -2018,7 +2018,10 @@ 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) @@ -4054,6 +4057,89 @@ void Graph::drawGraph(ImVec2 mousePos) } } } + + // Build a nodegraph from the selected nodes. + if (ImGui::IsKeyReleased(ImGuiKey_C) && + io2.KeyShift && + !io2.KeyCtrl && + _currUiNode != nullptr && + !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() || _isNodeGraph; + if (!isNodeGraph) + { + isNodeGraph |= _currUiNode->getNode()->getImplementation()->isA(); + + for (ed::NodeId selected : selectedNodes) + { + int pos = findNode((int) selected.Get()); + if (pos >= 0) + { + UiNodePtr node = _graphNodes[pos]; + + if (node->getNode() != nullptr) + { + isNodeGraph |= node->getNode()->getImplementation()->isA(); + } + + _copiedNodes.insert( + std::pair(_graphNodes[pos], nullptr)); + } + } + } + + // Delete nodes we just copied + if (!_copiedNodes.empty() && !isNodeGraph) + { + 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->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; + _currGraphName.push_back(implGraph->getName()); + buildUiNodeGraph(implGraph); + ed::NavigateToContent(); + } + + // Paste + for (std::map::iterator iter = _copiedNodes.begin(); iter != _copiedNodes.end(); iter++) + { + copyUiNode(iter->first); + } + _addNewNode = true; + } + + _copiedNodes.clear(); + } + // Set y-position of first node std::vector outputNum = createNodes(_isNodeGraph); 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);