From 4ef6701a99b1f7e8e2e854ae35e538bf2b34cf95 Mon Sep 17 00:00:00 2001 From: Bernard Kwok Date: Wed, 3 Dec 2025 16:41:05 -0500 Subject: [PATCH 1/3] Add image preview option. --- source/MaterialXGraphEditor/Graph.cpp | 77 +++++++++++++++++++++++++-- source/MaterialXGraphEditor/Graph.h | 6 ++- source/MaterialXGraphEditor/Main.cpp | 9 +++- 3 files changed, 86 insertions(+), 6 deletions(-) diff --git a/source/MaterialXGraphEditor/Graph.cpp b/source/MaterialXGraphEditor/Graph.cpp index e6d369c422..7d8adc2a26 100644 --- a/source/MaterialXGraphEditor/Graph.cpp +++ b/source/MaterialXGraphEditor/Graph.cpp @@ -136,7 +136,8 @@ Graph::Graph(const std::string& materialFilename, const mx::FileSearchPath& searchPath, const mx::FilePathVec& libraryFolders, int viewWidth, - int viewHeight) : + int viewHeight, + float previewWidth) : _materialFilename(materialFilename), _searchPath(searchPath), _libraryFolders(libraryFolders), @@ -154,6 +155,7 @@ Graph::Graph(const std::string& materialFilename, _autoLayout(false), _frameCount(INT_MIN), _fontScale(1.0f), + _previewSize(previewWidth), _saveNodePositions(true) { loadStandardLibraries(); @@ -1132,12 +1134,60 @@ void Graph::showPropertyEditorValue(UiNodePtr node, mx::InputPtr& input, const m } else if (input->getType() == "filename") { - mx::ValuePtr val = input->getValue(); + mx::ValuePtr val = input->getResolvedValue(); if (val && val->isA()) { std::string prev, temp; prev = temp = val->asA(); + mx::FilePath filePath(temp); + + bool drawPreview = _previewSize > 0; + if (drawPreview) + { + float previewSize = _previewSize; + // Clamp preview size to width of panel + float panelWidth = ImGui::GetContentRegionAvail().x; + if (previewSize > panelWidth) + { + previewSize = panelWidth; + } + + ImGui::BeginChild("imagePreview", ImVec2(previewSize, previewSize), false, + ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse); + + // Show image preview if file exists and is an image + if (!temp.empty()) + { + mx::ImageHandlerPtr imageHandler = _renderer ? _renderer->getImageHandler() : nullptr; + if (imageHandler) + { + unsigned int textureId = 0; + int width = 0, height = 0; + mx::ImagePtr image = imageHandler->acquireImage(filePath); + if (image) + { + textureId = image->getResourceId(); + width = image->getWidth(); + height = image->getHeight(); + } + else + { + std::cout << "filename not loaded: " << temp << std::endl; + } + if (textureId) + { + float aspect = (height > 0) ? (float)width / (float)height : 1.0f; + ImVec2 imagePreviewSize(previewSize, previewSize / aspect); + + ImGui::Image((void*)(intptr_t)textureId, imagePreviewSize); + } + } + } + ImGui::EndChild(); + //ImGui::PopItemWidth(); + } + ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(.15f, .15f, .15f, 1.0f)); ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(.2f, .4f, .6f, 1.0f)); @@ -1152,7 +1202,9 @@ void Graph::showPropertyEditorValue(UiNodePtr node, mx::InputPtr& input, const m } ImGui::PopItemWidth(); ImGui::SameLine(); - ImGui::Text("%s", mx::FilePath(temp).getBaseName().c_str()); + + ImGui::Text("%s", filePath.getBaseName().c_str()); + ImGui::PopStyleColor(); ImGui::PopStyleColor(); @@ -3518,6 +3570,9 @@ void Graph::propertyEditor() if (_currUiNode) { + // Set font scale + ImGui::SetWindowFontScale(_fontScale * 0.5); + // Set and edit name ImGui::Text("Name: "); ImGui::SameLine(); @@ -3658,16 +3713,30 @@ void Graph::propertyEditor() ImGui::Checkbox("Show output connections", &_currUiNode->_showOutputsInEditor); int count = 0; + float totalImagePadding = 0.0f; + float imagePadding = 0.0f; + if (_previewSize > 0.0f) + { + imagePadding = (_previewSize > availableWidth) ? availableWidth : _previewSize; + } for (UiPinPtr input : _currUiNode->inputPins) { if (_currUiNode->_showAllInputs || (input->getConnected() || _currUiNode->getNode()->getInput(input->_name))) { count++; + + // Add space for image previews + if (imagePadding > 0.0f && input->_input->getType() == "filename") + { + totalImagePadding += imagePadding; + } } } if (count) { - ImVec2 tableSize(0.0f, TEXT_BASE_HEIGHT * std::min(SCROLL_LINE_COUNT, count)); + //ImVec2 tableSize(0.0f, TEXT_BASE_HEIGHT * std::min(SCROLL_LINE_COUNT, count)); + float baseHeight = TEXT_BASE_HEIGHT * std::min(SCROLL_LINE_COUNT, count); + ImVec2 tableSize(0.0f, baseHeight + totalImagePadding); bool haveTable = ImGui::BeginTable("inputs_node_table", 2, tableFlags, tableSize); if (haveTable) { diff --git a/source/MaterialXGraphEditor/Graph.h b/source/MaterialXGraphEditor/Graph.h index 8d65706194..3ef56a5a2c 100644 --- a/source/MaterialXGraphEditor/Graph.h +++ b/source/MaterialXGraphEditor/Graph.h @@ -66,7 +66,8 @@ class Graph const mx::FileSearchPath& searchPath, const mx::FilePathVec& libraryFolders, int viewWidth, - int viewHeight); + int viewHeight, + float previewWidth); ~Graph() = default; mx::DocumentPtr loadDocument(const mx::FilePath& filename); @@ -330,6 +331,9 @@ class Graph // DPI scaling for fonts float _fontScale; + // Preview area size + float _previewSize; + // Options bool _saveNodePositions; }; diff --git a/source/MaterialXGraphEditor/Main.cpp b/source/MaterialXGraphEditor/Main.cpp index 59d3022ede..5fd8e4c49c 100644 --- a/source/MaterialXGraphEditor/Main.cpp +++ b/source/MaterialXGraphEditor/Main.cpp @@ -34,6 +34,7 @@ const std::string options = " --font [FILENAME] Specify the name of the custom font file to use. If not specified the default font will be used.\n" " --fontSize [SIZE] Specify font size to use for the custom font. If not specified a default of 18 will be used.\n" " --captureFilename [FILENAME] Specify the filename to which the first rendered frame should be written\n" + " --previewWidth [WIDTH] Specify the width for image previews\n" " --help Display the complete list of command-line options\n"; template void parseToken(std::string token, std::string type, T& res) @@ -72,6 +73,7 @@ int main(int argc, char* const argv[]) float uiScale = 0.0f; std::string fontFilename; int fontSize = 18; + float previewWidth = 128.0f; std::string captureFilename; for (size_t i = 0; i < tokens.size(); i++) @@ -115,6 +117,10 @@ int main(int argc, char* const argv[]) { parseToken(nextToken, "integer", fontSize); } + else if (token == "--previewWidth") + { + parseToken(nextToken, "float", previewWidth); + } else if (token == "--captureFilename") { parseToken(nextToken, "string", captureFilename); @@ -215,7 +221,8 @@ int main(int argc, char* const argv[]) searchPath, libraryFolders, viewWidth, - viewHeight); + viewHeight, + previewWidth); if (!captureFilename.empty()) { graph->getRenderer()->requestFrameCapture(captureFilename); From 9b56362b8b5f22cf53300d121bd4413e4d9166be Mon Sep 17 00:00:00 2001 From: Bernard Kwok Date: Wed, 3 Dec 2025 16:51:55 -0500 Subject: [PATCH 2/3] Cleanup. --- source/MaterialXGraphEditor/Graph.cpp | 6 +----- source/MaterialXGraphEditor/Main.cpp | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/source/MaterialXGraphEditor/Graph.cpp b/source/MaterialXGraphEditor/Graph.cpp index 7d8adc2a26..72255c48e0 100644 --- a/source/MaterialXGraphEditor/Graph.cpp +++ b/source/MaterialXGraphEditor/Graph.cpp @@ -1173,7 +1173,7 @@ void Graph::showPropertyEditorValue(UiNodePtr node, mx::InputPtr& input, const m } else { - std::cout << "filename not loaded: " << temp << std::endl; + std::cout << "Image file not loaded: " << temp << std::endl; } if (textureId) { @@ -1202,7 +1202,6 @@ void Graph::showPropertyEditorValue(UiNodePtr node, mx::InputPtr& input, const m } ImGui::PopItemWidth(); ImGui::SameLine(); - ImGui::Text("%s", filePath.getBaseName().c_str()); ImGui::PopStyleColor(); @@ -3570,9 +3569,6 @@ void Graph::propertyEditor() if (_currUiNode) { - // Set font scale - ImGui::SetWindowFontScale(_fontScale * 0.5); - // Set and edit name ImGui::Text("Name: "); ImGui::SameLine(); diff --git a/source/MaterialXGraphEditor/Main.cpp b/source/MaterialXGraphEditor/Main.cpp index 5fd8e4c49c..58553af130 100644 --- a/source/MaterialXGraphEditor/Main.cpp +++ b/source/MaterialXGraphEditor/Main.cpp @@ -73,7 +73,7 @@ int main(int argc, char* const argv[]) float uiScale = 0.0f; std::string fontFilename; int fontSize = 18; - float previewWidth = 128.0f; + float previewWidth = 256.0f; std::string captureFilename; for (size_t i = 0; i < tokens.size(); i++) From eab92f9238b26a1eabb0e11951da8cc2fb277b2a Mon Sep 17 00:00:00 2001 From: Bernard Kwok Date: Mon, 2 Mar 2026 13:47:25 -0500 Subject: [PATCH 3/3] Add missing merge changes. --- source/MaterialXGraphEditor/Graph.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/source/MaterialXGraphEditor/Graph.cpp b/source/MaterialXGraphEditor/Graph.cpp index 358c032aca..66b39145a8 100644 --- a/source/MaterialXGraphEditor/Graph.cpp +++ b/source/MaterialXGraphEditor/Graph.cpp @@ -3442,16 +3442,14 @@ void Graph::propertyEditor() imagePadding = (_previewSize > availableWidth) ? availableWidth : _previewSize; } - - int count = 0; - for (UiPinPtr input : _currUiNode->inputPins) + for (UiPinPtr input : _currUiNode->getInputPins()) { if (_currUiNode->getShowAllInputs() || (input->getConnected() || _currUiNode->getNode()->getInput(input->getName()))) { count++; // Add space for image previews - if (imagePadding > 0.0f && input->_input->getType() == "filename") + if (imagePadding > 0.0f && input->getInput()->getType() == "filename") { totalImagePadding += imagePadding; } @@ -3459,7 +3457,6 @@ void Graph::propertyEditor() } if (count) { - //ImVec2 tableSize(0.0f, TEXT_BASE_HEIGHT * std::min(SCROLL_LINE_COUNT, count)); float baseHeight = TEXT_BASE_HEIGHT * std::min(SCROLL_LINE_COUNT, count); ImVec2 tableSize(0.0f, baseHeight + totalImagePadding); bool haveTable = ImGui::BeginTable("inputs_node_table", 2, tableFlags, tableSize);