Skip to content

Commit 71ebb9d

Browse files
Consolidate edge creation in Graph Editor (#2793)
This changelist consolidates edge creation logic in the MaterialX Graph Editor, adding shared helper methods and merging parallel code paths. The following specific changes are included: - Add a `findUpstreamNode` helper method to handle the resolution of upstream connections for an input. - Add a `createEdgeForOutput` helper method to handle the creation of edges from output elements to their connected upstream nodes. - Unify edge creation in `buildUiBaseGraph` into a single loop over all graph nodes, replacing separate loops for nodegraphs and surface shader nodes. - Add missing edge creation and render material updates for document-scope outputs (addresses issue #2294).
1 parent 7e91c4d commit 71ebb9d

2 files changed

Lines changed: 86 additions & 82 deletions

File tree

source/MaterialXGraphEditor/Graph.cpp

Lines changed: 80 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,17 @@ void Graph::setRenderMaterial(UiNodePtr node)
546546
mtlxNodeGraph = parent->asA<mx::NodeGraph>();
547547
else if (parent->isA<mx::Node>())
548548
mtlxNode = parent->asA<mx::Node>();
549+
else if (parent->isA<mx::Document>())
550+
{
551+
// Document-scope outputs are directly renderable.
552+
if (_currRenderNode != node)
553+
{
554+
_currRenderNode = node;
555+
_frameCount = ImGui::GetFrameCount();
556+
_renderer->setMaterialCompilation(true);
557+
}
558+
return;
559+
}
549560
}
550561
mx::StringSet testPaths;
551562
if (mtlxNode)
@@ -1211,67 +1222,33 @@ void Graph::buildUiBaseGraph(mx::DocumentPtr doc)
12111222
setUiNodeInfo(currNode, output->getType(), output->getCategory());
12121223
}
12131224

1214-
// Create edges for nodegraphs
1215-
for (mx::NodeGraphPtr graph : nodeGraphs)
1225+
// Create edges for nodegraph and node inputs
1226+
for (size_t i = 0; i < _state.nodes.size(); i++)
12161227
{
1217-
int downNum = findNode(graph->getName(), "nodegraph");
1218-
if (downNum < 0)
1228+
UiNodePtr& uiNode = _state.nodes[i];
1229+
mx::ElementPtr elem = uiNode->getElement();
1230+
mx::InterfaceElementPtr interface = elem ? elem->asA<mx::InterfaceElement>() : nullptr;
1231+
if (!interface)
12191232
{
12201233
continue;
12211234
}
1222-
for (mx::InputPtr input : graph->getActiveInputs())
1223-
{
1224-
int upNum = -1;
1225-
mx::string nodeGraphName = input->getNodeGraphString();
1226-
mx::NodePtr connectedNode = input->getConnectedNode();
1227-
if (!nodeGraphName.empty())
1228-
{
1229-
upNum = findNode(nodeGraphName, "nodegraph");
1230-
}
1231-
else if (connectedNode)
1232-
{
1233-
upNum = findNode(connectedNode->getName(), "node");
1234-
}
12351235

1236+
int downNum = static_cast<int>(i);
1237+
1238+
for (mx::InputPtr input : interface->getActiveInputs())
1239+
{
1240+
int upNum = findUpstreamNode(input);
12361241
if (upNum >= 0)
12371242
{
12381243
createEdge(_state.nodes[upNum], _state.nodes[downNum], input);
12391244
}
12401245
}
12411246
}
12421247

1243-
// Create edges for surface and material nodes
1244-
for (mx::NodePtr node : docNodes)
1248+
// Create edges for document-scope outputs
1249+
for (mx::OutputPtr output : outputNodes)
12451250
{
1246-
mx::NodeDefPtr nD = node->getNodeDef(node->getName());
1247-
for (mx::InputPtr input : node->getActiveInputs())
1248-
{
1249-
mx::string nodeGraphName = input->getNodeGraphString();
1250-
mx::NodePtr connectedNode = input->getConnectedNode();
1251-
mx::OutputPtr connectedOutput = input->getConnectedOutput();
1252-
int upNum = -1;
1253-
int downNum = findNode(node->getName(), "node");
1254-
if (!nodeGraphName.empty())
1255-
{
1256-
upNum = findNode(nodeGraphName, "nodegraph");
1257-
}
1258-
else if (connectedNode)
1259-
{
1260-
upNum = findNode(connectedNode->getName(), "node");
1261-
}
1262-
else if (connectedOutput)
1263-
{
1264-
upNum = findNode(connectedOutput->getName(), "output");
1265-
}
1266-
else if (!input->getInterfaceName().empty())
1267-
{
1268-
upNum = findNode(input->getInterfaceName(), "input");
1269-
}
1270-
if (upNum >= 0 && downNum >= 0)
1271-
{
1272-
createEdge(_state.nodes[upNum], _state.nodes[downNum], input);
1273-
}
1274-
}
1251+
createEdgeForOutput(output);
12751252
}
12761253
}
12771254

@@ -1282,7 +1259,6 @@ void Graph::buildUiNodeGraph(const mx::NodeGraphPtr& nodeGraphs)
12821259
mx::NodeGraphPtr nodeGraph = nodeGraphs;
12831260
std::vector<mx::ElementPtr> children = nodeGraph->topologicalSort();
12841261
mx::NodeDefPtr nodeDef = nodeGraph->getNodeDef();
1285-
mx::NodeDefPtr currNodeDef;
12861262

12871263
// Create input nodes
12881264
if (nodeDef)
@@ -1335,13 +1311,13 @@ void Graph::buildUiNodeGraph(const mx::NodeGraphPtr& nodeGraphs)
13351311
mx::ElementPtr connectingElem = edge.getConnectingElement();
13361312

13371313
mx::NodePtr upstreamNode = upstreamElem->asA<mx::Node>();
1338-
mx::NodePtr downstreamNode = downstreamElem->asA<mx::Node>();
13391314
mx::InputPtr upstreamInput = upstreamElem->asA<mx::Input>();
1340-
mx::InputPtr downstreamInput = downstreamElem->asA<mx::Input>();
13411315
mx::OutputPtr upstreamOutput = upstreamElem->asA<mx::Output>();
1316+
mx::NodePtr downstreamNode = downstreamElem->asA<mx::Node>();
1317+
mx::InputPtr downstreamInput = downstreamElem->asA<mx::Input>();
13421318
mx::OutputPtr downstreamOutput = downstreamElem->asA<mx::Output>();
1343-
std::string downName = downstreamElem->getName();
13441319
std::string upName = upstreamElem->getName();
1320+
std::string downName = downstreamElem->getName();
13451321
std::string upstreamType;
13461322
std::string downstreamType;
13471323
if (upstreamNode)
@@ -1413,44 +1389,23 @@ void Graph::buildUiNodeGraph(const mx::NodeGraphPtr& nodeGraphs)
14131389
mx::OutputPtr output = elem->asA<mx::Output>();
14141390
if (node)
14151391
{
1392+
int downNum = findNode(node->getName(), "node");
1393+
if (downNum < 0)
1394+
{
1395+
continue;
1396+
}
14161397
for (mx::InputPtr input : node->getActiveInputs())
14171398
{
1418-
mx::NodePtr connectedNode = input->getConnectedNode();
1419-
int downNum = findNode(node->getName(), "node");
1420-
if (downNum < 0)
1399+
int upNum = findUpstreamNode(input);
1400+
if (upNum >= 0)
14211401
{
1422-
continue;
1423-
}
1424-
if (connectedNode)
1425-
{
1426-
int upNum = findNode(connectedNode->getName(), "node");
1427-
if (upNum >= 0)
1428-
{
1429-
createEdge(_state.nodes[upNum], _state.nodes[downNum], input);
1430-
}
1431-
}
1432-
else if (input->getInterfaceInput())
1433-
{
1434-
int upNum = findNode(input->getInterfaceInput()->getName(), "input");
1435-
if (upNum >= 0)
1436-
{
1437-
createEdge(_state.nodes[upNum], _state.nodes[downNum], input);
1438-
}
1402+
createEdge(_state.nodes[upNum], _state.nodes[downNum], input);
14391403
}
14401404
}
14411405
}
14421406
else if (output)
14431407
{
1444-
mx::NodePtr connectedNode = output->getConnectedNode();
1445-
if (connectedNode)
1446-
{
1447-
int upNum = findNode(connectedNode->getName(), "node");
1448-
int downNum = findNode(output->getName(), "output");
1449-
if (upNum >= 0 && downNum >= 0)
1450-
{
1451-
createEdge(_state.nodes[upNum], _state.nodes[downNum], nullptr);
1452-
}
1453-
}
1408+
createEdgeForOutput(output);
14541409
}
14551410
}
14561411
}
@@ -1485,6 +1440,35 @@ int Graph::findNode(const std::string& name, const std::string& type)
14851440
return -1;
14861441
}
14871442

1443+
int Graph::findUpstreamNode(mx::InputPtr input)
1444+
{
1445+
const mx::string& nodeGraphName = input->getNodeGraphString();
1446+
if (!nodeGraphName.empty())
1447+
{
1448+
return findNode(nodeGraphName, "nodegraph");
1449+
}
1450+
1451+
mx::NodePtr connectedNode = input->getConnectedNode();
1452+
if (connectedNode)
1453+
{
1454+
return findNode(connectedNode->getName(), "node");
1455+
}
1456+
1457+
mx::OutputPtr connectedOutput = input->getConnectedOutput();
1458+
if (connectedOutput)
1459+
{
1460+
return findNode(connectedOutput->getName(), "output");
1461+
}
1462+
1463+
const mx::string& interfaceName = input->getInterfaceName();
1464+
if (!interfaceName.empty())
1465+
{
1466+
return findNode(interfaceName, "input");
1467+
}
1468+
1469+
return -1;
1470+
}
1471+
14881472
void Graph::positionPasteBin(ImVec2 pos)
14891473
{
14901474
ImVec2 totalPos = ImVec2(0, 0);
@@ -1536,6 +1520,20 @@ bool Graph::createEdge(UiNodePtr upNode, UiNodePtr downNode, mx::InputPtr connec
15361520
return true;
15371521
}
15381522

1523+
void Graph::createEdgeForOutput(mx::OutputPtr output)
1524+
{
1525+
mx::NodePtr connectedNode = output->getConnectedNode();
1526+
if (connectedNode)
1527+
{
1528+
int upNum = findNode(connectedNode->getName(), "node");
1529+
int downNum = findNode(output->getName(), "output");
1530+
if (upNum >= 0 && downNum >= 0)
1531+
{
1532+
createEdge(_state.nodes[upNum], _state.nodes[downNum], nullptr);
1533+
}
1534+
}
1535+
}
1536+
15391537
void Graph::copyUiNode(UiNodePtr node)
15401538
{
15411539
UiNodePtr copyNode = std::make_shared<UiNode>(mx::EMPTY_STRING, int(_state.nextUiId + 1));

source/MaterialXGraphEditor/Graph.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,9 @@ class Graph
182182
// account for input/output UiNodes with same names as MaterialX nodes
183183
int findNode(const std::string& name, const std::string& type);
184184

185+
// Return the node position of the upstream connection from the given input.
186+
int findUpstreamNode(mx::InputPtr input);
187+
185188
// Add node to graphNodes based on nodedef information
186189
void addNode(const std::string& category, const std::string& name, const std::string& type);
187190

@@ -197,6 +200,9 @@ class Graph
197200
// Returns true if the edge was created, false if invalid or already exists.
198201
bool createEdge(UiNodePtr upNode, UiNodePtr downNode, mx::InputPtr connectingInput);
199202

203+
// Create an edge from an output element to its connected upstream node.
204+
void createEdgeForOutput(mx::OutputPtr output);
205+
200206
// Remove node edge based on connecting input
201207
void removeEdge(int downNode, int upNode, UiPinPtr pin);
202208

0 commit comments

Comments
 (0)