From 59a409005f09f65e76c16fc838a4bd3f4abf6791 Mon Sep 17 00:00:00 2001
From: lfl-eholthouser <84752487+lfl-eholthouser@users.noreply.github.com>
Date: Tue, 27 Jun 2023 10:15:44 -0700
Subject: [PATCH] Auto layout fix for subgraphs (#1389)

This is a bug fix for auto layout for nodes like triplanarprojection. This pull request also includes formatting fixes.
---
 source/MaterialXGraphEditor/Graph.cpp | 45 ++++++++++++++-------------
 1 file changed, 24 insertions(+), 21 deletions(-)

diff --git a/source/MaterialXGraphEditor/Graph.cpp b/source/MaterialXGraphEditor/Graph.cpp
index 134205bcff..9e3fbccc40 100644
--- a/source/MaterialXGraphEditor/Graph.cpp
+++ b/source/MaterialXGraphEditor/Graph.cpp
@@ -481,12 +481,18 @@ ImVec2 Graph::layoutPosition(UiNodePtr layoutNode, ImVec2 startingPos, bool init
                 // don't set position of group nodes
                 if (node->getMessage().empty())
                 {
-                    float x = std::stof(node->getMxElement()->getAttribute("xpos"));
-                    float y = std::stof(node->getMxElement()->getAttribute("ypos"));
-                    x *= DEFAULT_NODE_SIZE.x;
-                    y *= DEFAULT_NODE_SIZE.y;
-                    ed::SetNodePosition(node->getId(), ImVec2(x, y));
-                    node->setPos(ImVec2(x, y));
+                    if (node->getMxElement()->hasAttribute("xpos"))
+                    {
+                        float x = std::stof(node->getMxElement()->getAttribute("xpos"));
+                        if (node->getMxElement()->hasAttribute("ypos"))
+                        {
+                            float y = std::stof(node->getMxElement()->getAttribute("ypos"));
+                            x *= DEFAULT_NODE_SIZE.x;
+                            y *= DEFAULT_NODE_SIZE.y;
+                            ed::SetNodePosition(node->getId(), ImVec2(x, y));
+                            node->setPos(ImVec2(x, y));
+                        }
+                    }
                 }
             }
         }
@@ -831,7 +837,7 @@ void Graph::updateMaterials(mx::InputPtr input, mx::ValuePtr value)
 // set the value of the selected node constants in the node property editor
 void Graph::setConstant(UiNodePtr node, mx::InputPtr& input, const mx::UIProperties& uiProperties)
 {
-    std::string inName = !uiProperties.uiName.empty()? uiProperties.uiName : input->getName();
+    std::string inName = !uiProperties.uiName.empty() ? uiProperties.uiName : input->getName();
     ImGui::PushItemWidth(-1);
 
     mx::ValuePtr minVal = uiProperties.uiMin;
@@ -2940,7 +2946,7 @@ void Graph::graphButtons()
             }
             ImGui::EndMenu();
         }
-        
+
         if (ImGui::BeginMenu("Graph"))
         {
             if (ImGui::MenuItem("Auto Layout"))
@@ -2949,7 +2955,7 @@ void Graph::graphButtons()
             }
             ImGui::EndMenu();
         }
-        
+
         if (ImGui::BeginMenu("Viewer"))
         {
             if (ImGui::MenuItem("Load Geometry"))
@@ -2957,7 +2963,7 @@ void Graph::graphButtons()
                 loadGeometry();
             }
             ImGui::EndMenu();
-        }     
+        }
 
         if (ImGui::Button("Help"))
         {
@@ -3145,7 +3151,7 @@ void Graph::propertyEditor()
         }
 
         const float TEXT_BASE_HEIGHT = ImGui::GetTextLineHeightWithSpacing() * 1.3f;
-        const int SCROLL_LINE_COUNT= 20;
+        const int SCROLL_LINE_COUNT = 20;
         ImGuiTableFlags tableFlags = ImGuiTableFlags_ScrollY | ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings |
                                      ImGuiTableFlags_BordersOuterH | ImGuiTableFlags_NoBordersInBody;
 
@@ -3245,7 +3251,7 @@ void Graph::propertyEditor()
             if (count)
             {
                 bool haveTable = ImGui::BeginTable("inputs_input_table", 2, tableFlags,
-                    ImVec2(0.0f, TEXT_BASE_HEIGHT * std::min(SCROLL_LINE_COUNT, count)));
+                                                   ImVec2(0.0f, TEXT_BASE_HEIGHT * std::min(SCROLL_LINE_COUNT, count)));
                 if (haveTable)
                 {
                     ImGui::SetWindowFontScale(_fontScale);
@@ -3302,7 +3308,7 @@ void Graph::propertyEditor()
             if (count)
             {
                 bool haveTable = ImGui::BeginTable("inputs_nodegraph_table", 2, tableFlags,
-                    ImVec2(0.0f, TEXT_BASE_HEIGHT * std::min(SCROLL_LINE_COUNT, count)));
+                                                   ImVec2(0.0f, TEXT_BASE_HEIGHT * std::min(SCROLL_LINE_COUNT, count)));
                 if (haveTable)
                 {
                     ImGui::SetWindowFontScale(_fontScale);
@@ -3365,7 +3371,7 @@ void Graph::propertyEditor()
 // Helper to display basic user controls.
 void Graph::showHelp() const
 {
-    ImGui::Text("MATERIALX GRAPH EDITOR HELP");   
+    ImGui::Text("MATERIALX GRAPH EDITOR HELP");
     if (ImGui::CollapsingHeader("Graph"))
     {
         if (ImGui::TreeNode("Navigation"))
@@ -3437,9 +3443,9 @@ void Graph::addNodePopup(bool cursor)
                 {
                     std::string str(it->second[i][0]);
                     std::string nodeName = it->second[i][0];
-                    //allow spaces to be used to search for node names
+                    // allow spaces to be used to search for node names
                     std::replace(subs.begin(), subs.end(), ' ', '_');
-                                    
+
                     if (str.find(subs) != std::string::npos)
                     {
                         if (ImGui::MenuItem(getNodeDefId(nodeName).c_str()) || (ImGui::IsItemFocused() && ImGui::IsKeyPressedMap(ImGuiKey_Enter)))
@@ -3819,12 +3825,9 @@ void Graph::drawGraph(ImVec2 mousePos)
 
                 if (outputNum.size() == 0 && _graphNodes[0]->getMxElement())
                 {
-                    if (_graphNodes[0]->getMxElement()->hasAttribute("xpos"))
+                    for (UiNodePtr node : _graphNodes)
                     {
-                        for (UiNodePtr node : _graphNodes)
-                        {
-                            layoutPosition(node, ImVec2(0, 0), true, 0);
-                        }
+                        layoutPosition(node, ImVec2(0, 0), true, 0);
                     }
                 }
             }