diff --git a/applications/plugins/SofaMatrix/extensions/imgui/src/SofaMatrix/imgui/BaseMatrixImageProxyWidget.cpp b/applications/plugins/SofaMatrix/extensions/imgui/src/SofaMatrix/imgui/BaseMatrixImageProxyWidget.cpp index 5f58d5aacbc..5bdcc229aff 100644 --- a/applications/plugins/SofaMatrix/extensions/imgui/src/SofaMatrix/imgui/BaseMatrixImageProxyWidget.cpp +++ b/applications/plugins/SofaMatrix/extensions/imgui/src/SofaMatrix/imgui/BaseMatrixImageProxyWidget.cpp @@ -19,10 +19,15 @@ * * * Contact information: contact@sofa-framework.org * ******************************************************************************/ -#include -#include #include +#include #include +#include +#include +#include +#include +#include +#include #include @@ -76,26 +81,66 @@ std::optional textureID(sofa::linearalgebra::BaseMatrix* ptr) return mapIt->second; } +ImVec4& getColorNonZero() +{ + static ImVec4 color = ImGui::GetStyleColorVec4(ImGuiCol_Text); + return color; +} + +ImVec4& getColorZero() +{ + static ImVec4 color = ImGui::GetStyleColorVec4(ImGuiCol_WindowBg); + return color; +} + void updateTexture(sofa::linearalgebra::BaseMatrix* matrix, unsigned& textureIDRef, std::vector& imageDataRef) { const auto width = matrix->rows(); const auto height = matrix->cols(); - imageDataRef.resize(width * height, 255); + imageDataRef.resize(width * height * 3, 255); + + const ImVec4 colorTrue = getColorNonZero(); + const ImVec4 colorFalse = getColorZero(); + + // Extract R, G, B components + const unsigned char rTrue = static_cast(255.f * colorTrue.x); + const unsigned char gTrue = static_cast(255.f * colorTrue.y); + const unsigned char bTrue = static_cast(255.f * colorTrue.z); + + const unsigned char rFalse = static_cast(255.f * colorFalse.x); + const unsigned char gFalse = static_cast(255.f * colorFalse.y); + const unsigned char bFalse = static_cast(255.f * colorFalse.z); // write the data for (sofa::SignedIndex y = 0; y < height; ++y) { for (sofa::SignedIndex x = 0; x < width; ++x) { - imageDataRef[y * width + x] = !static_cast(matrix->element(x, y)) * std::numeric_limits::max(); + size_t index = (y * width + x) * 3; + + // Determine the color based on matrix element value + if (matrix->element(x, y)) + { + // Element is TRUE: Use Window Background Color + imageDataRef[index] = rTrue; // R + imageDataRef[index + 1] = gTrue; // G + imageDataRef[index + 2] = bTrue; // B + } + else + { + // Element is FALSE: Use Text Color + imageDataRef[index] = rFalse; // R + imageDataRef[index + 1] = gFalse; // G + imageDataRef[index + 2] = bFalse; // B + } } } // Update the texture glBindTexture(GL_TEXTURE_2D, textureIDRef); - glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, imageDataRef.data()); } @@ -183,6 +228,72 @@ void DataWidget::showWidget(MyData& data) { *lastCounter = counter; } + + if (ImGui::ColorEdit3(("Color non-zero##" + data.getOwner()->getPathName() + data.getName()).c_str(), (float*)&sofamatrix::imgui::getColorNonZero()) + || + ImGui::ColorEdit3(("Color zero##" + data.getOwner()->getPathName() + data.getName()).c_str(), (float*)&sofamatrix::imgui::getColorZero())) + { + auto textureID = sofamatrix::imgui::textureID(matrix); + if (textureID.has_value() == true) + { + auto imageData = sofamatrix::imgui::imageData(matrix); + if (imageData.has_value() == true) + { + auto& textureIDRef = textureID.value(); + auto& imageDataRef = imageData.value(); + + sofamatrix::imgui::updateTexture(matrix, textureIDRef, imageDataRef); + } + } + } + + ImGui::NewLine(); + if (ImGui::Button(("Save image##" + data.getOwner()->getPathName() + data.getName()).c_str())) + { + sofa::helper::io::STBImage image; + image.init(matrix->rows(), matrix->cols(), 1, 1, + sofa::helper::io::Image::DataType::UNORM8, sofa::helper::io::Image::ChannelFormat::RGB); + + auto textureID = sofamatrix::imgui::textureID(matrix); + if (textureID.has_value() == true) + { + auto imageData = sofamatrix::imgui::imageData(matrix); + if (imageData.has_value() == true) + { + auto& imageDataRef = imageData.value(); + auto& textureIDRef = textureID.value(); + sofamatrix::imgui::updateTexture(matrix, textureIDRef, imageDataRef); + + if (!imageDataRef.empty()) + { + unsigned char* pixels = image.getPixels(); + for (sofa::SignedIndex y = 0; y < matrix->cols(); ++y) + { + for (sofa::SignedIndex x = 0; x < matrix->rows(); ++x) + { + for (std::size_t i = 0; i < 3; ++i) + { + pixels[y * matrix->rows() * 3 + x * 3 + i] = imageDataRef[(matrix->rows() - y) * matrix->rows() * 3 + x * 3 + i]; + } + } + } + const auto filename = sofa::helper::system::FileSystem::append(sofa::helper::Utils::getExecutableDirectory(), "matrix.bmp"); + if (image.save(filename)) + { + msg_info("Matrix") << "Saved matrix file in '" << filename << "'"; + } + else + { + msg_error(data.getOwner()) << "Error while saving matrix to file '" << filename << "'"; + } + } + else + { + msg_error(data.getOwner()) << "Cannot save matrix to file"; + } + } + } + } } else {