Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Shift + C hotkey to create a nodegraph from selected nodes #2048

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 108 additions & 5 deletions source/MaterialXGraphEditor/Graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<mx::NodeDefPtr> matchingNodeDefs;
Expand All @@ -1913,7 +1913,7 @@ void Graph::addNode(const std::string& category, const std::string& name, const
auto outputNode = std::make_shared<UiNode>(outName, int(++_graphTotalSize));
outputNode->setOutput(newOut);
setUiNodeInfo(outputNode, type, category);
return;
return outputNode;
}
if (category == "input")
{
Expand All @@ -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")
{
Expand All @@ -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")
{
Expand All @@ -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
{
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -4029,6 +4031,107 @@ 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())
{
jstone-lucasfilm marked this conversation as resolved.
Show resolved Hide resolved
// 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)
{

isNodeGraph |= _currUiNode->getNode()->getImplementation()->isA<mx::NodeGraph>();

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<mx::NodeGraph>();
}

_copiedNodes.insert(
std::pair<UiNodePtr, UiNodePtr>(_graphNodes[pos],
nullptr));
}
}

}

jstone-lucasfilm marked this conversation as resolved.
Show resolved Hide resolved
// delete nodes we just copied

if (!_copiedNodes.empty() && !isNodeGraph)

{

for (std::map<UiNodePtr, UiNodePtr>::iterator iter = _copiedNodes.begin(); iter != _copiedNodes.end(); iter++)
{
UiNodePtr node = iter->first;
deleteNode(node);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to break the links between nodes so even though they are copied the links are not copied over?

Tried moving this later after the paste but it crashes with some shared ptr de-refencing error. Even with this as is, I've seen hang in refresh if you try and select the surfaceshader in the default marble graph and try this operation then try and go back to the parent.

@lfl-eholthouser pinging you as you know this code much better than I. If you don't delete then a nodegraph is created properly with linked nodes and have not experienced any side-effects.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found a fix for the linking. Remove this code and add in a new flag to know that a graph has been built. I called this isBuildGraph and set it here::

   // Paste                                
                for (std::map<UiNodePtr, UiNodePtr>::iterator iter = _copiedNodes.begin(); iter != _copiedNodes.end(); iter++)
                {
                    copyUiNode(iter->first);
                }
                _addNewNode = true;
                isBuildGraph = true;

Test this flag later on and go up back to the parent and perform a proper "cut".

  if (ImGui::IsWindowFocused(ImGuiFocusedFlags_RootWindow))
        {
            if (isBuildGraph)
            {
                upNodeGraph();
                _isCut = true;
                isBuildGraph = false;
            }

            if (ImGui::IsKeyReleased(ImGuiKey_Delete) || _isCut)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can add this to my code, thank you !!

}

// 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<UiNodePtr, UiNodePtr>::iterator iter = _copiedNodes.begin(); iter != _copiedNodes.end(); iter++)
{
copyUiNode(iter->first);
}
_addNewNode = true;
}

_copiedNodes.clear();

}

jstone-lucasfilm marked this conversation as resolved.
Show resolved Hide resolved

// Set y-position of first node
std::vector<int> outputNum = createNodes(_isNodeGraph);
Expand Down
2 changes: 1 addition & 1 deletion source/MaterialXGraphEditor/Graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down