diff --git a/source/MaterialXGraphEditor/Graph.cpp b/source/MaterialXGraphEditor/Graph.cpp index 9e3fbccc40..c8f62a58b0 100644 --- a/source/MaterialXGraphEditor/Graph.cpp +++ b/source/MaterialXGraphEditor/Graph.cpp @@ -14,66 +14,61 @@ #include -namespace -{ +namespace { // the default node size is based off the of the size of the dot_color3 node using ed::getNodeSize() on that node -const ImVec2 DEFAULT_NODE_SIZE = ImVec2(138, 116); + const ImVec2 DEFAULT_NODE_SIZE = ImVec2(138, 116); -const int DEFAULT_ALPHA = 255; -const int FILTER_ALPHA = 50; + const int DEFAULT_ALPHA = 255; + const int FILTER_ALPHA = 50; // Function based off ImRect_Expanded function from ImGui Node Editor blueprints-example.cpp -ImRect expandImRect(const ImRect& rect, float x, float y) -{ - ImRect result = rect; - result.Min.x -= x; - result.Min.y -= y; - result.Max.x += x; - result.Max.y += y; - return result; -} + ImRect expandImRect(const ImRect &rect, float x, float y) { + ImRect result = rect; + result.Min.x -= x; + result.Min.y -= y; + result.Max.x += x; + result.Max.y += y; + return result; + } // Get more user friendly node definition identifier. // Will try and remove "ND_" prefix if it exists. Otherwise just returns // the nodedef identifier. -std::string getNodeDefId(const std::string& val) -{ - const std::string ND_PREFIX = "ND_"; - std::string result = val; - if (mx::stringStartsWith(val, ND_PREFIX)) - { - result = val.substr(3, val.length()); + std::string getNodeDefId(const std::string &val) { + const std::string ND_PREFIX = "ND_"; + std::string result = val; + if (mx::stringStartsWith(val, ND_PREFIX)) { + result = val.substr(3, val.length()); + } + return result; } - return result; -} } // anonymous namespace -Graph::Graph(const std::string& materialFilename, - const std::string& meshFilename, - const mx::FileSearchPath& searchPath, - const mx::FilePathVec& libraryFolders, +Graph::Graph(const std::string &materialFilename, + const std::string &meshFilename, + const mx::FileSearchPath &searchPath, + const mx::FilePathVec &libraryFolders, int viewWidth, int viewHeight) : - _materialFilename(materialFilename), - _searchPath(searchPath), - _libraryFolders(libraryFolders), - _initial(false), - _delete(false), - _fileDialogSave(FileDialog::EnterNewFilename), - _isNodeGraph(false), - _graphTotalSize(0), - _popup(false), - _shaderPopup(false), - _searchNodeId(-1), - _addNewNode(false), - _ctrlClick(false), - _isCut(false), - _autoLayout(false), - _frameCount(INT_MIN), - _pinFilterType(mx::EMPTY_STRING) -{ + _materialFilename(materialFilename), + _searchPath(searchPath), + _libraryFolders(libraryFolders), + _initial(false), + _delete(false), + _fileDialogSave(FileDialog::EnterNewFilename), + _isNodeGraph(false), + _graphTotalSize(0), + _popup(false), + _shaderPopup(false), + _searchNodeId(-1), + _addNewNode(false), + _ctrlClick(false), + _isCut(false), + _autoLayout(false), + _frameCount(INT_MIN), + _pinFilterType(mx::EMPTY_STRING) { loadStandardLibraries(); setPinColor(); @@ -89,8 +84,7 @@ Graph::Graph(const std::string& materialFilename, _initial = true; createNodeUIList(_stdLib); - if (_graphDoc) - { + if (_graphDoc) { buildUiBaseGraph(_graphDoc); _currGraphElem = _graphDoc; _prevUiNode = nullptr; @@ -102,93 +96,74 @@ Graph::Graph(const std::string& materialFilename, _renderer = std::make_shared(_graphDoc, meshFilename, envRadianceFilename, _searchPath, viewWidth, viewHeight); _renderer->initialize(); - for (const std::string& ext : _renderer->getImageHandler()->supportedExtensions()) - { + for (const std::string &ext: _renderer->getImageHandler()->supportedExtensions()) { _imageFilter.push_back("." + ext); } _renderer->updateMaterials(nullptr); - for (const std::string& incl : _renderer->getXincludeFiles()) - { + for (const std::string &incl: _renderer->getXincludeFiles()) { _xincludeFiles.insert(incl); } } -mx::ElementPredicate Graph::getElementPredicate() const -{ - return [this](mx::ConstElementPtr elem) - { - if (elem->hasSourceUri()) - { +mx::ElementPredicate Graph::getElementPredicate() const { + return [this](mx::ConstElementPtr elem) { + if (elem->hasSourceUri()) { return (_xincludeFiles.count(elem->getSourceUri()) == 0); } return true; }; } -void Graph::loadStandardLibraries() -{ +void Graph::loadStandardLibraries() { // Initialize the standard library. - try - { + try { _stdLib = mx::createDocument(); _xincludeFiles = mx::loadLibraries(_libraryFolders, _searchPath, _stdLib); - if (_xincludeFiles.empty()) - { - std::cerr << "Could not find standard data libraries on the given search path: " << _searchPath.asString() << std::endl; + if (_xincludeFiles.empty()) { + std::cerr << "Could not find standard data libraries on the given search path: " << _searchPath.asString() + << std::endl; } } - catch (std::exception& e) - { + catch (std::exception &e) { std::cerr << "Failed to load standard data libraries: " << e.what() << std::endl; return; } } -mx::DocumentPtr Graph::loadDocument(mx::FilePath filename) -{ - mx::FilePathVec libraryFolders = { "libraries" }; +mx::DocumentPtr Graph::loadDocument(mx::FilePath filename) { + mx::FilePathVec libraryFolders = {"libraries"}; _libraryFolders = libraryFolders; mx::XmlReadOptions readOptions; - readOptions.readXIncludeFunction = [](mx::DocumentPtr doc, const mx::FilePath& filename, - const mx::FileSearchPath& searchPath, const mx::XmlReadOptions* options) - { + readOptions.readXIncludeFunction = [](mx::DocumentPtr doc, const mx::FilePath &filename, + const mx::FileSearchPath &searchPath, const mx::XmlReadOptions *options) { mx::FilePath resolvedFilename = searchPath.find(filename); - if (resolvedFilename.exists()) - { - try - { + if (resolvedFilename.exists()) { + try { readFromXmlFile(doc, resolvedFilename, searchPath, options); } - catch (mx::Exception& e) - { + catch (mx::Exception &e) { std::cerr << "Failed to read include file: " << filename.asString() << ". " << - std::string(e.what()) << std::endl; + std::string(e.what()) << std::endl; } - } - else - { + } else { std::cerr << "Include file not found: " << filename.asString() << std::endl; } }; mx::DocumentPtr doc = mx::createDocument(); - try - { - if (!filename.isEmpty()) - { + try { + if (!filename.isEmpty()) { mx::readFromXmlFile(doc, filename, _searchPath, &readOptions); std::string message; - if (!doc->validate(&message)) - { + if (!doc->validate(&message)) { std::cerr << "*** Validation warnings for " << filename.asString() << " ***" << std::endl; std::cerr << message << std::endl; } } } - catch (mx::Exception& e) - { + catch (mx::Exception &e) { std::cerr << "Failed to read file: " << filename.asString() << ": \"" << - std::string(e.what()) << "\"" << std::endl; + std::string(e.what()) << "\"" << std::endl; } _graphStack = std::stack>(); _pinStack = std::stack>(); @@ -196,10 +171,8 @@ mx::DocumentPtr Graph::loadDocument(mx::FilePath filename) } // populate nodes to add with input output group and nodegraph nodes which are not found in the stdlib -void Graph::addExtraNodes() -{ - if (!_graphDoc) - { +void Graph::addExtraNodes() { + if (!_graphDoc) { return; } @@ -210,71 +183,56 @@ void Graph::addExtraNodes() std::vector types; std::vector typeDefs = _graphDoc->getTypeDefs(); types.reserve(typeDefs.size()); - for (auto typeDef : typeDefs) - { + for (auto typeDef: typeDefs) { types.push_back(typeDef->getName()); } // add input and output nodes for all types - for (const std::string& type : types) - { + for (const std::string &type: types) { std::string nodeName = "ND_input_" + type; - _extraNodes["Input Nodes"].push_back({ nodeName, type, "input" }); + _extraNodes["Input Nodes"].push_back({nodeName, type, "input"}); nodeName = "ND_output_" + type; - _extraNodes["Output Nodes"].push_back({ nodeName, type, "output" }); + _extraNodes["Output Nodes"].push_back({nodeName, type, "output"}); } // add group node - std::vector groupNode{ "ND_group", "", "group" }; + std::vector groupNode{"ND_group", "", "group"}; _extraNodes["Group Nodes"].push_back(groupNode); // add nodegraph node - std::vector nodeGraph{ "ND_nodegraph", "", "nodegraph" }; + std::vector nodeGraph{"ND_nodegraph", "", "nodegraph"}; _extraNodes["Node Graph"].push_back(nodeGraph); } // return output pin needed to link the inputs and outputs -ed::PinId Graph::getOutputPin(UiNodePtr node, UiNodePtr upNode, UiPinPtr input) -{ - if (upNode->getNodeGraph() != nullptr) - { +ed::PinId Graph::getOutputPin(UiNodePtr node, UiNodePtr upNode, UiPinPtr input) { + if (upNode->getNodeGraph() != nullptr) { // For nodegraph need to get the correct ouput pin accorinding to the names of the output nodes - mx::OutputPtr output = input->_pinNode->getNode() ? input->_pinNode->getNode()->getConnectedOutput(input->_name) : nullptr; - if (output) - { + mx::OutputPtr output = input->_pinNode->getNode() ? input->_pinNode->getNode()->getConnectedOutput(input->_name) + : nullptr; + if (output) { std::string outName = output->getName(); - for (UiPinPtr outputs : upNode->outputPins) - { - if (outputs->_name == outName) - { + for (UiPinPtr outputs: upNode->outputPins) { + if (outputs->_name == outName) { return outputs->_pinId; } } } return ed::PinId(); - } - else - { + } else { // For node need to get the correct ouput pin based on the output attribute - if (!upNode->outputPins.empty()) - { + if (!upNode->outputPins.empty()) { std::string outputName = mx::EMPTY_STRING; - if (input->_input) - { + if (input->_input) { outputName = input->_input->getOutputString(); - } - else if (input->_output) - { + } else if (input->_output) { outputName = input->_output->getOutputString(); } size_t pinIndex = 0; - if (!outputName.empty()) - { - for (size_t i = 0; i < upNode->outputPins.size(); i++) - { - if (upNode->outputPins[i]->_name == outputName) - { + if (!outputName.empty()) { + for (size_t i = 0; i < upNode->outputPins.size(); i++) { + if (upNode->outputPins[i]->_name == outputName) { pinIndex = i; break; } @@ -287,23 +245,18 @@ ed::PinId Graph::getOutputPin(UiNodePtr node, UiNodePtr upNode, UiPinPtr input) } // connect links via connected nodes in UiNodePtr -void Graph::linkGraph() -{ +void Graph::linkGraph() { _currLinks.clear(); // start with bottom of graph - for (UiNodePtr node : _graphNodes) - { + for (UiNodePtr node: _graphNodes) { std::vector inputs = node->inputPins; - if (node->getInput() == nullptr) - { - for (size_t i = 0; i < inputs.size(); i++) - { + if (node->getInput() == nullptr) { + for (size_t i = 0; i < inputs.size(); i++) { // get upstream node for all inputs std::string inputName = inputs[i]->_name; UiNodePtr inputNode = node->getConnectedNode(inputName); - if (inputNode != nullptr) - { + if (inputNode != nullptr) { Link link; // getting the input connections for the current uiNode ax::NodeEditor::PinId id = inputs[i]->_pinId; @@ -315,13 +268,10 @@ void Graph::linkGraph() ed::PinId outputId = getOutputPin(node, inputNode, inputs[i]); int start = int(outputId.Get()); - if (start >= 0) - { + if (start >= 0) { // Connect the correct output pin to this input - for (UiPinPtr outPin : inputNode->outputPins) - { - if (outPin->_pinId == outputId) - { + for (UiPinPtr outPin: inputNode->outputPins) { + if (outPin->_pinId == outputId) { outPin->setConnected(true); outPin->addConnection(inputs[i]); } @@ -329,22 +279,16 @@ void Graph::linkGraph() link._startAttr = start; - if (!linkExists(link)) - { + if (!linkExists(link)) { _currLinks.push_back(link); } } - } - else if (inputs[i]->_input) - { - if (inputs[i]->_input->getInterfaceInput()) - { + } else if (inputs[i]->_input) { + if (inputs[i]->_input->getInterfaceInput()) { inputs[i]->setConnected(true); } - } - else - { + } else { inputs[i]->setConnected(false); } } @@ -353,60 +297,51 @@ void Graph::linkGraph() } // connect all the links via the graph editor library -void Graph::connectLinks() -{ +void Graph::connectLinks() { - for (Link const& link : _currLinks) - { + for (Link const &link: _currLinks) { ed::Link(link.id, link._startAttr, link._endAttr); } } // find link position in currLinks vector from link id -int Graph::findLinkPosition(int id) -{ +int Graph::findLinkPosition(int id) { int count = 0; - for (size_t i = 0; i < _currLinks.size(); i++) - { - if (_currLinks[i].id == id) - { + for (size_t i = 0; i < _currLinks.size(); i++) { + if (_currLinks[i].id == id) { return count; } count++; } return -1; } + // check if a node has already been assigned a position -bool Graph::checkPosition(UiNodePtr node) -{ - if (node->getMxElement() != nullptr) - { - if (node->getMxElement()->getAttribute("xpos") != "") - { +bool Graph::checkPosition(UiNodePtr node) { + if (node->getMxElement() != nullptr) { + if (node->getMxElement()->getAttribute("xpos") != "") { return true; } } return false; } + // calculate the total vertical space the node level takes up -float Graph::totalHeight(int level) -{ +float Graph::totalHeight(int level) { float total = 0.f; - for (UiNodePtr node : _levelMap[level]) - { + for (UiNodePtr node: _levelMap[level]) { total += ed::GetNodeSize(node->getId()).y; } return total; } + // set the y position of node based of the starting position and the nodes above it -void Graph::setYSpacing(int level, float startingPos) -{ +void Graph::setYSpacing(int level, float startingPos) { // set the y spacing for each node float currPos = startingPos; - for (UiNodePtr node : _levelMap[level]) - { + for (UiNodePtr node: _levelMap[level]) { ImVec2 oldPos = ed::GetNodePosition(node->getId()); ed::SetNodePosition(node->getId(), ImVec2(oldPos.x, currPos)); currPos += ed::GetNodeSize(node->getId()).y + 40; @@ -414,13 +349,11 @@ void Graph::setYSpacing(int level, float startingPos) } // calculate the average y position for a specific node level -float Graph::findAvgY(const std::vector& nodes) -{ +float Graph::findAvgY(const std::vector &nodes) { // find the mid point of node level grou[ float total = 0.f; int count = 0; - for (UiNodePtr node : nodes) - { + for (UiNodePtr node: nodes) { ImVec2 pos = ed::GetNodePosition(node->getId()); ImVec2 size = ed::GetNodeSize(node->getId()); @@ -430,17 +363,13 @@ float Graph::findAvgY(const std::vector& nodes) return (total / count); } -void Graph::findYSpacing(float startY) -{ +void Graph::findYSpacing(float startY) { // assume level 0 is set // for each level find the average y position of the previous level to use as a spacing guide int i = 0; - for (std::pair> levelChunk : _levelMap) - { - if (_levelMap[i].size() > 0) - { - if (_levelMap[i][0]->_level > 0) - { + for (std::pair> levelChunk: _levelMap) { + if (_levelMap[i].size() > 0) { + if (_levelMap[i][0]->_level > 0) { int prevLevel = _levelMap[i].front()->_level - 1; float avgY = findAvgY(_levelMap[prevLevel]); @@ -448,9 +377,7 @@ void Graph::findYSpacing(float startY) // caculate the starting position to be above the previous level's center so that it is evenly spaced on either side of the center float startingPos = avgY - ((height + (_levelMap[i].size() * 20)) / 2) + startY; setYSpacing(_levelMap[i].front()->_level, startingPos); - } - else - { + } else { setYSpacing(_levelMap[i].front()->_level, startY); } } @@ -459,33 +386,23 @@ void Graph::findYSpacing(float startY) } // layout the x position by assigning the node levels based off its distance from the first node -ImVec2 Graph::layoutPosition(UiNodePtr layoutNode, ImVec2 startingPos, bool initialLayout, int level) -{ - if (checkPosition(layoutNode) && !_autoLayout) - { - for (UiNodePtr node : _graphNodes) - { +ImVec2 Graph::layoutPosition(UiNodePtr layoutNode, ImVec2 startingPos, bool initialLayout, int level) { + if (checkPosition(layoutNode) && !_autoLayout) { + for (UiNodePtr node: _graphNodes) { // since nodegrpah nodes do not have any materialX info they are placed based off their conneced node - if (node->getNodeGraph() != nullptr) - { + if (node->getNodeGraph() != nullptr) { std::vector outputCon = node->getOutputConnections(); - if (outputCon.size() > 0) - { + if (outputCon.size() > 0) { ImVec2 outputPos = ed::GetNodePosition(outputCon[0]->getId()); ed::SetNodePosition(node->getId(), ImVec2(outputPos.x - 400, outputPos.y)); node->setPos(ImVec2(outputPos.x - 400, outputPos.y)); } - } - else - { + } else { // don't set position of group nodes - if (node->getMessage().empty()) - { - if (node->getMxElement()->hasAttribute("xpos")) - { + if (node->getMessage().empty()) { + if (node->getMxElement()->hasAttribute("xpos")) { float x = std::stof(node->getMxElement()->getAttribute("xpos")); - if (node->getMxElement()->hasAttribute("ypos")) - { + if (node->getMxElement()->hasAttribute("ypos")) { float y = std::stof(node->getMxElement()->getAttribute("ypos")); x *= DEFAULT_NODE_SIZE.x; y *= DEFAULT_NODE_SIZE.y; @@ -497,90 +414,69 @@ ImVec2 Graph::layoutPosition(UiNodePtr layoutNode, ImVec2 startingPos, bool init } } return ImVec2(0.f, 0.f); - } - else - { + } else { ImVec2 currPos = startingPos; ImVec2 newPos = currPos; - if (layoutNode->_level != -1) - { - if (layoutNode->_level < level) - { + if (layoutNode->_level != -1) { + if (layoutNode->_level < level) { // remove the old instance of the node from the map int levelNum = 0; int removeNum = -1; - for (UiNodePtr levelNode : _levelMap[layoutNode->_level]) - { - if (levelNode->getName() == layoutNode->getName()) - { + for (UiNodePtr levelNode: _levelMap[layoutNode->_level]) { + if (levelNode->getName() == layoutNode->getName()) { removeNum = levelNum; } levelNum++; } - if (removeNum > -1) - { + if (removeNum > -1) { _levelMap[layoutNode->_level].erase(_levelMap[layoutNode->_level].begin() + removeNum); } layoutNode->_level = level; } - } - else - { + } else { layoutNode->_level = level; } auto it = _levelMap.find(layoutNode->_level); - if (it != _levelMap.end()) - { + if (it != _levelMap.end()) { // key already exists add to it bool nodeFound = false; - for (UiNodePtr node : it->second) - { - if (node && node->getName() == layoutNode->getName()) - { + for (UiNodePtr node: it->second) { + if (node && node->getName() == layoutNode->getName()) { nodeFound = true; break; } } - if (!nodeFound) - { + if (!nodeFound) { _levelMap[layoutNode->_level].push_back(layoutNode); } - } - else - { + } else { // insert new vector into key - std::vector newValue = { layoutNode }; - _levelMap.insert({ layoutNode->_level, newValue }); + std::vector newValue = {layoutNode}; + _levelMap.insert({layoutNode->_level, newValue}); } std::vector pins = layoutNode->inputPins; - if (initialLayout) - { + if (initialLayout) { // check number of inputs that are connected to node - if (layoutNode->getInputConnect() > 0) - { + if (layoutNode->getInputConnect() > 0) { // not top of node graph stop recursion - if (pins.size() != 0 && layoutNode->getInput() == nullptr) - { - for (size_t i = 0; i < pins.size(); i++) - { + if (pins.size() != 0 && layoutNode->getInput() == nullptr) { + for (size_t i = 0; i < pins.size(); i++) { // get upstream node for all inputs newPos = startingPos; UiNodePtr nextNode = layoutNode->getConnectedNode(pins[i]->_name); - if (nextNode) - { + if (nextNode) { startingPos.x = (1200.f - ((layoutNode->_level) * 350)) * _fontScale; ed::SetNodePosition(layoutNode->getId(), startingPos); layoutNode->setPos(ImVec2(startingPos)); // call layout position on upstream node with newPos as -140 to the left of current node - layoutPosition(nextNode, ImVec2(newPos.x, startingPos.y), initialLayout, layoutNode->_level + 1); + layoutPosition(nextNode, ImVec2(newPos.x, startingPos.y), initialLayout, + layoutNode->_level + 1); } } } - } - else - { + } else { startingPos.x = (1200.f - ((layoutNode->_level) * 350)) * _fontScale; layoutNode->setPos(ImVec2(startingPos)); // set current node position @@ -592,32 +488,25 @@ ImVec2 Graph::layoutPosition(UiNodePtr layoutNode, ImVec2 startingPos, bool init } // extra layout pass for inputs and nodes that do not attach to an output node -void Graph::layoutInputs() -{ +void Graph::layoutInputs() { // layout inputs after other nodes so that they can be all in a line on far left side of node graph - if (_levelMap.begin() != _levelMap.end()) - { + if (_levelMap.begin() != _levelMap.end()) { int levelCount = -1; - for (std::pair> nodes : _levelMap) - { + for (std::pair> nodes: _levelMap) { ++levelCount; } ImVec2 startingPos = ed::GetNodePosition(_levelMap[levelCount].back()->getId()); startingPos.y += ed::GetNodeSize(_levelMap[levelCount].back()->getId()).y + 20; - for (UiNodePtr uiNode : _graphNodes) - { - if (uiNode->getOutputConnections().size() == 0 && (uiNode->getInput() != nullptr)) - { + for (UiNodePtr uiNode: _graphNodes) { + if (uiNode->getOutputConnections().size() == 0 && (uiNode->getInput() != nullptr)) { ed::SetNodePosition(uiNode->getId(), ImVec2(startingPos)); startingPos.y += ed::GetNodeSize(uiNode->getId()).y; startingPos.y += 23; } - // accoutning for extra nodes like in gltf - else if (uiNode->getOutputConnections().size() == 0 && (uiNode->getNode() != nullptr)) - { - if (uiNode->getNode()->getCategory() != mx::SURFACE_MATERIAL_NODE_STRING) - { + // accoutning for extra nodes like in gltf + else if (uiNode->getOutputConnections().size() == 0 && (uiNode->getNode() != nullptr)) { + if (uiNode->getNode()->getCategory() != mx::SURFACE_MATERIAL_NODE_STRING) { layoutPosition(uiNode, ImVec2(1200, 750), _initial, 0); } } @@ -626,8 +515,7 @@ void Graph::layoutInputs() } // reutrn pin color based on the type of the value of that pin -void Graph::setPinColor() -{ +void Graph::setPinColor() { _pinColor.insert(std::make_pair("integer", ImColor(255, 255, 28, 255))); _pinColor.insert(std::make_pair("boolean", ImColor(255, 0, 255, 255))); _pinColor.insert(std::make_pair("float", ImColor(50, 100, 255, 255))); @@ -663,8 +551,7 @@ void Graph::setPinColor() } // based off of showLabel from ImGui Node Editor blueprints-example.cpp -auto showLabel = [](const char* label, ImColor color) -{ +auto showLabel = [](const char *label, ImColor color) { ImGui::SetCursorPosY(ImGui::GetCursorPosY() - ImGui::GetTextLineHeight()); auto size = ImGui::CalcTextSize(label); @@ -681,17 +568,14 @@ auto showLabel = [](const char* label, ImColor color) ImGui::TextUnformatted(label); }; -void Graph::selectMaterial(UiNodePtr uiNode) -{ +void Graph::selectMaterial(UiNodePtr uiNode) { // find renderable element that correspond with material uiNode std::vector elems = mx::findRenderableElements(_graphDoc); mx::TypedElementPtr typedElem = nullptr; - for (mx::TypedElementPtr elem : elems) - { + for (mx::TypedElementPtr elem: elems) { mx::TypedElementPtr renderableElem = elem; mx::NodePtr node = elem->asA(); - if (node == uiNode->getNode()) - { + if (node == uiNode->getNode()) { typedElem = elem; } } @@ -699,132 +583,94 @@ void Graph::selectMaterial(UiNodePtr uiNode) } // set the node to display in render veiw based off the selected node or nodegraph -void Graph::setRenderMaterial(UiNodePtr node) -{ +void Graph::setRenderMaterial(UiNodePtr node) { // set render node right away is node is a material - if (node->getNode() && node->getNode()->getType() == "material") - { + if (node->getNode() && node->getNode()->getType() == "material") { // only set new render node if different material has been selected - if (_currRenderNode != node) - { + if (_currRenderNode != node) { _currRenderNode = node; _frameCount = ImGui::GetFrameCount(); _renderer->setMaterialCompilation(true); } - } - else - { + } else { // continue downstream using output connections until a material node is found std::vector outNodes = node->getOutputConnections(); - if (outNodes.size() > 0) - { - if (outNodes[0]->getNode()) - { - if (outNodes[0]->getNode()->getType() == mx::SURFACE_SHADER_TYPE_STRING) - { + if (outNodes.size() > 0) { + if (outNodes[0]->getNode()) { + if (outNodes[0]->getNode()->getType() == mx::SURFACE_SHADER_TYPE_STRING) { std::vector shaderOut = outNodes[0]->getOutputConnections(); - if (shaderOut.size() > 0) - { - if (shaderOut[0]) - { - if (shaderOut[0]->getNode()->getType() == "material") - { - if (_currRenderNode != shaderOut[0]) - { + if (shaderOut.size() > 0) { + if (shaderOut[0]) { + if (shaderOut[0]->getNode()->getType() == "material") { + if (_currRenderNode != shaderOut[0]) { _currRenderNode = shaderOut[0]; _frameCount = ImGui::GetFrameCount(); _renderer->setMaterialCompilation(true); } } } - } - else - { + } else { _currRenderNode = nullptr; } - } - else if (outNodes[0]->getNode()->getType() == mx::MATERIAL_TYPE_STRING) - { - if (_currRenderNode != outNodes[0]) - { + } else if (outNodes[0]->getNode()->getType() == mx::MATERIAL_TYPE_STRING) { + if (_currRenderNode != outNodes[0]) { _currRenderNode = outNodes[0]; _frameCount = ImGui::GetFrameCount(); _renderer->setMaterialCompilation(true); } } - } - else - { + } else { _currRenderNode = nullptr; } - } - else - { + } else { _currRenderNode = nullptr; } } } -void Graph::updateMaterials(mx::InputPtr input, mx::ValuePtr value) -{ +void Graph::updateMaterials(mx::InputPtr input, mx::ValuePtr value) { std::string renderablePath; mx::TypedElementPtr renderableElem; std::vector elems = mx::findRenderableElements(_graphDoc); size_t num = 0; int num2 = 0; - for (mx::TypedElementPtr elem : elems) - { + for (mx::TypedElementPtr elem: elems) { renderableElem = elem; mx::NodePtr node = elem->asA(); - if (node) - { - if (_currRenderNode) - { - if (node->getName() == _currRenderNode->getName()) - { + if (node) { + if (_currRenderNode) { + if (node->getName() == _currRenderNode->getName()) { renderablePath = renderableElem->getNamePath(); break; } - } - else - { + } else { renderablePath = renderableElem->getNamePath(); } - } - else - { + } else { renderablePath = renderableElem->getNamePath(); - if (num2 == 2) - { + if (num2 == 2) { break; } num2++; } } - if (renderablePath.empty()) - { + if (renderablePath.empty()) { _renderer->updateMaterials(nullptr); - } - else - { - if (!input) - { + } else { + if (!input) { mx::ElementPtr elem = nullptr; { elem = _graphDoc->getDescendant(renderablePath); } mx::TypedElementPtr typedElem = elem ? elem->asA() : nullptr; _renderer->updateMaterials(typedElem); - } - else - { + } else { std::string name = input->getNamePath(); // need to use exact interface name in order for input mx::InputPtr interfaceInput = findInput(input, input->getName()); - if (interfaceInput) - { + if (interfaceInput) { name = interfaceInput->getNamePath(); } // Note that if there is a topogical change due to @@ -834,9 +680,9 @@ 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) -{ +void Graph::setConstant(UiNodePtr node, mx::InputPtr &input, const mx::UIProperties &uiProperties) { std::string inName = !uiProperties.uiName.empty() ? uiProperties.uiName : input->getName(); ImGui::PushItemWidth(-1); @@ -844,12 +690,10 @@ void Graph::setConstant(UiNodePtr node, mx::InputPtr& input, const mx::UIPropert mx::ValuePtr maxVal = uiProperties.uiMax; // if input is a float set the float slider Ui to the value - if (input->getType() == "float") - { + if (input->getType() == "float") { mx::ValuePtr val = input->getValue(); - if (val && val->isA()) - { + if (val && val->isA()) { // updates the value to the default for new nodes float prev = val->asA(), temp = val->asA(); float min = minVal ? minVal->asA() : 0.f; @@ -857,38 +701,30 @@ void Graph::setConstant(UiNodePtr node, mx::InputPtr& input, const mx::UIPropert float speed = (max - min) / 1000.0f; ImGui::DragFloat("##hidelabel", &temp, speed, min, max); // set input value and update materials if different from previous value - if (prev != temp) - { + if (prev != temp) { addNodeInput(_currUiNode, input); input->setValue(temp, input->getType()); updateMaterials(input, input->getValue()); } } - } - else if (input->getType() == "integer") - { + } else if (input->getType() == "integer") { mx::ValuePtr val = input->getValue(); - if (val && val->isA()) - { + if (val && val->isA()) { int prev = val->asA(), temp = val->asA(); int min = minVal ? minVal->asA() : 0; int max = maxVal ? maxVal->asA() : 100; float speed = (max - min) / 100.0f; ImGui::DragInt("##hidelabel", &temp, speed, min, max); // set input value and update materials if different from previous value - if (prev != temp) - { + if (prev != temp) { addNodeInput(_currUiNode, input); input->setValue(temp, input->getType()); updateMaterials(input, input->getValue()); } } - } - else if (input->getType() == "color3") - { + } else if (input->getType() == "color3") { mx::ValuePtr val = input->getValue(); - if (val && val->isA()) - { + if (val && val->isA()) { mx::Color3 prev = val->asA(), temp = val->asA(); float min = minVal ? minVal->asA()[0] : 0.f; float max = maxVal ? maxVal->asA()[0] : 100.f; @@ -900,19 +736,15 @@ void Graph::setConstant(UiNodePtr node, mx::InputPtr& input, const mx::UIPropert ImGui::ColorEdit3("##color", &temp[0], ImGuiColorEditFlags_NoInputs); // set input value and update materials if different from previous value - if (prev != temp) - { + if (prev != temp) { addNodeInput(_currUiNode, input); input->setValue(temp, input->getType()); updateMaterials(input, input->getValue()); } } - } - else if (input->getType() == "color4") - { + } else if (input->getType() == "color4") { mx::ValuePtr val = input->getValue(); - if (val && val->isA()) - { + if (val && val->isA()) { mx::Color4 prev = val->asA(), temp = val->asA(); float min = minVal ? minVal->asA()[0] : 0.f; float max = maxVal ? maxVal->asA()[0] : 100.f; @@ -924,100 +756,79 @@ void Graph::setConstant(UiNodePtr node, mx::InputPtr& input, const mx::UIPropert // color edit for the color picker to the right of the color floats ImGui::ColorEdit4("##color", &temp[0], ImGuiColorEditFlags_NoInputs); // set input value and update materials if different from previous value - if (temp != prev) - { + if (temp != prev) { addNodeInput(_currUiNode, input); input->setValue(temp, input->getType()); updateMaterials(input, input->getValue()); } } - } - else if (input->getType() == "vector2") - { + } else if (input->getType() == "vector2") { mx::ValuePtr val = input->getValue(); - if (val && val->isA()) - { + if (val && val->isA()) { mx::Vector2 prev = val->asA(), temp = val->asA(); float min = minVal ? minVal->asA()[0] : 0.f; float max = maxVal ? maxVal->asA()[0] : 100.f; float speed = (max - min) / 1000.0f; ImGui::DragFloat2("##hidelabel", &temp[0], speed, min, max); // set input value and update materials if different from previous value - if (prev != temp) - { + if (prev != temp) { addNodeInput(_currUiNode, input); input->setValue(temp, input->getType()); updateMaterials(input, input->getValue()); } } - } - else if (input->getType() == "vector3") - { + } else if (input->getType() == "vector3") { mx::ValuePtr val = input->getValue(); - if (val && val->isA()) - { + if (val && val->isA()) { mx::Vector3 prev = val->asA(), temp = val->asA(); float min = minVal ? minVal->asA()[0] : 0.f; float max = maxVal ? maxVal->asA()[0] : 100.f; float speed = (max - min) / 1000.0f; ImGui::DragFloat3("##hidelabel", &temp[0], speed, min, max); // set input value and update materials if different from previous value - if (prev != temp) - { + if (prev != temp) { addNodeInput(_currUiNode, input); input->setValue(temp, input->getType()); updateMaterials(input, input->getValue()); } } - } - else if (input->getType() == "vector4") - { + } else if (input->getType() == "vector4") { mx::ValuePtr val = input->getValue(); - if (val && val->isA()) - { + if (val && val->isA()) { mx::Vector4 prev = val->asA(), temp = val->asA(); float min = minVal ? minVal->asA()[0] : 0.f; float max = maxVal ? maxVal->asA()[0] : 100.f; float speed = (max - min) / 1000.0f; ImGui::DragFloat4("##hidelabel", &temp[0], speed, min, max); // set input value and update materials if different from previous value - if (prev != temp) - { + if (prev != temp) { addNodeInput(_currUiNode, input); input->setValue(temp, input->getType()); updateMaterials(input, input->getValue()); } } - } - else if (input->getType() == "string") - { + } else if (input->getType() == "string") { mx::ValuePtr val = input->getValue(); - if (val && val->isA()) - { + if (val && val->isA()) { std::string prev = val->asA(), temp = val->asA(); ImGui::InputText("##constant", &temp); // set input value and update materials if different from previous value - if (prev != temp) - { + if (prev != temp) { addNodeInput(_currUiNode, input); input->setValue(temp, input->getType()); updateMaterials(); } } - } - else if (input->getType() == "filename") - { + } else if (input->getType() == "filename") { mx::ValuePtr val = input->getValue(); - if (val && val->isA()) - { + if (val && val->isA()) { std::string temp = val->asA(), prev = val->asA(); ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(.15f, .15f, .15f, 1.0f)); ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(.2f, .4f, .6f, 1.0f)); // browser button to select new file ImGui::PushItemWidth(-100); - if (ImGui::Button("Browse")) - { + if (ImGui::Button("Browse")) { _fileDialogImage.setTitle("Node Input Dialog"); _fileDialogImage.open(); _fileDialogImage.setTypeFilters(_imageFilter); @@ -1029,8 +840,7 @@ void Graph::setConstant(UiNodePtr node, mx::InputPtr& input, const mx::UIPropert ImGui::PopStyleColor(); // create and load document from selected file - if (_fileDialogImage.hasSelected()) - { + if (_fileDialogImage.hasSelected()) { // set the new filename to the complete file path mx::FilePath fileName = _fileDialogImage.getSelected(); temp = fileName; @@ -1041,25 +851,20 @@ void Graph::setConstant(UiNodePtr node, mx::InputPtr& input, const mx::UIPropert } // set input value and update materials if different from previous value - if (prev != temp) - { + if (prev != temp) { addNodeInput(_currUiNode, input); input->setValueString(temp); input->setValue(temp, input->getType()); updateMaterials(); } } - } - else if (input->getType() == "boolean") - { + } else if (input->getType() == "boolean") { mx::ValuePtr val = input->getValue(); - if (val && val->isA()) - { + if (val && val->isA()) { bool prev = val->asA(), temp = val->asA(); ImGui::Checkbox("", &temp); // set input value and update materials if different from previous value - if (prev != temp) - { + if (prev != temp) { addNodeInput(_currUiNode, input); input->setValue(temp, input->getType()); updateMaterials(input, input->getValue()); @@ -1069,83 +874,75 @@ void Graph::setConstant(UiNodePtr node, mx::InputPtr& input, const mx::UIPropert ImGui::PopItemWidth(); } + // build the initial graph of a loaded mtlx document including shader, material and nodegraph node -void Graph::setUiNodeInfo(UiNodePtr node, const std::string& type, const std::string& category) -{ +void Graph::setUiNodeInfo(UiNodePtr node, const std::string &type, const std::string &category) { node->setType(type); node->setCategory(category); ++_graphTotalSize; // create pins - if (node->getNodeGraph()) - { + if (node->getNodeGraph()) { std::vector outputs = node->getNodeGraph()->getOutputs(); - for (mx::OutputPtr out : outputs) - { - UiPinPtr outPin = std::make_shared(_graphTotalSize, &*out->getName().begin(), out->getType(), node, ax::NodeEditor::PinKind::Output, nullptr, nullptr); + for (mx::OutputPtr out: outputs) { + UiPinPtr outPin = std::make_shared(_graphTotalSize, &*out->getName().begin(), out->getType(), node, + ax::NodeEditor::PinKind::Output, nullptr, nullptr); ++_graphTotalSize; node->outputPins.push_back(outPin); _currPins.push_back(outPin); } - for (mx::InputPtr input : node->getNodeGraph()->getInputs()) - { - UiPinPtr inPin = std::make_shared(_graphTotalSize, &*input->getName().begin(), input->getType(), node, ax::NodeEditor::PinKind::Input, input, nullptr); + for (mx::InputPtr input: node->getNodeGraph()->getInputs()) { + UiPinPtr inPin = std::make_shared(_graphTotalSize, &*input->getName().begin(), input->getType(), + node, ax::NodeEditor::PinKind::Input, input, nullptr); node->inputPins.push_back(inPin); _currPins.push_back(inPin); ++_graphTotalSize; } - } - else - { - if (node->getNode()) - { + } else { + if (node->getNode()) { mx::NodeDefPtr nodeDef = node->getNode()->getNodeDef(node->getNode()->getName()); - if (nodeDef) - { - for (mx::InputPtr input : nodeDef->getActiveInputs()) - { - if (node->getNode()->getInput(input->getName())) - { + if (nodeDef) { + for (mx::InputPtr input: nodeDef->getActiveInputs()) { + if (node->getNode()->getInput(input->getName())) { input = node->getNode()->getInput(input->getName()); } - UiPinPtr inPin = std::make_shared(_graphTotalSize, &*input->getName().begin(), input->getType(), node, ax::NodeEditor::PinKind::Input, input, nullptr); + UiPinPtr inPin = std::make_shared(_graphTotalSize, &*input->getName().begin(), + input->getType(), node, ax::NodeEditor::PinKind::Input, + input, nullptr); node->inputPins.push_back(inPin); _currPins.push_back(inPin); ++_graphTotalSize; } - for (mx::OutputPtr output : nodeDef->getActiveOutputs()) - { - if (node->getNode()->getOutput(output->getName())) - { + for (mx::OutputPtr output: nodeDef->getActiveOutputs()) { + if (node->getNode()->getOutput(output->getName())) { output = node->getNode()->getOutput(output->getName()); } - UiPinPtr outPin = std::make_shared(_graphTotalSize, &*output->getName().begin(), output->getType(), + UiPinPtr outPin = std::make_shared(_graphTotalSize, &*output->getName().begin(), + output->getType(), node, ax::NodeEditor::PinKind::Output, nullptr, nullptr); node->outputPins.push_back(outPin); _currPins.push_back(outPin); ++_graphTotalSize; } } - } - else if (node->getInput()) - { - UiPinPtr inPin = std::make_shared(_graphTotalSize, &*("Value"), node->getInput()->getType(), node, ax::NodeEditor::PinKind::Input, node->getInput(), nullptr); + } else if (node->getInput()) { + UiPinPtr inPin = std::make_shared(_graphTotalSize, &*("Value"), node->getInput()->getType(), node, + ax::NodeEditor::PinKind::Input, node->getInput(), nullptr); node->inputPins.push_back(inPin); _currPins.push_back(inPin); ++_graphTotalSize; - } - else if (node->getOutput()) - { - UiPinPtr inPin = std::make_shared(_graphTotalSize, &*("input"), node->getOutput()->getType(), node, ax::NodeEditor::PinKind::Input, nullptr, node->getOutput()); + } else if (node->getOutput()) { + UiPinPtr inPin = std::make_shared(_graphTotalSize, &*("input"), node->getOutput()->getType(), node, + ax::NodeEditor::PinKind::Input, nullptr, node->getOutput()); node->inputPins.push_back(inPin); _currPins.push_back(inPin); ++_graphTotalSize; } - if (node->getInput() || node->getOutput()) - { - UiPinPtr outPin = std::make_shared(_graphTotalSize, &*("output"), type, node, ax::NodeEditor::PinKind::Output, nullptr, nullptr); + if (node->getInput() || node->getOutput()) { + UiPinPtr outPin = std::make_shared(_graphTotalSize, &*("output"), type, node, + ax::NodeEditor::PinKind::Output, nullptr, nullptr); ++_graphTotalSize; node->outputPins.push_back(outPin); _currPins.push_back(outPin); @@ -1156,20 +953,16 @@ void Graph::setUiNodeInfo(UiNodePtr node, const std::string& type, const std::st } // Generate node UI from nodedefs. -void Graph::createNodeUIList(mx::DocumentPtr doc) -{ +void Graph::createNodeUIList(mx::DocumentPtr doc) { _nodesToAdd.clear(); const std::string EXTRA_GROUP_NAME = "extra"; - for (mx::NodeDefPtr nodeDef : doc->getNodeDefs()) - { + for (mx::NodeDefPtr nodeDef: doc->getNodeDefs()) { // nodeDef is the key for the map std::string group = nodeDef->getNodeGroup(); - if (group.empty()) - { + if (group.empty()) { group = EXTRA_GROUP_NAME; } - if (_nodesToAdd.find(group) == _nodesToAdd.end()) - { + if (_nodesToAdd.find(group) == _nodesToAdd.end()) { _nodesToAdd[group] = std::vector(); } _nodesToAdd[group].push_back(nodeDef); @@ -1179,8 +972,7 @@ void Graph::createNodeUIList(mx::DocumentPtr doc) } // build the UiNode node graph based off of loading a document -void Graph::buildUiBaseGraph(mx::DocumentPtr doc) -{ +void Graph::buildUiBaseGraph(mx::DocumentPtr doc) { std::vector nodeGraphs = doc->getNodeGraphs(); std::vector inputNodes = doc->getActiveInputs(); std::vector outputNodes = doc->getOutputs(); @@ -1195,8 +987,7 @@ void Graph::buildUiBaseGraph(mx::DocumentPtr doc) _currPins.clear(); _graphTotalSize = 1; // creating uiNodes for nodes that belong to the document so they are not in a nodegraph - for (mx::NodePtr node : docNodes) - { + for (mx::NodePtr node: docNodes) { if (!includeElement(node)) continue; std::string name = node->getName(); @@ -1205,8 +996,7 @@ void Graph::buildUiBaseGraph(mx::DocumentPtr doc) setUiNodeInfo(currNode, node->getType(), node->getCategory()); } // creating uiNodes for the nodegraph - for (mx::NodeGraphPtr nodeGraph : nodeGraphs) - { + for (mx::NodeGraphPtr nodeGraph: nodeGraphs) { if (!includeElement(nodeGraph)) continue; std::string name = nodeGraph->getName(); @@ -1214,16 +1004,14 @@ void Graph::buildUiBaseGraph(mx::DocumentPtr doc) currNode->setNodeGraph(nodeGraph); setUiNodeInfo(currNode, "", "nodegraph"); } - for (mx::InputPtr input : inputNodes) - { + for (mx::InputPtr input: inputNodes) { if (!includeElement(input)) continue; auto currNode = std::make_shared(input->getName(), _graphTotalSize); currNode->setInput(input); setUiNodeInfo(currNode, input->getType(), input->getCategory()); } - for (mx::OutputPtr output : outputNodes) - { + for (mx::OutputPtr output: outputNodes) { if (!includeElement(output)) continue; auto currNode = std::make_shared(output->getName(), _graphTotalSize); @@ -1231,22 +1019,17 @@ void Graph::buildUiBaseGraph(mx::DocumentPtr doc) setUiNodeInfo(currNode, output->getType(), output->getCategory()); } // creating edges for nodegraphs - for (mx::NodeGraphPtr graph : nodeGraphs) - { - for (mx::InputPtr input : graph->getActiveInputs()) - { + for (mx::NodeGraphPtr graph: nodeGraphs) { + for (mx::InputPtr input: graph->getActiveInputs()) { int downNum = -1; int upNum = -1; mx::NodePtr connectedNode = input->getConnectedNode(); - if (connectedNode) - { + if (connectedNode) { downNum = findNode(graph->getName(), "nodegraph"); upNum = findNode(connectedNode->getName(), "node"); - if (upNum > -1) - { + if (upNum > -1) { UiEdge newEdge = UiEdge(_graphNodes[upNum], _graphNodes[downNum], input); - if (!edgeExists(newEdge)) - { + if (!edgeExists(newEdge)) { _graphNodes[downNum]->edges.push_back(newEdge); _graphNodes[downNum]->setInputNodeNum(1); _graphNodes[upNum]->setOutputConnection(_graphNodes[downNum]); @@ -1257,44 +1040,33 @@ void Graph::buildUiBaseGraph(mx::DocumentPtr doc) } } // creating edges for surface and material nodes - for (mx::NodePtr node : docNodes) - { + for (mx::NodePtr node: docNodes) { mx::NodeDefPtr nD = node->getNodeDef(node->getName()); - for (mx::InputPtr input : node->getActiveInputs()) - { + for (mx::InputPtr input: node->getActiveInputs()) { mx::string nodeGraphName = input->getNodeGraphString(); mx::NodePtr connectedNode = input->getConnectedNode(); mx::OutputPtr connectedOutput = input->getConnectedOutput(); int upNum = -1; int downNum = -1; - if (!nodeGraphName.empty()) - { + if (!nodeGraphName.empty()) { upNum = findNode(nodeGraphName, "nodegraph"); downNum = findNode(node->getName(), "node"); - } - else if (connectedNode) - { + } else if (connectedNode) { upNum = findNode(connectedNode->getName(), "node"); downNum = findNode(node->getName(), "node"); - } - else if (connectedOutput) - { + } else if (connectedOutput) { upNum = findNode(connectedOutput->getName(), "output"); downNum = findNode(node->getName(), "node"); - } - else if (!input->getInterfaceName().empty()) - { + } else if (!input->getInterfaceName().empty()) { upNum = findNode(input->getInterfaceName(), "input"); downNum = findNode(node->getName(), "node"); } - if (upNum != -1) - { + if (upNum != -1) { UiEdge newEdge = UiEdge(_graphNodes[upNum], _graphNodes[downNum], input); - if (!edgeExists(newEdge)) - { + if (!edgeExists(newEdge)) { _graphNodes[downNum]->edges.push_back(newEdge); _graphNodes[downNum]->setInputNodeNum(1); _graphNodes[upNum]->setOutputConnection(_graphNodes[downNum]); @@ -1304,9 +1076,9 @@ void Graph::buildUiBaseGraph(mx::DocumentPtr doc) } } } + // build the UiNode node graph based off of diving into a node graph node -void Graph::buildUiNodeGraph(const mx::NodeGraphPtr& nodeGraphs) -{ +void Graph::buildUiNodeGraph(const mx::NodeGraphPtr &nodeGraphs) { // clear all values so that ids can start with 0 or 1 _graphNodes.clear(); @@ -1315,8 +1087,7 @@ void Graph::buildUiNodeGraph(const mx::NodeGraphPtr& nodeGraphs) _newLinks.clear(); _currPins.clear(); _graphTotalSize = 1; - if (nodeGraphs) - { + if (nodeGraphs) { mx::NodeGraphPtr nodeGraph = nodeGraphs; std::vector children = nodeGraph->topologicalSort(); // Write out all nodes. @@ -1325,12 +1096,10 @@ void Graph::buildUiNodeGraph(const mx::NodeGraphPtr& nodeGraphs) mx::NodeDefPtr currNodeDef; // create input nodes - if (nodeDef) - { + if (nodeDef) { std::vector inputs = nodeDef->getActiveInputs(); - for (mx::InputPtr input : inputs) - { + for (mx::InputPtr input: inputs) { auto currNode = std::make_shared(input->getName(), _graphTotalSize); currNode->setInput(input); setUiNodeInfo(currNode, input->getType(), input->getCategory()); @@ -1338,25 +1107,19 @@ void Graph::buildUiNodeGraph(const mx::NodeGraphPtr& nodeGraphs) } // search node graph children to create uiNodes - for (mx::ElementPtr elem : children) - { + for (mx::ElementPtr elem: children) { mx::NodePtr node = elem->asA(); mx::InputPtr input = elem->asA(); mx::OutputPtr output = elem->asA(); std::string name = elem->getName(); auto currNode = std::make_shared(name, _graphTotalSize); - if (node) - { + if (node) { currNode->setNode(node); setUiNodeInfo(currNode, node->getType(), node->getCategory()); - } - else if (input) - { + } else if (input) { currNode->setInput(input); setUiNodeInfo(currNode, input->getType(), input->getCategory()); - } - else if (output) - { + } else if (output) { currNode->setOutput(output); setUiNodeInfo(currNode, output->getType(), output->getCategory()); } @@ -1364,12 +1127,9 @@ void Graph::buildUiNodeGraph(const mx::NodeGraphPtr& nodeGraphs) // Write out all connections. std::set processedEdges; - for (mx::OutputPtr output : nodeGraph->getOutputs()) - { - for (mx::Edge edge : output->traverseGraph()) - { - if (!processedEdges.count(edge)) - { + for (mx::OutputPtr output: nodeGraph->getOutputs()) { + for (mx::Edge edge: output->traverseGraph()) { + if (!processedEdges.count(edge)) { mx::ElementPtr upstreamElem = edge.getUpstreamElement(); mx::ElementPtr downstreamElem = edge.getDownstreamElement(); mx::ElementPtr connectingElem = edge.getConnectingElement(); @@ -1384,57 +1144,40 @@ void Graph::buildUiNodeGraph(const mx::NodeGraphPtr& nodeGraphs) std::string upName = upstreamElem->getName(); std::string upstreamType; std::string downstreamType; - if (upstreamNode) - { + if (upstreamNode) { upstreamType = "node"; - } - else if (upstreamInput) - { + } else if (upstreamInput) { upstreamType = "input"; - } - else if (upstreamOutput) - { + } else if (upstreamOutput) { upstreamType = "output"; } - if (downstreamNode) - { + if (downstreamNode) { downstreamType = "node"; - } - else if (downstreamInput) - { + } else if (downstreamInput) { downstreamType = "input"; - } - else if (downstreamOutput) - { + } else if (downstreamOutput) { downstreamType = "output"; } int upNode = findNode(upName, upstreamType); int downNode = findNode(downName, downstreamType); if (downNode > 0 && upNode > 0 && - _graphNodes[downNode]->getOutput() != nullptr) - { + _graphNodes[downNode]->getOutput() != nullptr) { // creating edges for the output nodes UiEdge newEdge = UiEdge(_graphNodes[upNode], _graphNodes[downNode], nullptr); - if (!edgeExists(newEdge)) - { + if (!edgeExists(newEdge)) { _graphNodes[downNode]->edges.push_back(newEdge); _graphNodes[downNode]->setInputNodeNum(1); _graphNodes[upNode]->setOutputConnection(_graphNodes[downNode]); _currEdge.push_back(newEdge); } - } - else if (connectingElem) - { + } else if (connectingElem) { mx::InputPtr connectingInput = connectingElem->asA(); - if (connectingInput) - { - if ((upNode >= 0) && (downNode >= 0)) - { + if (connectingInput) { + if ((upNode >= 0) && (downNode >= 0)) { UiEdge newEdge = UiEdge(_graphNodes[upNode], _graphNodes[downNode], connectingInput); - if (!edgeExists(newEdge)) - { + if (!edgeExists(newEdge)) { _graphNodes[downNode]->edges.push_back(newEdge); _graphNodes[downNode]->setInputNodeNum(1); _graphNodes[upNode]->setOutputConnection(_graphNodes[downNode]); @@ -1443,22 +1186,17 @@ void Graph::buildUiNodeGraph(const mx::NodeGraphPtr& nodeGraphs) } } } - if (upstreamNode) - { + if (upstreamNode) { std::vector ins = upstreamNode->getActiveInputs(); - for (mx::InputPtr input : ins) - { + for (mx::InputPtr input: ins) { // connecting input nodes - if (input->hasInterfaceName()) - { + if (input->hasInterfaceName()) { std::string interfaceName = input->getInterfaceName(); int newUp = findNode(interfaceName, "input"); - if (newUp >= 0) - { + if (newUp >= 0) { mx::InputPtr inputP = std::make_shared(downstreamElem, input->getName()); UiEdge newEdge = UiEdge(_graphNodes[newUp], _graphNodes[upNode], input); - if (!edgeExists(newEdge)) - { + if (!edgeExists(newEdge)) { _graphNodes[upNode]->edges.push_back(newEdge); _graphNodes[upNode]->setInputNodeNum(1); _graphNodes[newUp]->setOutputConnection(_graphNodes[upNode]); @@ -1475,44 +1213,34 @@ void Graph::buildUiNodeGraph(const mx::NodeGraphPtr& nodeGraphs) } // second pass to catch all of the connections that arent part of an output - for (mx::ElementPtr elem : children) - { + for (mx::ElementPtr elem: children) { mx::NodePtr node = elem->asA(); mx::InputPtr inputElem = elem->asA(); mx::OutputPtr output = elem->asA(); - if (node) - { + if (node) { std::vector inputs = node->getActiveInputs(); - for (mx::InputPtr input : inputs) - { + for (mx::InputPtr input: inputs) { mx::NodePtr upNode = input->getConnectedNode(); - if (upNode) - { + if (upNode) { int upNum = findNode(upNode->getName(), "node"); int downNode = findNode(node->getName(), "node"); - if ((upNum >= 0) && (downNode >= 0)) - { + if ((upNum >= 0) && (downNode >= 0)) { UiEdge newEdge = UiEdge(_graphNodes[upNum], _graphNodes[downNode], input); - if (!edgeExists(newEdge)) - { + if (!edgeExists(newEdge)) { _graphNodes[downNode]->edges.push_back(newEdge); _graphNodes[downNode]->setInputNodeNum(1); _graphNodes[upNum]->setOutputConnection(_graphNodes[downNode]); _currEdge.push_back(newEdge); } } - } - else if (input->getInterfaceInput()) - { + } else if (input->getInterfaceInput()) { int upNum = findNode(input->getInterfaceInput()->getName(), "input"); int downNode = findNode(node->getName(), "node"); - if ((upNum >= 0) && (downNode >= 0)) - { + if ((upNum >= 0) && (downNode >= 0)) { UiEdge newEdge = UiEdge(_graphNodes[upNum], _graphNodes[downNode], input); - if (!edgeExists(newEdge)) - { + if (!edgeExists(newEdge)) { _graphNodes[downNode]->edges.push_back(newEdge); _graphNodes[downNode]->setInputNodeNum(1); _graphNodes[upNum]->setOutputConnection(_graphNodes[downNode]); @@ -1521,17 +1249,13 @@ void Graph::buildUiNodeGraph(const mx::NodeGraphPtr& nodeGraphs) } } } - } - else if (output) - { + } else if (output) { mx::NodePtr upNode = output->getConnectedNode(); - if (upNode) - { + if (upNode) { int upNum = findNode(upNode->getName(), "node"); int downNode = findNode(output->getName(), "output"); UiEdge newEdge = UiEdge(_graphNodes[upNum], _graphNodes[downNode], nullptr); - if (!edgeExists(newEdge)) - { + if (!edgeExists(newEdge)) { _graphNodes[downNode]->edges.push_back(newEdge); _graphNodes[downNode]->setInputNodeNum(1); _graphNodes[upNum]->setOutputConnection(_graphNodes[downNode]); @@ -1544,27 +1268,17 @@ void Graph::buildUiNodeGraph(const mx::NodeGraphPtr& nodeGraphs) } // return node position in _graphNodes based off node name and type to account for input/output UiNodes with same names as mx Nodes -int Graph::findNode(const std::string& name, const std::string& type) -{ +int Graph::findNode(const std::string &name, const std::string &type) { int count = 0; - for (size_t i = 0; i < _graphNodes.size(); i++) - { - if (_graphNodes[i]->getName() == name) - { - if (type == "node" && _graphNodes[i]->getNode() != nullptr) - { + for (size_t i = 0; i < _graphNodes.size(); i++) { + if (_graphNodes[i]->getName() == name) { + if (type == "node" && _graphNodes[i]->getNode() != nullptr) { return count; - } - else if (type == "input" && _graphNodes[i]->getInput() != nullptr) - { + } else if (type == "input" && _graphNodes[i]->getInput() != nullptr) { return count; - } - else if (type == "output" && _graphNodes[i]->getOutput() != nullptr) - { + } else if (type == "output" && _graphNodes[i]->getOutput() != nullptr) { return count; - } - else if (type == "nodegraph" && _graphNodes[i]->getNodeGraph() != nullptr) - { + } else if (type == "nodegraph" && _graphNodes[i]->getNodeGraph() != nullptr) { return count; } } @@ -1574,14 +1288,12 @@ int Graph::findNode(const std::string& name, const std::string& type) } // set position of pasted nodes based off of original node position -void Graph::positionPasteBin(ImVec2 pos) -{ +void Graph::positionPasteBin(ImVec2 pos) { ImVec2 totalPos = ImVec2(0, 0); ImVec2 avgPos = ImVec2(0, 0); // get average position of original nodes - for (auto pasteNode : _copiedNodes) - { + for (auto pasteNode: _copiedNodes) { ImVec2 origPos = ed::GetNodePosition(pasteNode.first->getId()); totalPos.x += origPos.x; totalPos.y += origPos.y; @@ -1593,10 +1305,8 @@ void Graph::positionPasteBin(ImVec2 pos) ImVec2 offset = ImVec2(0, 0); offset.x = pos.x - avgPos.x; offset.y = pos.y - avgPos.y; - for (auto pasteNode : _copiedNodes) - { - if (!pasteNode.second) - { + for (auto pasteNode: _copiedNodes) { + if (!pasteNode.second) { continue; } ImVec2 newPos = ImVec2(0, 0); @@ -1605,22 +1315,18 @@ void Graph::positionPasteBin(ImVec2 pos) ed::SetNodePosition(pasteNode.second->getId(), newPos); } } -void Graph::createEdge(UiNodePtr upNode, UiNodePtr downNode, mx::InputPtr connectingInput) -{ - if (downNode->getOutput()) - { + +void Graph::createEdge(UiNodePtr upNode, UiNodePtr downNode, mx::InputPtr connectingInput) { + if (downNode->getOutput()) { // creating edges for the output nodes UiEdge newEdge = UiEdge(upNode, downNode, nullptr); - if (!edgeExists(newEdge)) - { + if (!edgeExists(newEdge)) { downNode->edges.push_back(newEdge); downNode->setInputNodeNum(1); upNode->setOutputConnection(downNode); _currEdge.push_back(newEdge); } - } - else if (connectingInput) - { + } else if (connectingInput) { UiEdge newEdge = UiEdge(upNode, downNode, connectingInput); downNode->edges.push_back(newEdge); downNode->setInputNodeNum(1); @@ -1629,134 +1335,102 @@ void Graph::createEdge(UiNodePtr upNode, UiNodePtr downNode, mx::InputPtr connec } } -void Graph::copyUiNode(UiNodePtr node) -{ +void Graph::copyUiNode(UiNodePtr node) { UiNodePtr copyNode = std::make_shared(mx::EMPTY_STRING, int(_graphTotalSize + 1)); ++_graphTotalSize; - if (node->getMxElement()) - { + if (node->getMxElement()) { std::string newName = _currGraphElem->createValidChildName(node->getName()); - if (node->getNode()) - { + if (node->getNode()) { mx::NodePtr mxNode; mxNode = _currGraphElem->addNodeInstance(node->getNode()->getNodeDef()); mxNode->copyContentFrom(node->getNode()); - mxNode->setName(newName); + setName(mxNode, newName); copyNode->setNode(mxNode); - } - else if (node->getInput()) - { + } else if (node->getInput()) { mx::InputPtr mxInput; mxInput = _currGraphElem->addInput(newName); mxInput->copyContentFrom(node->getInput()); copyNode->setInput(mxInput); - } - else if (node->getOutput()) - { + } else if (node->getOutput()) { mx::OutputPtr mxOutput; mxOutput = _currGraphElem->addOutput(newName); mxOutput->copyContentFrom(node->getOutput()); - mxOutput->setName(newName); + setName(mxOutput, newName); copyNode->setOutput(mxOutput); } - copyNode->getMxElement()->setName(newName); - copyNode->setName(newName); - } - else if (node->getNodeGraph()) - { + setName(copyNode->getMxElement(), newName); + setName(copyNode, newName); + } else if (node->getNodeGraph()) { _graphDoc->addNodeGraph(); std::string nodeGraphName = _graphDoc->getNodeGraphs().back()->getName(); copyNode->setNodeGraph(_graphDoc->getNodeGraphs().back()); - copyNode->setName(nodeGraphName); + setName(copyNode, nodeGraphName); copyNodeGraph(node, copyNode); } setUiNodeInfo(copyNode, node->getType(), node->getCategory()); _copiedNodes[node] = copyNode; _graphNodes.push_back(copyNode); } -void Graph::copyNodeGraph(UiNodePtr origGraph, UiNodePtr copyGraph) -{ + +void Graph::copyNodeGraph(UiNodePtr origGraph, UiNodePtr copyGraph) { copyGraph->getNodeGraph()->copyContentFrom(origGraph->getNodeGraph()); std::vector inputs = copyGraph->getNodeGraph()->getActiveInputs(); - for (mx::InputPtr input : inputs) - { + for (const mx::InputPtr &input: inputs) { std::string newName = _graphDoc->createValidChildName(input->getName()); - input->setName(newName); + setName(input, newName); } } -void Graph::copyInputs() -{ - for (std::map::iterator iter = _copiedNodes.begin(); iter != _copiedNodes.end(); ++iter) - { + +void Graph::copyInputs() { + for (std::map::iterator iter = _copiedNodes.begin(); iter != _copiedNodes.end(); ++iter) { int count = 0; UiNodePtr origNode = iter->first; UiNodePtr copyNode = iter->second; - for (UiPinPtr pin : origNode->inputPins) - { - if (origNode->getConnectedNode(pin->_name) && !_ctrlClick) - { + for (UiPinPtr pin: origNode->inputPins) { + if (origNode->getConnectedNode(pin->_name) && !_ctrlClick) { // if original node is connected check if connect node is in copied nodes - if (_copiedNodes.find(origNode->getConnectedNode(pin->_name)) != _copiedNodes.end()) - { + if (_copiedNodes.find(origNode->getConnectedNode(pin->_name)) != _copiedNodes.end()) { // set copy node connected to the value at this key // create an edge - createEdge(_copiedNodes[origNode->getConnectedNode(pin->_name)], copyNode, copyNode->inputPins[count]->_input); + createEdge(_copiedNodes[origNode->getConnectedNode(pin->_name)], copyNode, + copyNode->inputPins[count]->_input); UiNodePtr upNode = _copiedNodes[origNode->getConnectedNode(pin->_name)]; - if (copyNode->getNode() || copyNode->getNodeGraph()) - { + if (copyNode->getNode() || copyNode->getNodeGraph()) { mx::InputPtr connectingInput = nullptr; copyNode->inputPins[count]->_input->copyContentFrom(pin->_input); // update value to be empty - if (copyNode->getNode() && copyNode->getNode()->getType() == mx::SURFACE_SHADER_TYPE_STRING) - { - if (upNode->getOutput()) - { + if (copyNode->getNode() && copyNode->getNode()->getType() == mx::SURFACE_SHADER_TYPE_STRING) { + if (upNode->getOutput()) { copyNode->inputPins[count]->_input->setConnectedOutput(upNode->getOutput()); - } - else if (upNode->getInput()) - { + } else if (upNode->getInput()) { copyNode->inputPins[count]->_input->setInterfaceName(upNode->getName()); - } - else - { + } else { // node graph - if (upNode->getNodeGraph()) - { + if (upNode->getNodeGraph()) { ed::PinId outputId = getOutputPin(copyNode, upNode, copyNode->inputPins[count]); - for (UiPinPtr outPin : upNode->outputPins) - { - if (outPin->_pinId == outputId) - { + for (UiPinPtr outPin: upNode->outputPins) { + if (outPin->_pinId == outputId) { mx::OutputPtr outputs = upNode->getNodeGraph()->getOutput(outPin->_name); copyNode->inputPins[count]->_input->setConnectedOutput(outputs); } } - } - else - { + } else { copyNode->inputPins[count]->_input->setConnectedNode(upNode->getNode()); } } - } - else - { - if (upNode->getInput()) - { + } else { + if (upNode->getInput()) { copyNode->inputPins[count]->_input->setInterfaceName(upNode->getName()); - } - else - { + } else { copyNode->inputPins[count]->_input->setConnectedNode(upNode->getNode()); } } copyNode->inputPins[count]->setConnected(true); copyNode->inputPins[count]->_input->removeAttribute(mx::ValueElement::VALUE_ATTRIBUTE); - } - else if (copyNode->getOutput() != nullptr) - { + } else if (copyNode->getOutput() != nullptr) { mx::InputPtr connectingInput = nullptr; copyNode->getOutput()->setConnectedNode(upNode->getNode()); } @@ -1764,11 +1438,8 @@ void Graph::copyInputs() // update input node num and output connections copyNode->setInputNodeNum(1); upNode->setOutputConnection(copyNode); - } - else if (pin->_input) - { - if (pin->_input->getInterfaceInput()) - { + } else if (pin->_input) { + if (pin->_input->getInterfaceInput()) { copyNode->inputPins[count]->_input->removeAttribute(mx::ValueElement::INTERFACE_NAME_ATTRIBUTE); } copyNode->inputPins[count]->setConnected(false); @@ -1781,14 +1452,13 @@ void Graph::copyInputs() } } } + // add node to graphNodes based off of node def information -void Graph::addNode(const std::string& category, const std::string& name, const std::string& type) -{ +void Graph::addNode(const std::string &category, const std::string &name, const std::string &type) { mx::NodePtr node = nullptr; std::vector matchingNodeDefs; // create document or node graph is there is not already one - if (category == "output") - { + if (category == "output") { std::string outName = ""; mx::OutputPtr newOut; // add output as child of correct parent and create valid name @@ -1799,8 +1469,7 @@ void Graph::addNode(const std::string& category, const std::string& name, const setUiNodeInfo(outputNode, type, category); return; } - if (category == "input") - { + if (category == "input") { std::string inName = ""; mx::InputPtr newIn = nullptr; // add input as child of correct parent and create valid name @@ -1811,9 +1480,7 @@ void Graph::addNode(const std::string& category, const std::string& name, const inputNode->setInput(newIn); setUiNodeInfo(inputNode, type, category); return; - } - else if (category == "group") - { + } else if (category == "group") { auto groupNode = std::make_shared(name, int(++_graphTotalSize)); // set message of group uinode in order to identify it as such groupNode->setMessage("Comment"); @@ -1821,9 +1488,7 @@ void Graph::addNode(const std::string& category, const std::string& name, const // create ui portions of group node buildGroupNode(_graphNodes.back()); return; - } - else if (category == "nodegraph") - { + } else if (category == "nodegraph") { // create new mx::NodeGraph and set as current node graph _graphDoc->addNodeGraph(); std::string nodeGraphName = _graphDoc->getNodeGraphs().back()->getName(); @@ -1833,32 +1498,25 @@ void Graph::addNode(const std::string& category, const std::string& name, const setUiNodeInfo(nodeGraphNode, type, "nodegraph"); return; - } - else - { + } else { matchingNodeDefs = _graphDoc->getMatchingNodeDefs(category); - for (mx::NodeDefPtr nodedef : matchingNodeDefs) - { + for (mx::NodeDefPtr nodedef: matchingNodeDefs) { std::string nodedefName = nodedef->getName(); std::string sub = getNodeDefId(nodedefName); - if (sub == name) - { + if (sub == name) { node = _currGraphElem->addNodeInstance(nodedef, _currGraphElem->createValidChildName(name)); } } } - if (node) - { + if (node) { int num = 0; int countDef = 0; - for (size_t i = 0; i < matchingNodeDefs.size(); i++) - { + for (size_t i = 0; i < matchingNodeDefs.size(); i++) { // use substring of name in order to remove ND_ std::string nodedefName = matchingNodeDefs[i]->getName(); std::string sub = getNodeDefId(nodedefName); - if (sub == name) - { + if (sub == name) { num = countDef; } countDef++; @@ -1872,17 +1530,17 @@ void Graph::addNode(const std::string& category, const std::string& name, const newNode->_showAllInputs = true; node->setType(type); ++_graphTotalSize; - for (mx::InputPtr input : defInputs) - { - UiPinPtr inPin = std::make_shared(_graphTotalSize, &*input->getName().begin(), input->getType(), newNode, ax::NodeEditor::PinKind::Input, input, nullptr); + for (mx::InputPtr input: defInputs) { + UiPinPtr inPin = std::make_shared(_graphTotalSize, &*input->getName().begin(), input->getType(), + newNode, ax::NodeEditor::PinKind::Input, input, nullptr); newNode->inputPins.push_back(inPin); _currPins.push_back(inPin); ++_graphTotalSize; } std::vector defOutputs = matchingNodeDefs[num]->getActiveOutputs(); - for (mx::OutputPtr output : defOutputs) - { - UiPinPtr outPin = std::make_shared(_graphTotalSize, &*output->getName().begin(), output->getType(), newNode, ax::NodeEditor::PinKind::Output, nullptr, nullptr); + for (mx::OutputPtr output: defOutputs) { + UiPinPtr outPin = std::make_shared(_graphTotalSize, &*output->getName().begin(), output->getType(), + newNode, ax::NodeEditor::PinKind::Output, nullptr, nullptr); newNode->outputPins.push_back(outPin); _currPins.push_back(outPin); ++_graphTotalSize; @@ -1892,13 +1550,11 @@ void Graph::addNode(const std::string& category, const std::string& name, const updateMaterials(); } } + // return node pos -int Graph::getNodeId(ed::PinId pinId) -{ - for (UiPinPtr pin : _currPins) - { - if (pin->_pinId == pinId) - { +int Graph::getNodeId(ed::PinId pinId) { + for (UiPinPtr pin: _currPins) { + if (pin->_pinId == pinId) { return findNode(pin->_pinNode->getId()); } } @@ -1906,26 +1562,22 @@ int Graph::getNodeId(ed::PinId pinId) } // return pin based off of UiPin id -UiPinPtr Graph::getPin(ed::PinId pinId) -{ - for (UiPinPtr pin : _currPins) - { - if (pin->_pinId == pinId) - { +UiPinPtr Graph::getPin(ed::PinId pinId) { + for (UiPinPtr pin: _currPins) { + if (pin->_pinId == pinId) { return pin; } } - UiPinPtr nullPin = std::make_shared(-10000, "nullPin", "null", nullptr, ax::NodeEditor::PinKind::Output, nullptr, nullptr); + UiPinPtr nullPin = std::make_shared(-10000, "nullPin", "null", nullptr, ax::NodeEditor::PinKind::Output, + nullptr, nullptr); return nullPin; } // This function is based off of the pin icon function in the ImGui Node Editor blueprints-example.cpp -void Graph::DrawPinIcon(std::string type, bool connected, int alpha) -{ +void Graph::DrawPinIcon(std::string type, bool connected, int alpha) { ax::Drawing::IconType iconType = ax::Drawing::IconType::Flow; ImColor color = ImColor(0, 0, 0, 255); - if (_pinColor.find(type) != _pinColor.end()) - { + if (_pinColor.find(type) != _pinColor.end()) { color = _pinColor[type]; } @@ -1935,8 +1587,7 @@ void Graph::DrawPinIcon(std::string type, bool connected, int alpha) } // This function is based off of the comment node in the ImGui Node Editor blueprints-example.cpp -void Graph::buildGroupNode(UiNodePtr node) -{ +void Graph::buildGroupNode(UiNodePtr node) { const float commentAlpha = 0.75f; ImGui::PushStyleVar(ImGuiStyleVar_Alpha, commentAlpha); @@ -1958,8 +1609,7 @@ void Graph::buildGroupNode(UiNodePtr node) ed::EndNode(); ed::PopStyleColor(2); ImGui::PopStyleVar(); - if (ed::BeginGroupHint(node->getId())) - { + if (ed::BeginGroupHint(node->getId())) { auto bgAlpha = static_cast(ImGui::GetStyle().Alpha * 255); auto min = ed::GetGroupMin(); @@ -1970,7 +1620,7 @@ void Graph::buildGroupNode(UiNodePtr node) ImVec2 nameSize = ImGui::CalcTextSize(temp.c_str()); ImGui::PushItemWidth(nameSize.x); ImGui::InputText("##edit", &tempName); - node->setName(tempName); + setName(node, tempName); ImGui::PopID(); ImGui::EndGroup(); @@ -1980,57 +1630,44 @@ void Graph::buildGroupNode(UiNodePtr node) ImRect hintFrameBounds = expandImRect(hintBounds, 8, 4); drawList->AddRectFilled( - hintFrameBounds.GetTL(), - hintFrameBounds.GetBR(), - IM_COL32(255, 255, 255, 64 * bgAlpha / 255), 4.0f); + hintFrameBounds.GetTL(), + hintFrameBounds.GetBR(), + IM_COL32(255, 255, 255, 64 * bgAlpha / 255), 4.0f); drawList->AddRect( - hintFrameBounds.GetTL(), - hintFrameBounds.GetBR(), - IM_COL32(0, 255, 255, 128 * bgAlpha / 255), 4.0f); + hintFrameBounds.GetTL(), + hintFrameBounds.GetBR(), + IM_COL32(0, 255, 255, 128 * bgAlpha / 255), 4.0f); } ed::EndGroupHint(); } -bool Graph::readOnly() -{ + +bool Graph::readOnly() { // if the sources are not the same then the current graph cannot be modified return _currGraphElem->getActiveSourceUri() != _graphDoc->getActiveSourceUri(); } -mx::InputPtr Graph::findInput(mx::InputPtr nodeInput, std::string name) -{ - if (_isNodeGraph) - { - for (UiNodePtr node : _graphNodes) - { - if (node->getNode()) - { - for (mx::InputPtr input : node->getNode()->getActiveInputs()) - { - if (input->getInterfaceInput()) - { - if (input->getInterfaceInput() == nodeInput) - { +mx::InputPtr Graph::findInput(mx::InputPtr nodeInput, std::string name) { + if (_isNodeGraph) { + for (UiNodePtr node: _graphNodes) { + if (node->getNode()) { + for (mx::InputPtr input: node->getNode()->getActiveInputs()) { + if (input->getInterfaceInput()) { + + if (input->getInterfaceInput() == nodeInput) { return input; } } } } } - } - else - { - if (_currUiNode->getNodeGraph()) - { - for (mx::NodePtr node : _currUiNode->getNodeGraph()->getNodes()) - { - for (mx::InputPtr input : node->getActiveInputs()) - { - if (input->getInterfaceInput()) - { + } else { + if (_currUiNode->getNodeGraph()) { + for (mx::NodePtr node: _currUiNode->getNodeGraph()->getNodes()) { + for (mx::InputPtr input: node->getActiveInputs()) { + if (input->getInterfaceInput()) { - if (input->getInterfaceName() == name) - { + if (input->getInterfaceName() == name) { return input; } } @@ -2040,32 +1677,34 @@ mx::InputPtr Graph::findInput(mx::InputPtr nodeInput, std::string name) } return nullptr; } + // This function is based off the splitter function in the ImGui Node Editor blueprints-example.cpp -static bool Splitter(bool split_vertically, float thickness, float* size1, float* size2, float min_size1, float min_size2, float splitter_long_axis_size = -1.0f) -{ +static bool +Splitter(bool split_vertically, float thickness, float *size1, float *size2, float min_size1, float min_size2, + float splitter_long_axis_size = -1.0f) { using namespace ImGui; - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; + ImGuiContext &g = *GImGui; + ImGuiWindow *window = g.CurrentWindow; ImGuiID id = window->GetID("##Splitter"); ImRect bb; bb.Min = window->DC.CursorPos + (split_vertically ? ImVec2(*size1, 0.0f) : ImVec2(0.0f, *size1)); - bb.Max = bb.Min + CalcItemSize(split_vertically ? ImVec2(thickness, splitter_long_axis_size) : ImVec2(splitter_long_axis_size, thickness), 0.0f, 0.0f); - return SplitterBehavior(bb, id, split_vertically ? ImGuiAxis_X : ImGuiAxis_Y, size1, size2, min_size1, min_size2, 0.0f); + bb.Max = bb.Min + CalcItemSize( + split_vertically ? ImVec2(thickness, splitter_long_axis_size) : ImVec2(splitter_long_axis_size, thickness), + 0.0f, 0.0f); + return SplitterBehavior(bb, id, split_vertically ? ImGuiAxis_X : ImGuiAxis_Y, size1, size2, min_size1, min_size2, + 0.0f); } -void Graph::drawOutputPins(UiNodePtr node, const std::string& longestInputLabel) -{ +void Graph::drawOutputPins(UiNodePtr node, const std::string &longestInputLabel) { std::string longestLabel = longestInputLabel; - for (UiPinPtr pin : node->outputPins) - { + for (UiPinPtr pin: node->outputPins) { if (pin->_name.size() > longestLabel.size()) longestLabel = pin->_name; } // Create output pins float nodeWidth = ImGui::CalcTextSize(longestLabel.c_str()).x; - for (UiPinPtr pin : node->outputPins) - { + for (UiPinPtr pin: node->outputPins) { const float indent = nodeWidth - ImGui::CalcTextSize(pin->_name.c_str()).x; ImGui::Indent(indent); ImGui::TextUnformatted(pin->_name.c_str()); @@ -2073,12 +1712,9 @@ void Graph::drawOutputPins(UiNodePtr node, const std::string& longestInputLabel) ed::BeginPin(pin->_pinId, ed::PinKind::Output); bool connected = pin->getConnected(); - if (!_pinFilterType.empty()) - { + if (!_pinFilterType.empty()) { DrawPinIcon(pin->_type, connected, _pinFilterType == pin->_type ? DEFAULT_ALPHA : FILTER_ALPHA); - } - else - { + } else { DrawPinIcon(pin->_type, connected, DEFAULT_ALPHA); } @@ -2087,24 +1723,17 @@ void Graph::drawOutputPins(UiNodePtr node, const std::string& longestInputLabel) } } -void Graph::drawInputPin(UiPinPtr pin) -{ +void Graph::drawInputPin(UiPinPtr pin) { ed::BeginPin(pin->_pinId, ed::PinKind::Input); ImGui::PushID(int(pin->_pinId.Get())); bool connected = pin->getConnected(); - if (!_pinFilterType.empty()) - { - if (_pinFilterType == pin->_type) - { + if (!_pinFilterType.empty()) { + if (_pinFilterType == pin->_type) { DrawPinIcon(pin->_type, connected, DEFAULT_ALPHA); - } - else - { + } else { DrawPinIcon(pin->_type, connected, FILTER_ALPHA); } - } - else - { + } else { DrawPinIcon(pin->_type, connected, DEFAULT_ALPHA); } ImGui::PopID(); @@ -2114,53 +1743,43 @@ void Graph::drawInputPin(UiPinPtr pin) ImGui::TextUnformatted(pin->_name.c_str()); } -std::vector Graph::createNodes(bool nodegraph) -{ +std::vector Graph::createNodes(bool nodegraph) { std::vector outputNum; - for (UiNodePtr node : _graphNodes) - { - if (node->getCategory() == "group") - { + for (UiNodePtr node: _graphNodes) { + if (node->getCategory() == "group") { buildGroupNode(node); - } - else - { + } else { // color for output pin std::string outputType; - if (node->getNode() != nullptr) - { + if (node->getNode() != nullptr) { ed::BeginNode(node->getId()); ImGui::PushID(node->getId()); ImGui::SetWindowFontScale(1.2f * _fontScale); ImGui::GetWindowDrawList()->AddRectFilled( - ImGui::GetCursorScreenPos() + ImVec2(-7.0, -8.0), - ImGui::GetCursorScreenPos() + ImVec2(ed::GetNodeSize(node->getId()).x - 9.f, ImGui::GetTextLineHeight() + 2.f), - ImColor(ImColor(55, 55, 55, 255)), 12.f); + ImGui::GetCursorScreenPos() + ImVec2(-7.0, -8.0), + ImGui::GetCursorScreenPos() + + ImVec2(ed::GetNodeSize(node->getId()).x - 9.f, ImGui::GetTextLineHeight() + 2.f), + ImColor(ImColor(55, 55, 55, 255)), 12.f); ImGui::GetWindowDrawList()->AddRectFilled( - ImGui::GetCursorScreenPos() + ImVec2(-7.0, 3), - ImGui::GetCursorScreenPos() + ImVec2(ed::GetNodeSize(node->getId()).x - 9.f, ImGui::GetTextLineHeight() + 2.f), - ImColor(ImColor(55, 55, 55, 255)), 0.f); + ImGui::GetCursorScreenPos() + ImVec2(-7.0, 3), + ImGui::GetCursorScreenPos() + + ImVec2(ed::GetNodeSize(node->getId()).x - 9.f, ImGui::GetTextLineHeight() + 2.f), + ImColor(ImColor(55, 55, 55, 255)), 0.f); ImGui::Text("%s", node->getName().c_str()); ImGui::SetWindowFontScale(_fontScale); std::string longestInputLabel = node->getName(); - for (UiPinPtr pin : node->inputPins) - { + for (UiPinPtr pin: node->inputPins) { UiNodePtr upUiNode = node->getConnectedNode(pin->_name); - if (upUiNode) - { + if (upUiNode) { size_t pinIndex = 0; - if (upUiNode->outputPins.size() > 0) - { + if (upUiNode->outputPins.size() > 0) { const std::string outputString = pin->_input->getOutputString(); - if (!outputString.empty()) - { - for (size_t i = 0; i < upUiNode->outputPins.size(); i++) - { + if (!outputString.empty()) { + for (size_t i = 0; i < upUiNode->outputPins.size(); i++) { UiPinPtr outPin = upUiNode->outputPins[i]; - if (outPin->_name == outputString) - { + if (outPin->_name == outputString) { pinIndex = i; break; } @@ -2171,8 +1790,7 @@ std::vector Graph::createNodes(bool nodegraph) } pin->setConnected(true); } - if (node->_showAllInputs || (pin->getConnected() || node->getNode()->getInput(pin->_name))) - { + if (node->_showAllInputs || (pin->getConnected() || node->getNode()->getInput(pin->_name))) { drawInputPin(pin); if (pin->_name.size() > longestInputLabel.size()) @@ -2182,51 +1800,42 @@ std::vector Graph::createNodes(bool nodegraph) drawOutputPins(node, longestInputLabel); // set color of output pin - if (node->getNode()->getType() == mx::SURFACE_SHADER_TYPE_STRING) - { - if (node->getOutputConnections().size() > 0) - { - for (UiNodePtr outputCon : node->getOutputConnections()) - { + if (node->getNode()->getType() == mx::SURFACE_SHADER_TYPE_STRING) { + if (node->getOutputConnections().size() > 0) { + for (UiNodePtr outputCon: node->getOutputConnections()) { outputNum.push_back(findNode(outputCon->getId())); } } } - } - else if (node->getInput() != nullptr) - { + } else if (node->getInput() != nullptr) { std::string longestInputLabel = node->getName(); ed::BeginNode(node->getId()); ImGui::PushID(node->getId()); ImGui::SetWindowFontScale(1.2f * _fontScale); ImGui::GetWindowDrawList()->AddRectFilled( - ImGui::GetCursorScreenPos() + ImVec2(-7.0f, -8.0f), - ImGui::GetCursorScreenPos() + ImVec2(ed::GetNodeSize(node->getId()).x - 9.f, ImGui::GetTextLineHeight() + 2.f), - ImColor(ImColor(85, 85, 85, 255)), 12.f); + ImGui::GetCursorScreenPos() + ImVec2(-7.0f, -8.0f), + ImGui::GetCursorScreenPos() + + ImVec2(ed::GetNodeSize(node->getId()).x - 9.f, ImGui::GetTextLineHeight() + 2.f), + ImColor(ImColor(85, 85, 85, 255)), 12.f); ImGui::GetWindowDrawList()->AddRectFilled( - ImGui::GetCursorScreenPos() + ImVec2(-7.0f, 3.f), - ImGui::GetCursorScreenPos() + ImVec2(ed::GetNodeSize(node->getId()).x - 9.f, ImGui::GetTextLineHeight() + 2.f), - ImColor(ImColor(85, 85, 85, 255)), 0.f); + ImGui::GetCursorScreenPos() + ImVec2(-7.0f, 3.f), + ImGui::GetCursorScreenPos() + + ImVec2(ed::GetNodeSize(node->getId()).x - 9.f, ImGui::GetTextLineHeight() + 2.f), + ImColor(ImColor(85, 85, 85, 255)), 0.f); ImGui::Text("%s", node->getName().c_str()); ImGui::SetWindowFontScale(_fontScale); outputType = node->getInput()->getType(); - for (UiPinPtr pin : node->inputPins) - { + for (UiPinPtr pin: node->inputPins) { UiNodePtr upUiNode = node->getConnectedNode(node->getName()); - if (upUiNode) - { - if (upUiNode->outputPins.size()) - { + if (upUiNode) { + if (upUiNode->outputPins.size()) { std::string outString = pin->_output ? pin->_output->getOutputString() : mx::EMPTY_STRING; size_t pinIndex = 0; - if (!outString.empty()) - { - for (size_t i = 0; i < upUiNode->outputPins.size(); i++) - { - if (upUiNode->outputPins[i]->_name == outString) - { + if (!outString.empty()) { + for (size_t i = 0; i < upUiNode->outputPins.size(); i++) { + if (upUiNode->outputPins[i]->_name == outString) { pinIndex = i; break; } @@ -2237,19 +1846,13 @@ std::vector Graph::createNodes(bool nodegraph) pin->setConnected(true); } ed::BeginPin(pin->_pinId, ed::PinKind::Input); - if (!_pinFilterType.empty()) - { - if (_pinFilterType == pin->_type) - { + if (!_pinFilterType.empty()) { + if (_pinFilterType == pin->_type) { DrawPinIcon(pin->_type, true, DEFAULT_ALPHA); - } - else - { + } else { DrawPinIcon(pin->_type, true, FILTER_ALPHA); } - } - else - { + } else { DrawPinIcon(pin->_type, true, DEFAULT_ALPHA); } @@ -2261,42 +1864,36 @@ std::vector Graph::createNodes(bool nodegraph) longestInputLabel = pin->_name; } drawOutputPins(node, longestInputLabel); - } - else if (node->getOutput() != nullptr) - { + } else if (node->getOutput() != nullptr) { std::string longestInputLabel = node->getName(); ed::BeginNode(node->getId()); ImGui::PushID(node->getId()); ImGui::SetWindowFontScale(1.2f * _fontScale); ImGui::GetWindowDrawList()->AddRectFilled( - ImGui::GetCursorScreenPos() + ImVec2(-7.0, -8.0), - ImGui::GetCursorScreenPos() + ImVec2(ed::GetNodeSize(node->getId()).x - 9.f, ImGui::GetTextLineHeight() + 2.f), - ImColor(ImColor(35, 35, 35, 255)), 12.f); + ImGui::GetCursorScreenPos() + ImVec2(-7.0, -8.0), + ImGui::GetCursorScreenPos() + + ImVec2(ed::GetNodeSize(node->getId()).x - 9.f, ImGui::GetTextLineHeight() + 2.f), + ImColor(ImColor(35, 35, 35, 255)), 12.f); ImGui::GetWindowDrawList()->AddRectFilled( - ImGui::GetCursorScreenPos() + ImVec2(-7.0, 3), - ImGui::GetCursorScreenPos() + ImVec2(ed::GetNodeSize(node->getId()).x - 9.f, ImGui::GetTextLineHeight() + 2.f), - ImColor(ImColor(35, 35, 35, 255)), 0); + ImGui::GetCursorScreenPos() + ImVec2(-7.0, 3), + ImGui::GetCursorScreenPos() + + ImVec2(ed::GetNodeSize(node->getId()).x - 9.f, ImGui::GetTextLineHeight() + 2.f), + ImColor(ImColor(35, 35, 35, 255)), 0); ImGui::Text("%s", node->getName().c_str()); ImGui::SetWindowFontScale(_fontScale); outputType = node->getOutput()->getType(); - for (UiPinPtr pin : node->inputPins) - { + for (UiPinPtr pin: node->inputPins) { UiNodePtr upUiNode = node->getConnectedNode(""); - if (upUiNode) - { - if (upUiNode->outputPins.size()) - { + if (upUiNode) { + if (upUiNode->outputPins.size()) { std::string outString = pin->_output ? pin->_output->getOutputString() : mx::EMPTY_STRING; size_t pinIndex = 0; - if (!outString.empty()) - { - for (size_t i = 0; i < upUiNode->outputPins.size(); i++) - { - if (upUiNode->outputPins[i]->_name == outString) - { + if (!outString.empty()) { + for (size_t i = 0; i < upUiNode->outputPins.size(); i++) { + if (upUiNode->outputPins[i]->_name == outString) { pinIndex = i; break; } @@ -2307,19 +1904,13 @@ std::vector Graph::createNodes(bool nodegraph) } ed::BeginPin(pin->_pinId, ed::PinKind::Input); - if (!_pinFilterType.empty()) - { - if (_pinFilterType == pin->_type) - { + if (!_pinFilterType.empty()) { + if (_pinFilterType == pin->_type) { DrawPinIcon(pin->_type, true, DEFAULT_ALPHA); - } - else - { + } else { DrawPinIcon(pin->_type, true, FILTER_ALPHA); } - } - else - { + } else { DrawPinIcon(pin->_type, true, DEFAULT_ALPHA); } ImGui::SameLine(); @@ -2331,36 +1922,32 @@ std::vector Graph::createNodes(bool nodegraph) longestInputLabel = pin->_name; } drawOutputPins(node, longestInputLabel); - if (nodegraph) - { + if (nodegraph) { outputNum.push_back(findNode(node->getId())); } - } - else if (node->getNodeGraph() != nullptr) - { + } else if (node->getNodeGraph() != nullptr) { std::string longestInputLabel = node->getName(); ed::BeginNode(node->getId()); ImGui::PushID(node->getId()); ImGui::SetWindowFontScale(1.2f * _fontScale); ImGui::GetWindowDrawList()->AddRectFilled( - ImGui::GetCursorScreenPos() + ImVec2(-7.0, -8.0), - ImGui::GetCursorScreenPos() + ImVec2(ed::GetNodeSize(node->getId()).x - 9.f, ImGui::GetTextLineHeight() + 2.f), - ImColor(ImColor(35, 35, 35, 255)), 12.f); + ImGui::GetCursorScreenPos() + ImVec2(-7.0, -8.0), + ImGui::GetCursorScreenPos() + + ImVec2(ed::GetNodeSize(node->getId()).x - 9.f, ImGui::GetTextLineHeight() + 2.f), + ImColor(ImColor(35, 35, 35, 255)), 12.f); ImGui::GetWindowDrawList()->AddRectFilled( - ImGui::GetCursorScreenPos() + ImVec2(-7.0, 3), - ImGui::GetCursorScreenPos() + ImVec2(ed::GetNodeSize(node->getId()).x - 9.f, ImGui::GetTextLineHeight() + 2.f), - ImColor(ImColor(35, 35, 35, 255)), 0); + ImGui::GetCursorScreenPos() + ImVec2(-7.0, 3), + ImGui::GetCursorScreenPos() + + ImVec2(ed::GetNodeSize(node->getId()).x - 9.f, ImGui::GetTextLineHeight() + 2.f), + ImColor(ImColor(35, 35, 35, 255)), 0); ImGui::Text("%s", node->getName().c_str()); ImGui::SetWindowFontScale(_fontScale); - for (UiPinPtr pin : node->inputPins) - { - if (node->getConnectedNode(pin->_name) != nullptr) - { + for (UiPinPtr pin: node->inputPins) { + if (node->getConnectedNode(pin->_name) != nullptr) { pin->setConnected(true); } - if (node->_showAllInputs || (pin->getConnected() || node->getNodeGraph()->getInput(pin->_name))) - { + if (node->_showAllInputs || (pin->getConnected() || node->getNodeGraph()->getInput(pin->_name))) { drawInputPin(pin); if (pin->_name.size() > longestInputLabel.size()) @@ -2378,98 +1965,69 @@ std::vector Graph::createNodes(bool nodegraph) } // add mx::InputPtr to node based off of input pin -void Graph::addNodeInput(UiNodePtr node, mx::InputPtr& input) -{ - if (node->getNode()) - { - if (!node->getNode()->getInput(input->getName())) - { +void Graph::addNodeInput(UiNodePtr node, mx::InputPtr &input) { + if (node->getNode()) { + if (!node->getNode()->getInput(input->getName())) { input = node->getNode()->addInput(input->getName(), input->getType()); input->setConnectedNode(nullptr); } } } -void Graph::setDefaults(mx::InputPtr input) -{ - if (input->getType() == "float") - { + +void Graph::setDefaults(mx::InputPtr input) { + if (input->getType() == "float") { input->setValue(0.f, "float"); - } - else if (input->getType() == "integer") - { + } else if (input->getType() == "integer") { input->setValue(0, "integer"); - } - else if (input->getType() == "color3") - { + } else if (input->getType() == "color3") { input->setValue(mx::Color3(0.f, 0.f, 0.f), "color3"); - } - else if (input->getType() == "color4") - { + } else if (input->getType() == "color4") { input->setValue(mx::Color4(0.f, 0.f, 0.f, 1.f), "color4"); - } - else if (input->getType() == "vector2") - { + } else if (input->getType() == "vector2") { input->setValue(mx::Vector2(0.f, 0.f), "vector2"); - } - else if (input->getType() == "vector3") - { + } else if (input->getType() == "vector3") { input->setValue(mx::Vector3(0.f, 0.f, 0.f), "vector3"); - } - else if (input->getType() == "vector4") - { + } else if (input->getType() == "vector4") { input->setValue(mx::Vector4(0.f, 0.f, 0.f, 0.f), "vector4"); - } - else if (input->getType() == "string") - { + } else if (input->getType() == "string") { input->setValue("", "string"); - } - else if (input->getType() == "filename") - { + } else if (input->getType() == "filename") { input->setValue("", "filename"); - } - else if (input->getType() == "boolean") - { + } else if (input->getType() == "boolean") { input->setValue(false, "boolean"); } } // add link to nodegraph and set up connections between UiNodes and MaterialX Nodes to update shader -void Graph::AddLink(ed::PinId inputPinId, ed::PinId outputPinId) -{ +void Graph::AddLink(ed::PinId inputPinId, ed::PinId outputPinId) { int end_attr = int(outputPinId.Get()); int start_attr = int(inputPinId.Get()); UiPinPtr inputPin = getPin(outputPinId); UiPinPtr outputPin = getPin(inputPinId); - if (inputPinId && outputPinId && (outputPin->_type == inputPin->_type)) - { - if (inputPin->_connected == false) - { + if (inputPinId && outputPinId && (outputPin->_type == inputPin->_type)) { + if (inputPin->_connected == false) { int upNode = getNodeId(inputPinId); int downNode = getNodeId(outputPinId); // make sure there is an implementation for node - const mx::ShaderGenerator& shadergen = _renderer->getGenContext().getShaderGenerator(); + const mx::ShaderGenerator &shadergen = _renderer->getGenContext().getShaderGenerator(); // Find the implementation for this nodedef if not an input or output uinode - if (_graphNodes[downNode]->getInput() && _isNodeGraph) - { + if (_graphNodes[downNode]->getInput() && _isNodeGraph) { ed::RejectNewItem(); showLabel("Cannot connect to inputs inside of graph", ImColor(50, 50, 50, 255)); return; - } - else if (_graphNodes[upNode]->getNode()) - { - mx::ShaderNodeImplPtr impl = shadergen.getImplementation(*_graphNodes[upNode]->getNode()->getNodeDef(), _renderer->getGenContext()); - if (!impl) - { + } else if (_graphNodes[upNode]->getNode()) { + mx::ShaderNodeImplPtr impl = shadergen.getImplementation(*_graphNodes[upNode]->getNode()->getNodeDef(), + _renderer->getGenContext()); + if (!impl) { ed::RejectNewItem(); showLabel("Invalid Connection: Node does not have an implementation", ImColor(50, 50, 50, 255)); return; } } - if (ed::AcceptNewItem()) - { + if (ed::AcceptNewItem()) { // Since we accepted new link, lets add one to our list of links. Link link; link._startAttr = start_attr; @@ -2478,67 +2036,46 @@ void Graph::AddLink(ed::PinId inputPinId, ed::PinId outputPinId) _frameCount = ImGui::GetFrameCount(); _renderer->setMaterialCompilation(true); - if (_graphNodes[downNode]->getNode() || _graphNodes[downNode]->getNodeGraph()) - { + if (_graphNodes[downNode]->getNode() || _graphNodes[downNode]->getNodeGraph()) { mx::InputPtr connectingInput = nullptr; - for (UiPinPtr pin : _graphNodes[downNode]->inputPins) - { - if (pin->_pinId == outputPinId) - { + for (UiPinPtr pin: _graphNodes[downNode]->inputPins) { + if (pin->_pinId == outputPinId) { addNodeInput(_graphNodes[downNode], pin->_input); // update value to be empty - if (_graphNodes[downNode]->getNode() && _graphNodes[downNode]->getNode()->getType() == mx::SURFACE_SHADER_TYPE_STRING) - { - if (_graphNodes[upNode]->getOutput() != nullptr) - { + if (_graphNodes[downNode]->getNode() && + _graphNodes[downNode]->getNode()->getType() == mx::SURFACE_SHADER_TYPE_STRING) { + if (_graphNodes[upNode]->getOutput() != nullptr) { pin->_input->setConnectedOutput(_graphNodes[upNode]->getOutput()); - } - else if (_graphNodes[upNode]->getInput() != nullptr) - { + } else if (_graphNodes[upNode]->getInput() != nullptr) { pin->_input->setInterfaceName(_graphNodes[upNode]->getName()); - } - else - { + } else { // node graph - if (_graphNodes[upNode]->getNodeGraph() != nullptr) - { - for (UiPinPtr outPin : _graphNodes[upNode]->outputPins) - { + if (_graphNodes[upNode]->getNodeGraph() != nullptr) { + for (UiPinPtr outPin: _graphNodes[upNode]->outputPins) { // set pin connection to correct output - if (outPin->_pinId == inputPinId) - { - mx::OutputPtr outputs = _graphNodes[upNode]->getNodeGraph()->getOutput(outPin->_name); + if (outPin->_pinId == inputPinId) { + mx::OutputPtr outputs = _graphNodes[upNode]->getNodeGraph()->getOutput( + outPin->_name); pin->_input->setConnectedOutput(outputs); } } - } - else - { + } else { pin->_input->setConnectedNode(_graphNodes[upNode]->getNode()); } } - } - else - { - if (_graphNodes[upNode]->getInput()) - { + } else { + if (_graphNodes[upNode]->getInput()) { pin->_input->setInterfaceName(_graphNodes[upNode]->getName()); - } - else - { - if (_graphNodes[upNode]->getNode()) - { + } else { + if (_graphNodes[upNode]->getNode()) { pin->_input->setConnectedNode(_graphNodes[upNode]->getNode()); - } - else if (_graphNodes[upNode]->getNodeGraph()) - { - for (UiPinPtr outPin : _graphNodes[upNode]->outputPins) - { + } else if (_graphNodes[upNode]->getNodeGraph()) { + for (UiPinPtr outPin: _graphNodes[upNode]->outputPins) { // set pin connection to correct output - if (outPin->_pinId == inputPinId) - { - mx::OutputPtr outputs = _graphNodes[upNode]->getNodeGraph()->getOutput(outPin->_name); + if (outPin->_pinId == inputPinId) { + mx::OutputPtr outputs = _graphNodes[upNode]->getNodeGraph()->getOutput( + outPin->_name); pin->_input->setConnectedOutput(outputs); } } @@ -2554,21 +2091,16 @@ void Graph::AddLink(ed::PinId inputPinId, ed::PinId outputPinId) } // create new edge and set edge information createEdge(_graphNodes[upNode], _graphNodes[downNode], connectingInput); - } - else if (_graphNodes[downNode]->getOutput() != nullptr) - { + } else if (_graphNodes[downNode]->getOutput() != nullptr) { mx::InputPtr connectingInput = nullptr; _graphNodes[downNode]->getOutput()->setConnectedNode(_graphNodes[upNode]->getNode()); // create new edge and set edge information createEdge(_graphNodes[upNode], _graphNodes[downNode], connectingInput); - } - else - { + } else { // create new edge and set edge info UiEdge newEdge = UiEdge(_graphNodes[upNode], _graphNodes[downNode], nullptr); - if (!edgeExists(newEdge)) - { + if (!edgeExists(newEdge)) { _graphNodes[downNode]->edges.push_back(newEdge); _currEdge.push_back(newEdge); @@ -2578,31 +2110,22 @@ void Graph::AddLink(ed::PinId inputPinId, ed::PinId outputPinId) } } } - } - else - { + } else { ed::RejectNewItem(); } - } - else - { + } else { ed::RejectNewItem(); showLabel("Invalid Connection due to Mismatch Types", ImColor(50, 50, 50, 255)); } } // remove node edge based of off connecting input -void Graph::removeEdge(int downNode, int upNode, UiPinPtr pin) -{ +void Graph::removeEdge(int downNode, int upNode, UiPinPtr pin) { int num = _graphNodes[downNode]->getEdgeIndex(_graphNodes[upNode]->getId(), pin); - if (num != -1) - { - if (_graphNodes[downNode]->edges.size() == 1) - { + if (num != -1) { + if (_graphNodes[downNode]->edges.size() == 1) { _graphNodes[downNode]->edges.erase(_graphNodes[downNode]->edges.begin() + 0); - } - else if (_graphNodes[downNode]->edges.size() > 1) - { + } else if (_graphNodes[downNode]->edges.size() > 1) { _graphNodes[downNode]->edges.erase(_graphNodes[downNode]->edges.begin() + num); } } @@ -2613,32 +2136,26 @@ void Graph::removeEdge(int downNode, int upNode, UiPinPtr pin) _graphNodes[upNode]->removeOutputConnection(_graphNodes[downNode]->getName()); } -void Graph::deleteLinkInfo(int startAttr, int endAttr) -{ +void Graph::deleteLinkInfo(int startAttr, int endAttr) { int upNode = getNodeId(startAttr); int downNode = getNodeId(endAttr); // change input so that is default val // change informtion of actual mx::Node - if (_graphNodes[downNode]->getNode()) - { - mx::NodeDefPtr nodeDef = _graphNodes[downNode]->getNode()->getNodeDef(_graphNodes[downNode]->getNode()->getName()); + if (_graphNodes[downNode]->getNode()) { + mx::NodeDefPtr nodeDef = _graphNodes[downNode]->getNode()->getNodeDef( + _graphNodes[downNode]->getNode()->getName()); - for (UiPinPtr pin : _graphNodes[downNode]->inputPins) - { - if ((int) pin->_pinId.Get() == endAttr) - { + for (UiPinPtr pin: _graphNodes[downNode]->inputPins) { + if ((int) pin->_pinId.Get() == endAttr) { removeEdge(downNode, upNode, pin); mx::ValuePtr val = nodeDef->getActiveInput(pin->_input->getName())->getValue(); - if (_graphNodes[downNode]->getNode()->getType() == mx::SURFACE_SHADER_TYPE_STRING && _graphNodes[upNode]->getNodeGraph()) - { + if (_graphNodes[downNode]->getNode()->getType() == mx::SURFACE_SHADER_TYPE_STRING && + _graphNodes[upNode]->getNodeGraph()) { pin->_input->setConnectedOutput(nullptr); - } - else - { + } else { pin->_input->setConnectedNode(nullptr); } - if (_graphNodes[upNode]->getInput()) - { + if (_graphNodes[upNode]->getInput()) { // remove interface value in order to set the default of the input pin->_input->removeAttribute(mx::ValueElement::INTERFACE_NAME_ATTRIBUTE); setDefaults(pin->_input); @@ -2647,25 +2164,20 @@ void Graph::deleteLinkInfo(int startAttr, int endAttr) pin->setConnected(false); // if a value exists update the input with it - if (val) - { + if (val) { pin->_input->setValueString(val->getValueString()); } } } - } - else if (_graphNodes[downNode]->getNodeGraph()) - { + } else if (_graphNodes[downNode]->getNodeGraph()) { // set default values for nodegraph node pins ie nodegraph inputs mx::NodeDefPtr nodeDef = _graphNodes[downNode]->getNodeGraph()->getNodeDef(); - for (UiPinPtr pin : _graphNodes[downNode]->inputPins) - { - if ((int) pin->_pinId.Get() == endAttr) - { + for (UiPinPtr pin: _graphNodes[downNode]->inputPins) { + if ((int) pin->_pinId.Get() == endAttr) { removeEdge(downNode, upNode, pin); - if (_graphNodes[upNode]->getInput()) - { - _graphNodes[downNode]->getNodeGraph()->getInput(pin->_name)->removeAttribute(mx::ValueElement::INTERFACE_NAME_ATTRIBUTE); + if (_graphNodes[upNode]->getInput()) { + _graphNodes[downNode]->getNodeGraph()->getInput(pin->_name)->removeAttribute( + mx::ValueElement::INTERFACE_NAME_ATTRIBUTE); setDefaults(_graphNodes[upNode]->getInput()); } pin->_input->setConnectedNode(nullptr); @@ -2673,13 +2185,9 @@ void Graph::deleteLinkInfo(int startAttr, int endAttr) setDefaults(pin->_input); } } - } - else if (_graphNodes[downNode]->getOutput()) - { - for (UiPinPtr pin : _graphNodes[downNode]->inputPins) - { - if ((int) pin->_pinId.Get() == endAttr) - { + } else if (_graphNodes[downNode]->getOutput()) { + for (UiPinPtr pin: _graphNodes[downNode]->inputPins) { + if ((int) pin->_pinId.Get() == endAttr) { removeEdge(downNode, upNode, pin); _graphNodes[downNode]->getOutput()->removeAttribute("nodename"); pin->setConnected(false); @@ -2687,12 +2195,11 @@ void Graph::deleteLinkInfo(int startAttr, int endAttr) } } } + // delete link from currLink vector and remove any connections in UiNode or MaterialX Nodes to update shader -void Graph::deleteLink(ed::LinkId deletedLinkId) -{ +void Graph::deleteLink(ed::LinkId deletedLinkId) { // If you agree that link can be deleted, accept deletion. - if (ed::AcceptDeletedItem()) - { + if (ed::AcceptDeletedItem()) { _renderer->setMaterialCompilation(true); _frameCount = ImGui::GetFrameCount(); int link_id = int(deletedLinkId.Get()); @@ -2706,55 +2213,40 @@ void Graph::deleteLink(ed::LinkId deletedLinkId) } } -void Graph::deleteNode(UiNodePtr node) -{ +void Graph::deleteNode(UiNodePtr node) { // delete link - for (UiPinPtr inputPin : node->inputPins) - { + for (UiPinPtr inputPin: node->inputPins) { UiNodePtr upNode = node->getConnectedNode(inputPin->_name); - if (upNode) - { + if (upNode) { upNode->removeOutputConnection(node->getName()); int num = node->getEdgeIndex(upNode->getId(), inputPin); // erase edge between node and up node - if (num != -1) - { - if (node->edges.size() == 1) - { + if (num != -1) { + if (node->edges.size() == 1) { node->edges.erase(node->edges.begin() + 0); - } - else if (node->edges.size() > 1) - { + } else if (node->edges.size() > 1) { node->edges.erase(node->edges.begin() + num); } } } } - if (node->outputPins.size() > 0) - { + if (node->outputPins.size() > 0) { // update downNode info - for (UiPinPtr pin : node->outputPins.front()->getConnections()) - { + for (UiPinPtr pin: node->outputPins.front()->getConnections()) { mx::ValuePtr val; - if (pin->_pinNode->getNode()) - { + if (pin->_pinNode->getNode()) { mx::NodeDefPtr nodeDef = pin->_pinNode->getNode()->getNodeDef(pin->_pinNode->getNode()->getName()); val = nodeDef->getActiveInput(pin->_input->getName())->getValue(); - if (pin->_pinNode->getNode()->getType() == "surfaceshader") - { + if (pin->_pinNode->getNode()->getType() == "surfaceshader") { pin->_input->setConnectedOutput(nullptr); - } - else - { + } else { pin->_input->setConnectedNode(nullptr); } - } - else if (pin->_pinNode->getNodeGraph()) - { - if (node->getInput()) - { - pin->_pinNode->getNodeGraph()->getInput(pin->_name)->removeAttribute(mx::ValueElement::INTERFACE_NAME_ATTRIBUTE); + } else if (pin->_pinNode->getNodeGraph()) { + if (node->getInput()) { + pin->_pinNode->getNodeGraph()->getInput(pin->_name)->removeAttribute( + mx::ValueElement::INTERFACE_NAME_ATTRIBUTE); setDefaults(node->getInput()); } pin->_input->setConnectedNode(nullptr); @@ -2763,20 +2255,15 @@ void Graph::deleteNode(UiNodePtr node) } pin->setConnected(false); - if (val) - { + if (val) { pin->_input->setValueString(val->getValueString()); } int num = pin->_pinNode->getEdgeIndex(node->getId(), pin); - if (num != -1) - { - if (pin->_pinNode->edges.size() == 1) - { + if (num != -1) { + if (pin->_pinNode->edges.size() == 1) { pin->_pinNode->edges.erase(pin->_pinNode->edges.begin() + 0); - } - else if (pin->_pinNode->edges.size() > 1) - { + } else if (pin->_pinNode->edges.size() > 1) { pin->_pinNode->edges.erase(pin->_pinNode->edges.begin() + num); } } @@ -2795,42 +2282,35 @@ void Graph::deleteNode(UiNodePtr node) } // create pins for outputs/inputs added while inside the node graph -void Graph::addNodeGraphPins() -{ - for (UiNodePtr node : _graphNodes) - { - if (node->getNodeGraph()) - { - if (node->inputPins.size() != node->getNodeGraph()->getInputs().size()) - { - for (mx::InputPtr input : node->getNodeGraph()->getInputs()) - { +void Graph::addNodeGraphPins() { + for (UiNodePtr node: _graphNodes) { + if (node->getNodeGraph()) { + if (node->inputPins.size() != node->getNodeGraph()->getInputs().size()) { + for (mx::InputPtr input: node->getNodeGraph()->getInputs()) { std::string name = input->getName(); - auto result = std::find_if(node->inputPins.begin(), node->inputPins.end(), [name](UiPinPtr x) - { + auto result = std::find_if(node->inputPins.begin(), node->inputPins.end(), [name](UiPinPtr x) { return x->_name == name; }); - if (result == node->inputPins.end()) - { - UiPinPtr inPin = std::make_shared(++_graphTotalSize, &*input->getName().begin(), input->getType(), node, ax::NodeEditor::PinKind::Input, input, nullptr); + if (result == node->inputPins.end()) { + UiPinPtr inPin = std::make_shared(++_graphTotalSize, &*input->getName().begin(), + input->getType(), node, ax::NodeEditor::PinKind::Input, + input, nullptr); node->inputPins.push_back(inPin); _currPins.push_back(inPin); ++_graphTotalSize; } } } - if (node->outputPins.size() != node->getNodeGraph()->getOutputs().size()) - { - for (mx::OutputPtr output : node->getNodeGraph()->getOutputs()) - { + if (node->outputPins.size() != node->getNodeGraph()->getOutputs().size()) { + for (mx::OutputPtr output: node->getNodeGraph()->getOutputs()) { std::string name = output->getName(); - auto result = std::find_if(node->outputPins.begin(), node->outputPins.end(), [name](UiPinPtr x) - { + auto result = std::find_if(node->outputPins.begin(), node->outputPins.end(), [name](UiPinPtr x) { return x->_name == name; }); - if (result == node->outputPins.end()) - { - UiPinPtr outPin = std::make_shared(++_graphTotalSize, &*output->getName().begin(), output->getType(), node, ax::NodeEditor::PinKind::Output, nullptr, nullptr); + if (result == node->outputPins.end()) { + UiPinPtr outPin = std::make_shared(++_graphTotalSize, &*output->getName().begin(), + output->getType(), node, + ax::NodeEditor::PinKind::Output, nullptr, nullptr); ++_graphTotalSize; node->outputPins.push_back(outPin); _currPins.push_back(outPin); @@ -2841,10 +2321,8 @@ void Graph::addNodeGraphPins() } } -void Graph::upNodeGraph() -{ - if (!_graphStack.empty()) - { +void Graph::upNodeGraph() { + if (!_graphStack.empty()) { savePosition(); _graphNodes = _graphStack.top(); _currPins = _pinStack.top(); @@ -2856,8 +2334,7 @@ void Graph::upNodeGraph() _currGraphName.pop_back(); _initial = true; ed::NavigateToContent(); - if (_currUiNode) - { + if (_currUiNode) { ed::DeselectNode(_currUiNode->getId()); _currUiNode = nullptr; } @@ -2868,8 +2345,7 @@ void Graph::upNodeGraph() } } -void Graph::clearGraph() -{ +void Graph::clearGraph() { _graphNodes.clear(); _currLinks.clear(); _currEdge.clear(); @@ -2879,8 +2355,7 @@ void Graph::clearGraph() _graphDoc->importLibrary(_stdLib); _currGraphElem = _graphDoc; - if (_currUiNode != nullptr) - { + if (_currUiNode != nullptr) { ed::DeselectNode(_currUiNode->getId()); _currUiNode = nullptr; } @@ -2893,11 +2368,9 @@ void Graph::clearGraph() _renderer->updateMaterials(nullptr); } -void Graph::loadGraphFromFile() -{ +void Graph::loadGraphFromFile() { // deselect node before loading new file - if (_currUiNode != nullptr) - { + if (_currUiNode != nullptr) { ed::DeselectNode(_currUiNode->getId()); _currUiNode = nullptr; } @@ -2907,70 +2380,54 @@ void Graph::loadGraphFromFile() _fileDialog.open(); } -void Graph::saveGraphToFile() -{ +void Graph::saveGraphToFile() { _fileDialogSave.setTypeFilters(_mtlxFilter); _fileDialogSave.setTitle("Save File As"); _fileDialogSave.open(); } -void Graph::loadGeometry() -{ +void Graph::loadGeometry() { _fileDialogGeom.setTitle("Load Geometry"); _fileDialogGeom.setTypeFilters(_geomFilter); _fileDialogGeom.open(); } -void Graph::graphButtons() -{ +void Graph::graphButtons() { ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(.15f, .15f, .15f, 1.0f)); ImGui::SetWindowFontScale(_fontScale); - if (ImGui::BeginMenuBar()) - { - if (ImGui::BeginMenu("File")) - { + if (ImGui::BeginMenuBar()) { + if (ImGui::BeginMenu("File")) { // buttons for loading and saving a .mtlx // new Material button - if (ImGui::MenuItem("New", "Ctrl-N")) - { + if (ImGui::MenuItem("New", "Ctrl-N")) { clearGraph(); - } - else if (ImGui::MenuItem("Open", "Ctrl-O")) - { + } else if (ImGui::MenuItem("Open", "Ctrl-O")) { loadGraphFromFile(); - } - else if (ImGui::MenuItem("Save", "Ctrl-S")) - { + } else if (ImGui::MenuItem("Save", "Ctrl-S")) { saveGraphToFile(); } ImGui::EndMenu(); } - if (ImGui::BeginMenu("Graph")) - { - if (ImGui::MenuItem("Auto Layout")) - { + if (ImGui::BeginMenu("Graph")) { + if (ImGui::MenuItem("Auto Layout")) { _autoLayout = true; } ImGui::EndMenu(); } - if (ImGui::BeginMenu("Viewer")) - { - if (ImGui::MenuItem("Load Geometry")) - { + if (ImGui::BeginMenu("Viewer")) { + if (ImGui::MenuItem("Load Geometry")) { loadGeometry(); } ImGui::EndMenu(); } - if (ImGui::Button("Help")) - { + if (ImGui::Button("Help")) { ImGui::OpenPopup("Help"); } - if (ImGui::BeginPopup("Help")) - { + if (ImGui::BeginPopup("Help")) { showHelp(); ImGui::EndPopup(); } @@ -2979,19 +2436,13 @@ void Graph::graphButtons() } // Menu keys - ImGuiIO& guiIO = ImGui::GetIO(); - if (guiIO.KeyCtrl && !_fileDialogSave.isOpened() && !_fileDialog.isOpened() && !_fileDialogGeom.isOpened()) - { - if (ImGui::IsKeyReleased(ImGuiKey_O)) - { + ImGuiIO &guiIO = ImGui::GetIO(); + if (guiIO.KeyCtrl && !_fileDialogSave.isOpened() && !_fileDialog.isOpened() && !_fileDialogGeom.isOpened()) { + if (ImGui::IsKeyReleased(ImGuiKey_O)) { loadGraphFromFile(); - } - else if (ImGui::IsKeyReleased(ImGuiKey_N)) - { + } else if (ImGui::IsKeyReleased(ImGuiKey_N)) { clearGraph(); - } - else if (ImGui::IsKeyReleased(ImGuiKey_S)) - { + } else if (ImGui::IsKeyReleased(ImGuiKey_S)) { saveGraphToFile(); } } @@ -3002,19 +2453,15 @@ void Graph::graphButtons() Splitter(true, 4.0f, &leftPaneWidth, &rightPaneWidth, 20.0f, 20.0f); // create back button and graph hiearchy name display ImGui::Indent(leftPaneWidth + 15.f); - if (ImGui::Button("<")) - { + if (ImGui::Button("<")) { upNodeGraph(); } ImGui::SameLine(); - if (!_currGraphName.empty()) - { - for (std::string name : _currGraphName) - { + if (!_currGraphName.empty()) { + for (std::string name: _currGraphName) { ImGui::Text("%s", name.c_str()); ImGui::SameLine(); - if (name != _currGraphName.back()) - { + if (name != _currGraphName.back()) { ImGui::Text(">"); ImGui::SameLine(); } @@ -3035,8 +2482,7 @@ void Graph::graphButtons() _renderer->setViewWidth((int) screenSize[0]); _renderer->setViewHeight((int) screenSize[1]); - if (_renderer != nullptr) - { + if (_renderer != nullptr) { glEnable(GL_FRAMEBUFFER_SRGB); _renderer->getViewCamera()->setViewportSize(mx::Vector2(screenSize[0], screenSize[1])); @@ -3054,11 +2500,10 @@ void Graph::graphButtons() handleRenderViewInputs(windowPos, screenSize[0], screenSize[1]); } -void Graph::propertyEditor() -{ + +void Graph::propertyEditor() { ImGui::Text("Node Property Editor"); - if (_currUiNode) - { + if (_currUiNode) { // set and edit name ImGui::Text("Name: "); ImGui::SameLine(); @@ -3066,153 +2511,124 @@ void Graph::propertyEditor() std::string temp = original; ImGui::InputText("##edit", &temp); std::string docString = "NodeDef Doc String: \n"; - if (_currUiNode->getNode()) - { - if (temp != original) - { + if (_currUiNode->getNode()) { + if (temp != original) { std::string name = _currUiNode->getNode()->getParent()->createValidChildName(temp); std::vector downstreamNodes = _currUiNode->getOutputConnections(); - for (UiNodePtr nodes : downstreamNodes) - { - if (nodes->getInput() == nullptr) - { - for (mx::InputPtr input : nodes->getNode()->getActiveInputs()) - { - if (input->getConnectedNode() == _currUiNode->getNode()) - { - _currUiNode->getNode()->setName(name); + for (UiNodePtr nodes: downstreamNodes) { + if (nodes->getInput() == nullptr) { + for (mx::InputPtr input: nodes->getNode()->getActiveInputs()) { + if (input->getConnectedNode() == _currUiNode->getNode()) { + setName(_currUiNode->getNode(), name); nodes->getNode()->setConnectedNode(input->getName(), _currUiNode->getNode()); } } } } - _currUiNode->setName(name); - _currUiNode->getNode()->setName(name); + setName(_currUiNode, name); + setName(_currUiNode->getNode(), name); } - } - else if (_currUiNode->getInput()) - { - if (temp != original) - { + } else if (_currUiNode->getInput()) { + if (temp != original) { std::string name = _currUiNode->getInput()->getParent()->createValidChildName(temp); std::vector downstreamNodes = _currUiNode->getOutputConnections(); - for (UiNodePtr nodes : downstreamNodes) - { - if (nodes->getInput() == nullptr) - { - if (nodes->getNode()) - { - for (mx::InputPtr input : nodes->getNode()->getActiveInputs()) - { - if (input->getInterfaceInput() == _currUiNode->getInput()) - { - _currUiNode->getInput()->setName(name); + for (UiNodePtr nodes: downstreamNodes) { + if (nodes->getInput() == nullptr) { + if (nodes->getNode()) { + for (mx::InputPtr input: nodes->getNode()->getActiveInputs()) { + if (input->getInterfaceInput() == _currUiNode->getInput()) { + setName(_currUiNode->getInput(), name); mx::ValuePtr val = _currUiNode->getInput()->getValue(); input->setInterfaceName(name); mx::InputPtr pt = input->getInterfaceInput(); } } - } - else - { + } else { nodes->getOutput()->setConnectedNode(_currUiNode->getNode()); } } } - _currUiNode->getInput()->setName(name); - _currUiNode->setName(name); + setName(_currUiNode->getInput(), name); + setName(_currUiNode, name); } - } - else if (_currUiNode->getOutput()) - { - if (temp != original) - { + } else if (_currUiNode->getOutput()) { + if (temp != original) { std::string name = _currUiNode->getOutput()->getParent()->createValidChildName(temp); - _currUiNode->getOutput()->setName(name); - _currUiNode->setName(name); + setName(_currUiNode->getOutput(), name); + setName(_currUiNode, name); } - } - else if (_currUiNode->getCategory() == "group") - { - _currUiNode->setName(temp); - } - else if (_currUiNode->getCategory() == "nodegraph") - { - if (temp != original) - { + } else if (_currUiNode->getCategory() == "group") { + setName(_currUiNode, temp); + } else if (_currUiNode->getCategory() == "nodegraph") { + if (temp != original) { std::string name = _currUiNode->getNodeGraph()->getParent()->createValidChildName(temp); - _currUiNode->getNodeGraph()->setName(name); - _currUiNode->setName(name); + setName(_currUiNode->getNodeGraph(), name); + setName(_currUiNode, name); } } const float TEXT_BASE_HEIGHT = ImGui::GetTextLineHeightWithSpacing() * 1.3f; const int SCROLL_LINE_COUNT = 20; - ImGuiTableFlags tableFlags = ImGuiTableFlags_ScrollY | ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings | - ImGuiTableFlags_BordersOuterH | ImGuiTableFlags_NoBordersInBody; + ImGuiTableFlags tableFlags = + ImGuiTableFlags_ScrollY | ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings | + ImGuiTableFlags_BordersOuterH | ImGuiTableFlags_NoBordersInBody; ImGui::Text("Category:"); ImGui::SameLine(); // change button color to match background ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(.096f, .096f, .096f, 1.0f)); ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(.1f, .1f, .1f, 1.0f)); - if (_currUiNode->getNode()) - { + if (_currUiNode->getNode()) { ImGui::NextColumn(); ImGui::Text("%s", _currUiNode->getNode()->getCategory().c_str()); docString += _currUiNode->getNode()->getCategory(); - if (_currUiNode->getNode()->getNodeDef()) - { + if (_currUiNode->getNode()->getNodeDef()) { docString += ":"; docString += _currUiNode->getNode()->getNodeDef()->getDocString() + "\n"; } - if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) - { + if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) { ImGui::SetTooltip("%s", _currUiNode->getNode()->getNodeDef()->getDocString().c_str()); } ImGui::Text("Inputs:"); int count = 0; - for (UiPinPtr input : _currUiNode->inputPins) - { - if (_currUiNode->_showAllInputs || (input->getConnected() || _currUiNode->getNode()->getInput(input->_name))) - { + for (UiPinPtr input: _currUiNode->inputPins) { + if (_currUiNode->_showAllInputs || + (input->getConnected() || _currUiNode->getNode()->getInput(input->_name))) { count++; } } - if (count) - { + if (count) { ImVec2 tableSize(0.0f, TEXT_BASE_HEIGHT * std::min(SCROLL_LINE_COUNT, count)); bool haveTable = ImGui::BeginTable("inputs_node_table", 2, tableFlags, tableSize); - if (haveTable) - { + if (haveTable) { ImGui::SetWindowFontScale(_fontScale); - for (UiPinPtr input : _currUiNode->inputPins) - { - if (_currUiNode->_showAllInputs || (input->getConnected() || _currUiNode->getNode()->getInput(input->_name))) - { + for (UiPinPtr input: _currUiNode->inputPins) { + if (_currUiNode->_showAllInputs || + (input->getConnected() || _currUiNode->getNode()->getInput(input->_name))) { ImGui::TableNextRow(); ImGui::TableNextColumn(); mx::UIProperties uiProperties; mx::getUIProperties(input->_input, mx::EMPTY_STRING, uiProperties); - std::string inputLabel = !uiProperties.uiName.empty() ? uiProperties.uiName : input->_input->getName(); + std::string inputLabel = !uiProperties.uiName.empty() ? uiProperties.uiName + : input->_input->getName(); mx::OutputPtr out = input->_input->getConnectedOutput(); // setting comment help box ImGui::PushID(int(input->_pinId.Get())); ImGui::Text("%s", inputLabel.c_str()); - mx::InputPtr tempInt = _currUiNode->getNode()->getNodeDef()->getActiveInput(input->_input->getName()); + mx::InputPtr tempInt = _currUiNode->getNode()->getNodeDef()->getActiveInput( + input->_input->getName()); docString += input->_name; docString += ": "; - if (tempInt) - { - std::string newStr = _currUiNode->getNode()->getNodeDef()->getActiveInput(input->_input->getName())->getDocString(); - if (newStr != mx::EMPTY_STRING) - { + if (tempInt) { + std::string newStr = _currUiNode->getNode()->getNodeDef()->getActiveInput( + input->_input->getName())->getDocString(); + if (newStr != mx::EMPTY_STRING) { docString += newStr; } } @@ -3220,12 +2636,9 @@ void Graph::propertyEditor() // setting constant sliders for input values ImGui::TableNextColumn(); - if (!input->getConnected()) - { + if (!input->getConnected()) { setConstant(_currUiNode, input->_input, uiProperties); - } - else - { + } else { std::string typeText = " [" + input->_input->getType() + "]"; ImGui::Text("%s", typeText.c_str()); } @@ -3239,31 +2652,26 @@ void Graph::propertyEditor() } } ImGui::Checkbox("Show all inputs", &_currUiNode->_showAllInputs); - } - - else if (_currUiNode->getInput() != nullptr) - { + } else if (_currUiNode->getInput() != nullptr) { ImGui::Text("%s", _currUiNode->getCategory().c_str()); std::vector inputs = _currUiNode->inputPins; ImGui::Text("Inputs:"); int count = static_cast(inputs.size()); - if (count) - { + if (count) { bool haveTable = ImGui::BeginTable("inputs_input_table", 2, tableFlags, ImVec2(0.0f, TEXT_BASE_HEIGHT * std::min(SCROLL_LINE_COUNT, count))); - if (haveTable) - { + if (haveTable) { ImGui::SetWindowFontScale(_fontScale); - for (size_t i = 0; i < inputs.size(); i++) - { + for (size_t i = 0; i < inputs.size(); i++) { ImGui::TableNextRow(); ImGui::TableNextColumn(); mx::InputPtr mxinput = inputs[i]->_input; mx::UIProperties uiProperties; mx::getUIProperties(mxinput, mx::EMPTY_STRING, uiProperties); - std::string inputLabel = !uiProperties.uiName.empty() ? uiProperties.uiName : mxinput->getName(); + std::string inputLabel = !uiProperties.uiName.empty() ? uiProperties.uiName + : mxinput->getName(); // setting comment help box ImGui::PushID(int(inputs[i]->_pinId.Get())); @@ -3272,12 +2680,9 @@ void Graph::propertyEditor() ImGui::TableNextColumn(); // setting constant sliders for input values - if (!inputs[i]->getConnected()) - { + if (!inputs[i]->getConnected()) { setConstant(_currUiNode, inputs[i]->_input, uiProperties); - } - else - { + } else { std::string typeText = " [" + inputs[i]->_input->getType() + "]"; ImGui::Text("%s", typeText.c_str()); } @@ -3287,56 +2692,48 @@ void Graph::propertyEditor() ImGui::SetWindowFontScale(1.0f); } } - } - else if (_currUiNode->getOutput() != nullptr) - { + } else if (_currUiNode->getOutput() != nullptr) { ImGui::Text("%s", _currUiNode->getOutput()->getCategory().c_str()); - } - else if (_currUiNode->getNodeGraph() != nullptr) - { + } else if (_currUiNode->getNodeGraph() != nullptr) { std::vector inputs = _currUiNode->inputPins; ImGui::Text("%s", _currUiNode->getCategory().c_str()); ImGui::Text("Inputs:"); int count = 0; - for (UiPinPtr input : inputs) - { - if (_currUiNode->_showAllInputs || (input->getConnected() || _currUiNode->getNodeGraph()->getInput(input->_name))) - { + for (UiPinPtr input: inputs) { + if (_currUiNode->_showAllInputs || + (input->getConnected() || _currUiNode->getNodeGraph()->getInput(input->_name))) { count++; } } - if (count) - { + if (count) { bool haveTable = ImGui::BeginTable("inputs_nodegraph_table", 2, tableFlags, ImVec2(0.0f, TEXT_BASE_HEIGHT * std::min(SCROLL_LINE_COUNT, count))); - if (haveTable) - { + if (haveTable) { ImGui::SetWindowFontScale(_fontScale); - for (UiPinPtr input : inputs) - { - if (_currUiNode->_showAllInputs || (input->getConnected() || _currUiNode->getNodeGraph()->getInput(input->_name))) - { + for (UiPinPtr input: inputs) { + if (_currUiNode->_showAllInputs || + (input->getConnected() || _currUiNode->getNodeGraph()->getInput(input->_name))) { ImGui::TableNextRow(); ImGui::TableNextColumn(); mx::InputPtr mxinput = input->_input; mx::UIProperties uiProperties; mx::getUIProperties(mxinput, mx::EMPTY_STRING, uiProperties); - std::string inputLabel = !uiProperties.uiName.empty() ? uiProperties.uiName : mxinput->getName(); + std::string inputLabel = !uiProperties.uiName.empty() ? uiProperties.uiName + : mxinput->getName(); // setting comment help box ImGui::PushID(int(input->_pinId.Get())); ImGui::Text("%s", inputLabel.c_str()); - docString += _currUiNode->getNodeGraph()->getActiveInput(input->_input->getName())->getDocString(); + docString += _currUiNode->getNodeGraph()->getActiveInput( + input->_input->getName())->getDocString(); ImGui::TableNextColumn(); - if (!input->_input->getConnectedNode() && _currUiNode->getNodeGraph()->getActiveInput(input->_input->getName())) - { + if (!input->_input->getConnectedNode() && + _currUiNode->getNodeGraph()->getActiveInput(input->_input->getName())) { setConstant(_currUiNode, input->_input, uiProperties); - } - else - { + } else { std::string typeText = " [" + input->_input->getType() + "]"; ImGui::Text("%s", typeText.c_str()); } @@ -3353,13 +2750,11 @@ void Graph::propertyEditor() ImGui::PopStyleColor(); ImGui::PopStyleColor(); - if (ImGui::Button("Node Info")) - { + if (ImGui::Button("Node Info")) { ImGui::OpenPopup("docstring"); } - if (ImGui::BeginPopup("docstring")) - { + if (ImGui::BeginPopup("docstring")) { ImGui::SetWindowFontScale(_fontScale); ImGui::Text("%s", docString.c_str()); ImGui::SetWindowFontScale(1.0f); @@ -3369,21 +2764,17 @@ void Graph::propertyEditor() } // Helper to display basic user controls. -void Graph::showHelp() const -{ +void Graph::showHelp() const { ImGui::Text("MATERIALX GRAPH EDITOR HELP"); - if (ImGui::CollapsingHeader("Graph")) - { - if (ImGui::TreeNode("Navigation")) - { + if (ImGui::CollapsingHeader("Graph")) { + if (ImGui::TreeNode("Navigation")) { ImGui::BulletText("F : Frame selected nodes in graph."); ImGui::BulletText("RIGHT MOUSE button to pan."); ImGui::BulletText("SCROLL WHEEL to zoom."); ImGui::BulletText("\"<\" BUTTON to view parent of current graph"); ImGui::TreePop(); } - if (ImGui::TreeNode("Editing")) - { + if (ImGui::TreeNode("Editing")) { ImGui::BulletText("TAB : Show popup menu to add new nodes."); ImGui::BulletText("CTRL-C : Copy selected nodes to clipboard."); ImGui::BulletText("CTRL-V : Paste clipboard to graph."); @@ -3393,81 +2784,70 @@ void Graph::showHelp() const ImGui::TreePop(); } } - if (ImGui::CollapsingHeader("Viewer")) - { + if (ImGui::CollapsingHeader("Viewer")) { ImGui::BulletText("LEFT MOUSE button to tumble."); ImGui::BulletText("RIGHT MOUSE button to pan."); ImGui::BulletText("SCROLL WHEEL to zoom."); ImGui::BulletText("Keypad +/- to zoom in fixed increments"); } - if (ImGui::CollapsingHeader("Property Editor")) - { + if (ImGui::CollapsingHeader("Property Editor")) { ImGui::BulletText("UP/DOWN ARROW to move between inputs."); ImGui::BulletText("LEFT-MOUSE DRAG to modify values while entry field is in focus."); ImGui::BulletText("DBL_CLICK or CTRL+CLICK LEFT-MOUSE on entry field to input values."); ImGui::Separator(); - ImGui::BulletText("\"Show all inputs\" Will toggle between showing all inputs and\n only those that have been modified."); + ImGui::BulletText( + "\"Show all inputs\" Will toggle between showing all inputs and\n only those that have been modified."); ImGui::BulletText("\"Node Info\" Will toggle showing node information."); } } -void Graph::addNodePopup(bool cursor) -{ - bool open_AddPopup = ImGui::IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows) && ImGui::IsKeyReleased(ImGuiKey_Tab); - static char input[32]{ "" }; - if (open_AddPopup) - { +void Graph::addNodePopup(bool cursor) { + bool open_AddPopup = + ImGui::IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows) && ImGui::IsKeyReleased(ImGuiKey_Tab); + static char input[32]{""}; + if (open_AddPopup) { cursor = true; ImGui::OpenPopup("add node"); } - if (ImGui::BeginPopup("add node")) - { + if (ImGui::BeginPopup("add node")) { ImGui::Text("Add Node"); ImGui::Separator(); - if (cursor) - { + if (cursor) { ImGui::SetKeyboardFocusHere(); } ImGui::InputText("##input", input, sizeof(input)); std::string subs(input); // input string length // filter extra nodes - includes inputs, outputs, groups, and node graphs - for (std::unordered_map>>::iterator it = _extraNodes.begin(); it != _extraNodes.end(); ++it) - { + for (std::unordered_map>>::iterator it = _extraNodes.begin(); + it != _extraNodes.end(); ++it) { // filter out list of nodes - if (subs.size() > 0) - { + if (subs.size() > 0) { ImGui::SetNextWindowSizeConstraints(ImVec2(250.0f, 300.0f), ImVec2(-1.0f, 500.0f)); - for (size_t i = 0; i < it->second.size(); i++) - { + for (size_t i = 0; i < it->second.size(); i++) { std::string str(it->second[i][0]); std::string nodeName = it->second[i][0]; // 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))) - { + if (str.find(subs) != std::string::npos) { + if (ImGui::MenuItem(getNodeDefId(nodeName).c_str()) || + (ImGui::IsItemFocused() && ImGui::IsKeyPressedMap(ImGuiKey_Enter))) { addNode(it->second[i][2], getNodeDefId(nodeName), it->second[i][1]); _addNewNode = true; memset(input, '\0', sizeof(input)); } } } - } - else - { + } else { ImGui::SetNextWindowSizeConstraints(ImVec2(100, 10), ImVec2(-1, 300)); - if (ImGui::BeginMenu(it->first.c_str())) - { + if (ImGui::BeginMenu(it->first.c_str())) { ImGui::SetWindowFontScale(_fontScale); - for (size_t j = 0; j < it->second.size(); j++) - { + for (size_t j = 0; j < it->second.size(); j++) { std::string name = it->second[j][0]; - if (ImGui::MenuItem(getNodeDefId(name).c_str()) || (ImGui::IsItemFocused() && ImGui::IsKeyPressedMap(ImGuiKey_Enter))) - { + if (ImGui::MenuItem(getNodeDefId(name).c_str()) || + (ImGui::IsItemFocused() && ImGui::IsKeyPressedMap(ImGuiKey_Enter))) { addNode(it->second[j][2], getNodeDefId(name), it->second[j][1]); _addNewNode = true; } @@ -3477,40 +2857,33 @@ void Graph::addNodePopup(bool cursor) } } // filter nodedefs and add to menu if matches filter - for (std::unordered_map>::iterator it = _nodesToAdd.begin(); it != _nodesToAdd.end(); ++it) - { + for (std::unordered_map>::iterator it = _nodesToAdd.begin(); + it != _nodesToAdd.end(); ++it) { // filter out list of nodes - if (subs.size() > 0) - { + if (subs.size() > 0) { ImGui::SetNextWindowSizeConstraints(ImVec2(250.0f, 300.0f), ImVec2(-1.0f, 500.0f)); - for (size_t i = 0; i < it->second.size(); i++) - { + for (size_t i = 0; i < it->second.size(); i++) { std::string str(it->second[i]->getName()); std::string nodeName = it->second[i]->getName(); - if (str.find(subs) != std::string::npos) - { + if (str.find(subs) != std::string::npos) { std::string val = getNodeDefId(nodeName); - if (ImGui::MenuItem(val.c_str()) || (ImGui::IsItemFocused() && ImGui::IsKeyPressedMap(ImGuiKey_Enter))) - { + if (ImGui::MenuItem(val.c_str()) || + (ImGui::IsItemFocused() && ImGui::IsKeyPressedMap(ImGuiKey_Enter))) { addNode(it->second[i]->getNodeString(), val, it->second[i]->getType()); _addNewNode = true; memset(input, '\0', sizeof(input)); } } } - } - else - { + } else { ImGui::SetNextWindowSizeConstraints(ImVec2(100, 10), ImVec2(-1, 300)); - if (ImGui::BeginMenu(it->first.c_str())) - { + if (ImGui::BeginMenu(it->first.c_str())) { ImGui::SetWindowFontScale(_fontScale); - for (size_t i = 0; i < it->second.size(); i++) - { + for (size_t i = 0; i < it->second.size(); i++) { std::string name = it->second[i]->getName(); std::string val = getNodeDefId(name); - if (ImGui::MenuItem(val.c_str()) || (ImGui::IsItemFocused() && ImGui::IsKeyPressedMap(ImGuiKey_Enter))) - { + if (ImGui::MenuItem(val.c_str()) || + (ImGui::IsItemFocused() && ImGui::IsKeyPressedMap(ImGuiKey_Enter))) { addNode(it->second[i]->getNodeString(), val, it->second[i]->getType()); _addNewNode = true; } @@ -3524,37 +2897,33 @@ void Graph::addNodePopup(bool cursor) open_AddPopup = false; } } -void Graph::searchNodePopup(bool cursor) -{ - const bool open_search = ImGui::IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows) && ImGui::IsKeyDown(ImGuiKey_F) && ImGui::IsKeyDown(ImGuiKey_LeftCtrl); - if (open_search) - { + +void Graph::searchNodePopup(bool cursor) { + const bool open_search = + ImGui::IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows) && ImGui::IsKeyDown(ImGuiKey_F) && + ImGui::IsKeyDown(ImGuiKey_LeftCtrl); + if (open_search) { cursor = true; ImGui::OpenPopup("search"); } - if (ImGui::BeginPopup("search")) - { + if (ImGui::BeginPopup("search")) { ed::NavigateToSelection(); static ImGuiTextFilter filter; ImGui::Text("Search for Node:"); - static char input[16]{ "" }; + static char input[16]{""}; ImGui::SameLine(); - if (cursor) - { + if (cursor) { ImGui::SetKeyboardFocusHere(); } ImGui::InputText("##input", input, sizeof(input)); - if (std::string(input).size() > 0) - { + if (std::string(input).size() > 0) { - for (UiNodePtr node : _graphNodes) - { - if (node->getName().find(std::string(input)) != std::string::npos) - { + for (UiNodePtr node: _graphNodes) { + if (node->getName().find(std::string(input)) != std::string::npos) { - if (ImGui::MenuItem(node->getName().c_str()) || (ImGui::IsItemFocused() && ImGui::IsKeyPressedMap(ImGuiKey_Enter))) - { + if (ImGui::MenuItem(node->getName().c_str()) || + (ImGui::IsItemFocused() && ImGui::IsKeyPressedMap(ImGuiKey_Enter))) { _searchNodeId = node->getId(); memset(input, '\0', sizeof(input)); } @@ -3566,35 +2935,29 @@ void Graph::searchNodePopup(bool cursor) } } -void Graph::readOnlyPopup() -{ - if (_popup) - { +void Graph::readOnlyPopup() { + if (_popup) { ImGui::SetNextWindowSize(ImVec2(200, 100)); ImGui::OpenPopup("Read Only"); _popup = false; } - if (ImGui::BeginPopup("Read Only")) - { + if (ImGui::BeginPopup("Read Only")) { ImGui::Text("This graph is Read Only"); ImGui::EndPopup(); } } // compiling shaders message -void Graph::shaderPopup() -{ - if (_renderer->getMaterialCompilation()) - { - ImGui::SetNextWindowPos(ImVec2((float) _renderer->getViewWidth() - 135, (float) _renderer->getViewHeight() + 5)); +void Graph::shaderPopup() { + if (_renderer->getMaterialCompilation()) { + ImGui::SetNextWindowPos( + ImVec2((float) _renderer->getViewWidth() - 135, (float) _renderer->getViewHeight() + 5)); ImGui::SetNextWindowBgAlpha(80.f); ImGui::OpenPopup("Shaders"); } - if (ImGui::BeginPopup("Shaders")) - { + if (ImGui::BeginPopup("Shaders")) { ImGui::Text("Compiling Shaders"); - if (!_renderer->getMaterialCompilation()) - { + if (!_renderer->getMaterialCompilation()) { ImGui::CloseCurrentPopup(); } ImGui::EndPopup(); @@ -3602,61 +2965,46 @@ void Graph::shaderPopup() } // allow for camera manipulation of render view window -void Graph::handleRenderViewInputs(ImVec2 minValue, float width, float height) -{ +void Graph::handleRenderViewInputs(ImVec2 minValue, float width, float height) { ImVec2 mousePos = ImGui::GetMousePos(); - if (mousePos.x > minValue.x && mousePos.x < (minValue.x + width) && mousePos.y > minValue.y && mousePos.y < (minValue.y + height)) - { + if (mousePos.x > minValue.x && mousePos.x < (minValue.x + width) && mousePos.y > minValue.y && + mousePos.y < (minValue.y + height)) { mx::Vector2 mxMousePos = mx::Vector2(mousePos.x, mousePos.y); float scrollAmt = ImGui::GetIO().MouseWheel; int button = -1; bool down = false; - if (ImGui::IsMouseDragging(0) || ImGui::IsMouseDragging(1)) - { + if (ImGui::IsMouseDragging(0) || ImGui::IsMouseDragging(1)) { _renderer->setMouseMotionEvent(mxMousePos); } - if (ImGui::IsMouseClicked(0)) - { + if (ImGui::IsMouseClicked(0)) { button = 0; down = true; _renderer->setMouseButtonEvent(button, down, mxMousePos); - } - else if (ImGui::IsMouseClicked(1)) - { + } else if (ImGui::IsMouseClicked(1)) { button = 1; down = true; _renderer->setMouseButtonEvent(button, down, mxMousePos); - } - else if (ImGui::IsMouseReleased(0)) - { + } else if (ImGui::IsMouseReleased(0)) { button = 0; _renderer->setMouseButtonEvent(button, down, mxMousePos); - } - else if (ImGui::IsMouseReleased(1)) - { + } else if (ImGui::IsMouseReleased(1)) { button = 1; _renderer->setMouseButtonEvent(button, down, mxMousePos); - } - else if (ImGui::IsKeyPressed(ImGuiKey_KeypadAdd)) - { + } else if (ImGui::IsKeyPressed(ImGuiKey_KeypadAdd)) { _renderer->setKeyEvent(ImGuiKey_KeypadAdd); - } - else if (ImGui::IsKeyPressed(ImGuiKey_KeypadSubtract)) - { + } else if (ImGui::IsKeyPressed(ImGuiKey_KeypadSubtract)) { _renderer->setKeyEvent(ImGuiKey_KeypadSubtract); } // scrolling not possible if open or save file dialog is open - if (scrollAmt != 0 && !_fileDialogSave.isOpened() && !_fileDialog.isOpened() && !_fileDialogGeom.isOpened()) - { + if (scrollAmt != 0 && !_fileDialogSave.isOpened() && !_fileDialog.isOpened() && !_fileDialogGeom.isOpened()) { _renderer->setScrollEvent(scrollAmt); } } } + // sets up graph editor -void Graph::drawGraph(ImVec2 mousePos) -{ - if (_searchNodeId > 0) - { +void Graph::drawGraph(ImVec2 mousePos) { + if (_searchNodeId > 0) { ed::SelectNode(_searchNodeId); ed::NavigateToSelection(); _searchNodeId = -1; @@ -3664,10 +3012,13 @@ void Graph::drawGraph(ImVec2 mousePos) bool TextCursor = false; // center imgui window and setting size - ImGuiIO& io2 = ImGui::GetIO(); + ImGuiIO &io2 = ImGui::GetIO(); ImGui::SetNextWindowSize(io2.DisplaySize); - ImGui::SetNextWindowPos(ImVec2(io2.DisplaySize.x * 0.5f, io2.DisplaySize.y * 0.5f), ImGuiCond_Always, ImVec2(0.5f, 0.5f)); - ImGui::Begin("MaterialX", nullptr, ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings); + ImGui::SetNextWindowPos(ImVec2(io2.DisplaySize.x * 0.5f, io2.DisplaySize.y * 0.5f), ImGuiCond_Always, + ImVec2(0.5f, 0.5f)); + ImGui::Begin("MaterialX", nullptr, + ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoScrollbar | + ImGuiWindowFlags_NoSavedSettings); io2.ConfigFlags = ImGuiConfigFlags_IsSRGB | ImGuiConfigFlags_NavEnableKeyboard; io2.MouseDoubleClickTime = .5; @@ -3697,35 +3048,26 @@ void Graph::drawGraph(ImVec2 mousePos) selectedNodes.resize(nodeCount); selectedLinks.resize(linkCount); - if (io2.KeyCtrl && io2.MouseDown[0]) - { + if (io2.KeyCtrl && io2.MouseDown[0]) { _ctrlClick = true; } // setting current node based off of selected node - if (selectedNodes.size() > 0) - { + if (selectedNodes.size() > 0) { int graphPos = findNode(int(selectedNodes[0].Get())); - if (graphPos > -1) - { + if (graphPos > -1) { // only selected not if its not the same as previously selected - if (!_prevUiNode || (_prevUiNode->getName() != _graphNodes[graphPos]->getName())) - { + if (!_prevUiNode || (_prevUiNode->getName() != _graphNodes[graphPos]->getName())) { _currUiNode = _graphNodes[graphPos]; // update render material if needed - if (_currUiNode->getNode()) - { - if (_currUiNode->getNode()->getType() == mx::SURFACE_SHADER_TYPE_STRING || _currUiNode->getNode()->getType() == mx::MATERIAL_TYPE_STRING) - { + if (_currUiNode->getNode()) { + if (_currUiNode->getNode()->getType() == mx::SURFACE_SHADER_TYPE_STRING || + _currUiNode->getNode()->getType() == mx::MATERIAL_TYPE_STRING) { setRenderMaterial(_currUiNode); } - } - else if (_currUiNode->getNodeGraph()) - { + } else if (_currUiNode->getNodeGraph()) { setRenderMaterial(_currUiNode); - } - else if (_currUiNode->getOutput()) - { + } else if (_currUiNode->getOutput()) { setRenderMaterial(_currUiNode); } _prevUiNode = _currUiNode; @@ -3734,53 +3076,37 @@ void Graph::drawGraph(ImVec2 mousePos) } // check if keyboard shortcuts for copy/cut/paste have been used - if (ed::BeginShortcut()) - { - if (ed::AcceptCopy()) - { + if (ed::BeginShortcut()) { + if (ed::AcceptCopy()) { _copiedNodes.clear(); - for (ed::NodeId selected : selectedNodes) - { + for (ed::NodeId selected: selectedNodes) { int pos = findNode((int) selected.Get()); - if (pos >= 0) - { + if (pos >= 0) { _copiedNodes.insert(std::pair(_graphNodes[pos], nullptr)); } } - } - else if (ed::AcceptCut()) - { - if (!readOnly()) - { + } else if (ed::AcceptCut()) { + if (!readOnly()) { _copiedNodes.clear(); // same as copy but remove from graphNodes - for (ed::NodeId selected : selectedNodes) - { + for (ed::NodeId selected: selectedNodes) { int pos = findNode((int) selected.Get()); - if (pos >= 0) - { + if (pos >= 0) { _copiedNodes.insert(std::pair(_graphNodes[pos], nullptr)); } } _isCut = true; - } - else - { + } else { _popup = true; } - } - else if (ed::AcceptPaste()) - { - if (!readOnly()) - { - for (std::map::iterator iter = _copiedNodes.begin(); iter != _copiedNodes.end(); iter++) - { + } else if (ed::AcceptPaste()) { + if (!readOnly()) { + for (std::map::iterator iter = _copiedNodes.begin(); + iter != _copiedNodes.end(); iter++) { copyUiNode(iter->first); } _addNewNode = true; - } - else - { + } else { _popup = true; } } @@ -3790,43 +3116,34 @@ void Graph::drawGraph(ImVec2 mousePos) std::vector outputNum = createNodes(_isNodeGraph); // address copy information if applicable and relink graph if a new node has been added - if (_addNewNode) - { + if (_addNewNode) { copyInputs(); linkGraph(); ImVec2 canvasPos = ed::ScreenToCanvas(mousePos); // place the copied nodes or the individual new nodes - if ((int) _copiedNodes.size() > 0) - { + if ((int) _copiedNodes.size() > 0) { positionPasteBin(canvasPos); - } - else - { + } else { ed::SetNodePosition(_graphNodes.back()->getId(), canvasPos); } _copiedNodes.clear(); _addNewNode = false; } // layout and link graph during the initial call of drawGraph() - if (_initial || _autoLayout) - { + if (_initial || _autoLayout) { _currLinks.clear(); float y = 0.f; _levelMap = std::unordered_map>(); // start layout with output or material nodes since layout algorithm works right to left - for (int outN : outputNum) - { + for (int outN: outputNum) { layoutPosition(_graphNodes[outN], ImVec2(1200.f, y), true, 0); y += 350; } // if there are no output or material nodes but the nodes have position layout each individual node - if (_graphNodes.size() > 0) - { + if (_graphNodes.size() > 0) { - if (outputNum.size() == 0 && _graphNodes[0]->getMxElement()) - { - for (UiNodePtr node : _graphNodes) - { + if (outputNum.size() == 0 && _graphNodes[0]->getMxElement()) { + for (UiNodePtr node: _graphNodes) { layoutPosition(node, ImVec2(0, 0), true, 0); } } @@ -3837,8 +3154,7 @@ void Graph::drawGraph(ImVec2 mousePos) // automatically frame node graph upon loading ed::NavigateToContent(); } - if (_delete) - { + if (_delete) { linkGraph(); _delete = false; @@ -3848,29 +3164,22 @@ void Graph::drawGraph(ImVec2 mousePos) _initial = false; _autoLayout = false; // delete selected nodes and their links if delete key is pressed or if the shortcut for cut is used - if (ImGui::IsKeyReleased(ImGuiKey_Delete) || _isCut) - { + if (ImGui::IsKeyReleased(ImGuiKey_Delete) || _isCut) { - if (selectedNodes.size() > 0) - { + if (selectedNodes.size() > 0) { _frameCount = ImGui::GetFrameCount(); _renderer->setMaterialCompilation(true); - for (ed::NodeId id : selectedNodes) - { + for (ed::NodeId id: selectedNodes) { - if (int(id.Get()) > 0) - { + if (int(id.Get()) > 0) { int pos = findNode(int(id.Get())); - if (pos >= 0 && !readOnly()) - { + if (pos >= 0 && !readOnly()) { deleteNode(_graphNodes[pos]); _delete = true; ed::DeselectNode(id); ed::DeleteNode(id); _currUiNode = nullptr; - } - else if (readOnly()) - { + } else if (readOnly()) { _popup = true; } } @@ -3881,62 +3190,46 @@ void Graph::drawGraph(ImVec2 mousePos) } // start the session with content centered - if (ImGui::GetFrameCount() == 2) - { + if (ImGui::GetFrameCount() == 2) { ed::NavigateToContent(0.0f); } // hotkey to frame selected node(s) - if (ImGui::IsKeyReleased(ImGuiKey_F) && !_fileDialogSave.isOpened()) - { + if (ImGui::IsKeyReleased(ImGuiKey_F) && !_fileDialogSave.isOpened()) { ed::NavigateToSelection(); } // go back up from inside a subgraph - if (ImGui::IsKeyReleased(ImGuiKey_U) && (!ImGui::IsPopupOpen("add node")) && (!ImGui::IsPopupOpen("search")) && !_fileDialogSave.isOpened()) - { + if (ImGui::IsKeyReleased(ImGuiKey_U) && (!ImGui::IsPopupOpen("add node")) && (!ImGui::IsPopupOpen("search")) && + !_fileDialogSave.isOpened()) { upNodeGraph(); } // adding new link - if (ed::BeginCreate()) - { + if (ed::BeginCreate()) { ed::PinId inputPinId, outputPinId, filterPinId; - if (ed::QueryNewLink(&inputPinId, &outputPinId)) - { - if (!readOnly()) - { + if (ed::QueryNewLink(&inputPinId, &outputPinId)) { + if (!readOnly()) { AddLink(inputPinId, outputPinId); - } - else - { + } else { _popup = true; } } - if (ed::QueryNewNode(&filterPinId)) - { - if (getPin(filterPinId)->_type != "null") - { + if (ed::QueryNewNode(&filterPinId)) { + if (getPin(filterPinId)->_type != "null") { _pinFilterType = getPin(filterPinId)->_type; } } - } - else - { + } else { _pinFilterType = mx::EMPTY_STRING; } ed::EndCreate(); // deleting link - if (ed::BeginDelete()) - { + if (ed::BeginDelete()) { ed::LinkId deletedLinkId; - while (ed::QueryDeletedLink(&deletedLinkId)) - { - if (!readOnly()) - { + while (ed::QueryDeletedLink(&deletedLinkId)) { + if (!readOnly()) { deleteLink(deletedLinkId); - } - else - { + } else { _popup = true; } } @@ -3946,17 +3239,13 @@ void Graph::drawGraph(ImVec2 mousePos) // diving into a node that has a subgraph ed::NodeId clickedNode = ed::GetDoubleClickedNode(); - if (clickedNode.Get() > 0) - { - if (_currUiNode != nullptr) - { - if (_currUiNode->getNode() != nullptr) - { + if (clickedNode.Get() > 0) { + 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()) - { + if (impl && impl->isA()) { savePosition(); _graphStack.push(_graphNodes); _pinStack.push(_currPins); @@ -3967,23 +3256,18 @@ void Graph::drawGraph(ImVec2 mousePos) ed::DeselectNode(_currUiNode->getId()); _currUiNode = nullptr; _currGraphElem = implGraph; - if (readOnly()) - { + if (readOnly()) { std::string graphName = implGraph->getName() + " (Read Only)"; _currGraphName.push_back(graphName); _popup = true; - } - else - { + } else { _currGraphName.push_back(implGraph->getName()); } buildUiNodeGraph(implGraph); ed::NavigateToContent(); } - } - else if (_currUiNode->getNodeGraph() != nullptr) - { + } else if (_currUiNode->getNodeGraph() != nullptr) { savePosition(); _graphStack.push(_graphNodes); _pinStack.push(_currPins); @@ -3996,15 +3280,12 @@ void Graph::drawGraph(ImVec2 mousePos) ed::DeselectNode(_currUiNode->getId()); _currUiNode = nullptr; _currGraphElem = implGraph; - if (readOnly()) - { + if (readOnly()) { std::string graphName = implGraph->getName() + " (Read Only)"; _currGraphName.push_back(graphName); _popup = true; - } - else - { + } else { _currGraphName.push_back(implGraph->getName()); } buildUiNodeGraph(implGraph); @@ -4014,8 +3295,7 @@ void Graph::drawGraph(ImVec2 mousePos) } shaderPopup(); - if (ImGui::GetFrameCount() == (_frameCount + 2)) - { + if (ImGui::GetFrameCount() == (_frameCount + 2)) { updateMaterials(); _renderer->setMaterialCompilation(false); } @@ -4023,12 +3303,10 @@ void Graph::drawGraph(ImVec2 mousePos) ed::Suspend(); _fileDialogSave.display(); // saving file - if (_fileDialogSave.hasSelected()) - { + if (_fileDialogSave.hasSelected()) { std::string message; - if (!_graphDoc->validate(&message)) - { + if (!_graphDoc->validate(&message)) { std::cerr << "*** Validation warnings for " << _materialFilename.getBaseName() << " ***" << std::endl; std::cerr << message; } @@ -4039,9 +3317,7 @@ void Graph::drawGraph(ImVec2 mousePos) writeText(fileName, name); _fileDialogSave.clearSelected(); - } - else - { + } else { ed::Resume(); } @@ -4050,8 +3326,7 @@ void Graph::drawGraph(ImVec2 mousePos) _fileDialog.display(); // create and load document from selected file - if (_fileDialog.hasSelected()) - { + if (_fileDialog.hasSelected()) { mx::FilePath fileName = _fileDialog.getSelected(); _currGraphName.clear(); std::string graphName = fileName.getBaseName(); @@ -4070,8 +3345,7 @@ void Graph::drawGraph(ImVec2 mousePos) } _fileDialogGeom.display(); - if (_fileDialogGeom.hasSelected()) - { + if (_fileDialogGeom.hasSelected()) { mx::FilePath fileName = _fileDialogGeom.getSelected(); _fileDialogGeom.clearSelected(); _renderer->loadMesh(fileName); @@ -4082,13 +3356,10 @@ void Graph::drawGraph(ImVec2 mousePos) } // return node location in graphNodes vector based off of node id -int Graph::findNode(int nodeId) -{ +int Graph::findNode(int nodeId) { int count = 0; - for (size_t i = 0; i < _graphNodes.size(); i++) - { - if (_graphNodes[i]->getId() == nodeId) - { + for (size_t i = 0; i < _graphNodes.size(); i++) { + if (_graphNodes[i]->getId() == nodeId) { return count; } count++; @@ -4097,71 +3368,50 @@ int Graph::findNode(int nodeId) } // find a link based on an attribute id -std::vector Graph::findLinkId(int id) -{ +std::vector Graph::findLinkId(int id) { std::vector ids; - for (const Link& link : _currLinks) - { - if (link._startAttr == id || link._endAttr == id) - { + for (const Link &link: _currLinks) { + if (link._startAttr == id || link._endAttr == id) { ids.push_back(link.id); } } return ids; } + // check if current edge is already in edge vector -bool Graph::edgeExists(UiEdge newEdge) -{ - if (_currEdge.size() > 0) - { - for (UiEdge edge : _currEdge) - { - if (edge.getDown()->getId() == newEdge.getDown()->getId()) - { - if (edge.getUp()->getId() == newEdge.getUp()->getId()) - { - if (edge.getInput() == newEdge.getInput()) - { +bool Graph::edgeExists(UiEdge newEdge) { + if (_currEdge.size() > 0) { + for (UiEdge edge: _currEdge) { + if (edge.getDown()->getId() == newEdge.getDown()->getId()) { + if (edge.getUp()->getId() == newEdge.getUp()->getId()) { + if (edge.getInput() == newEdge.getInput()) { return true; } } - } - else if (edge.getUp()->getId() == newEdge.getDown()->getId()) - { - if (edge.getDown()->getId() == newEdge.getUp()->getId()) - { - if (edge.getInput() == newEdge.getInput()) - { + } else if (edge.getUp()->getId() == newEdge.getDown()->getId()) { + if (edge.getDown()->getId() == newEdge.getUp()->getId()) { + if (edge.getInput() == newEdge.getInput()) { return true; } } } } - } - else - { + } else { return false; } return false; } // check if a link exists in currLink vector -bool Graph::linkExists(Link newLink) -{ - for (const auto& link : _currLinks) - { - if (link._startAttr == newLink._startAttr) - { - if (link._endAttr == newLink._endAttr) - { +bool Graph::linkExists(Link newLink) { + for (const auto &link: _currLinks) { + if (link._startAttr == newLink._startAttr) { + if (link._endAttr == newLink._endAttr) { // link exists return true; } - } - else if (link._startAttr == newLink._endAttr) - { - if (link._endAttr == newLink._startAttr) - { + } else if (link._startAttr == newLink._endAttr) { + if (link._endAttr == newLink._startAttr) { // link exists return true; } @@ -4171,28 +3421,23 @@ bool Graph::linkExists(Link newLink) } // set materialX attribute positions for nodes which changed pos -void Graph::savePosition() -{ - for (UiNodePtr node : _graphNodes) - { - if (node->getMxElement() != nullptr) - { +void Graph::savePosition() { + for (UiNodePtr node: _graphNodes) { + if (node->getMxElement() != nullptr) { ImVec2 pos = ed::GetNodePosition(node->getId()); pos.x /= DEFAULT_NODE_SIZE.x; pos.y /= DEFAULT_NODE_SIZE.y; node->getMxElement()->setAttribute("xpos", std::to_string(pos.x)); node->getMxElement()->setAttribute("ypos", std::to_string(pos.y)); - if (node->getMxElement()->hasAttribute("nodedef")) - { + if (node->getMxElement()->hasAttribute("nodedef")) { node->getMxElement()->removeAttribute("nodedef"); } } } } -void Graph::writeText(std::string fileName, mx::FilePath filePath) -{ - if (filePath.getExtension() != mx::MTLX_EXTENSION) - { + +void Graph::writeText(std::string fileName, mx::FilePath filePath) { + if (filePath.getExtension() != mx::MTLX_EXTENSION) { filePath.addExtension(mx::MTLX_EXTENSION); } @@ -4200,3 +3445,13 @@ void Graph::writeText(std::string fileName, mx::FilePath filePath) writeOptions.elementPredicate = getElementPredicate(); mx::writeToXmlFile(_graphDoc, filePath, &writeOptions); } + +template +void Graph::setName(const Element &node, const std::string &name) { + if (name.empty()) { + auto childName = _currGraphElem->createValidChildName(name + "1"); + node->setName(childName); + } else { + node->setName(name); + } +} diff --git a/source/MaterialXGraphEditor/Graph.h b/source/MaterialXGraphEditor/Graph.h index 68140cdaae..f4f31f2202 100644 --- a/source/MaterialXGraphEditor/Graph.h +++ b/source/MaterialXGraphEditor/Graph.h @@ -19,106 +19,142 @@ namespace mx = MaterialX; // A link connects two pins and includes a unique id and the ids of the two pins it connects // Based off Link struct from ImGui Node Editor blueprints-examples.cpp -struct Link -{ +struct Link { int id; int _startAttr, _endAttr; + Link() : - _startAttr(-1), - _endAttr(-1) - { + _startAttr(-1), + _endAttr(-1) { static int _id = 0; id = ++_id; } }; -class Graph -{ - public: - Graph(const std::string& materialFilename, - const std::string& meshFilename, - const mx::FileSearchPath& searchPath, - const mx::FilePathVec& libraryFolders, +class Graph { +public: + Graph(const std::string &materialFilename, + const std::string &meshFilename, + const mx::FileSearchPath &searchPath, + const mx::FilePathVec &libraryFolders, int viewWidth, int viewHeight); mx::DocumentPtr loadDocument(mx::FilePath filename); + void drawGraph(ImVec2 mousePos); - RenderViewPtr getRenderer() - { + RenderViewPtr getRenderer() { return _renderer; } - void setFontScale(float val) - { + void setFontScale(float val) { _fontScale = val; } - ~Graph(){}; + ~Graph() {}; - private: +private: mx::ElementPredicate getElementPredicate() const; + void loadStandardLibraries(); + void createNodeUIList(mx::DocumentPtr doc); + void buildUiBaseGraph(mx::DocumentPtr doc); - void buildUiNodeGraph(const mx::NodeGraphPtr& nodeGraphs); + + void buildUiNodeGraph(const mx::NodeGraphPtr &nodeGraphs); + void buildGroupNode(UiNodePtr node); + template + void setName(const Element& node,const std::string &name); + // handling link information void linkGraph(); + void connectLinks(); + int findLinkPosition(int id); + std::vector findLinkId(int attrId); + bool linkExists(Link newLink); + void AddLink(ed::PinId inputPinId, ed::PinId outputPinId); + void deleteLink(ed::LinkId deletedLinkId); + void deleteLinkInfo(int startAtrr, int endAttr); // functions for the layout of the nodes ImVec2 layoutPosition(UiNodePtr node, ImVec2 pos, bool initialLayout, int level); + void layoutInputs(); + void findYSpacing(float startPos); + float totalHeight(int level); + void setYSpacing(int level, float startingPos); - float findAvgY(const std::vector& nodes); + + float findAvgY(const std::vector &nodes); // pin information void setPinColor(); + void DrawPinIcon(std::string type, bool connected, int alpha); + UiPinPtr getPin(ed::PinId id); + void drawInputPin(UiPinPtr pin); + ed::PinId getOutputPin(UiNodePtr node, UiNodePtr inputNode, UiPinPtr input); - void drawOutputPins(UiNodePtr node, const std::string& longestInputLabel); + + void drawOutputPins(UiNodePtr node, const std::string &longestInputLabel); + void addNodeGraphPins(); // UiNode functions std::vector createNodes(bool nodegraph); + int getNodeId(ed::PinId pinId); + int findNode(int nodeId); - int findNode(const std::string& name, const std::string& type); - void addNode(const std::string& category, const std::string& name, const std::string& type); + + int findNode(const std::string &name, const std::string &type); + + void addNode(const std::string &category, const std::string &name, const std::string &type); + void deleteNode(UiNodePtr node); - void setUiNodeInfo(UiNodePtr node, const std::string& type, const std::string& category); + + void setUiNodeInfo(UiNodePtr node, const std::string &type, const std::string &category); // UiEdge functions bool edgeExists(UiEdge edge); + void createEdge(UiNodePtr upNode, UiNodePtr downNode, mx::InputPtr connectingInput); + void removeEdge(int downNode, int upNode, UiPinPtr pin); void writeText(std::string filename, mx::FilePath filePath); + void savePosition(); + bool checkPosition(UiNodePtr node); - void addNodeInput(UiNodePtr node, mx::InputPtr& input); + void addNodeInput(UiNodePtr node, mx::InputPtr &input); + mx::InputPtr findInput(mx::InputPtr input, std::string name); // travel up from inside a node graph void upNodeGraph(); // property editor information - void setConstant(UiNodePtr node, mx::InputPtr& input, const mx::UIProperties& uiProperties); + void setConstant(UiNodePtr node, mx::InputPtr &input, const mx::UIProperties &uiProperties); + void propertyEditor(); + void setDefaults(mx::InputPtr input); // set up Ui information for add node popup @@ -126,8 +162,11 @@ class Graph // copy and paste functions void copyInputs(); + void positionPasteBin(ImVec2 pos); + void copyNodeGraph(UiNodePtr origGraph, UiNodePtr copyGraph); + void copyUiNode(UiNodePtr node); // renderview window and buttons @@ -135,21 +174,31 @@ class Graph // popup information void addNodePopup(bool cursor); + void searchNodePopup(bool cursor); + bool readOnly(); + void readOnlyPopup(); + void shaderPopup(); // modifying materials void updateMaterials(mx::InputPtr input = nullptr, mx::ValuePtr value = nullptr); + void selectMaterial(UiNodePtr node); + void handleRenderViewInputs(ImVec2 minValue, float width, float height); + void setRenderMaterial(UiNodePtr node); // File I/O void clearGraph(); + void loadGraphFromFile(); + void saveGraphToFile(); + void loadGeometry(); mx::StringVec _geomFilter;