From b756346f433a930a2c4687a2271a9ca294aa7469 Mon Sep 17 00:00:00 2001 From: Nicholas Sharp Date: Fri, 20 Dec 2024 09:32:24 -0500 Subject: [PATCH 1/3] initial implementation of texture filtering option --- include/polyscope/color_quantity.h | 3 +- include/polyscope/color_quantity.ipp | 3 ++ include/polyscope/persistent_value.h | 2 + include/polyscope/render/engine.h | 7 ++- include/polyscope/surface_color_quantity.h | 13 ++++++ include/polyscope/types.h | 1 + src/persistent_value.cpp | 1 + src/surface_color_quantity.cpp | 52 +++++++++++++++++++++- 8 files changed, 75 insertions(+), 7 deletions(-) diff --git a/include/polyscope/color_quantity.h b/include/polyscope/color_quantity.h index 63c97d835..e880bb877 100644 --- a/include/polyscope/color_quantity.h +++ b/include/polyscope/color_quantity.h @@ -17,8 +17,9 @@ class ColorQuantity { public: ColorQuantity(QuantityT& parent, const std::vector& colors); - // Build the ImGUI UIs for scalars + // Build the ImGUI UIs for colors void buildColorUI(); + virtual void buildColorOptionsUI(); // called inside of an options menu // Add rules to rendering programs for scalars std::vector addColorRules(std::vector rules); diff --git a/include/polyscope/color_quantity.ipp b/include/polyscope/color_quantity.ipp index d42678de3..cd20821b5 100644 --- a/include/polyscope/color_quantity.ipp +++ b/include/polyscope/color_quantity.ipp @@ -9,6 +9,9 @@ ColorQuantity::ColorQuantity(QuantityT& quantity_, const std::vector< template void ColorQuantity::buildColorUI() {} +template +void ColorQuantity::buildColorOptionsUI() {} + template void ColorQuantity::setColorUniforms(render::ShaderProgram& p) {} diff --git a/include/polyscope/persistent_value.h b/include/polyscope/persistent_value.h index fc7dca8f1..daa9449f2 100644 --- a/include/polyscope/persistent_value.h +++ b/include/polyscope/persistent_value.h @@ -142,6 +142,7 @@ extern PersistentCache> persistentCache_vectorstring; extern PersistentCache persistentCache_paramVizStyle; extern PersistentCache persistentCache_BackFacePolicy; extern PersistentCache persistentCache_MeshNormalType; +extern PersistentCache persistentCache_FilterMode; template<> inline PersistentCache& getPersistentCacheRef() { return persistentCache_double; } template<> inline PersistentCache& getPersistentCacheRef() { return persistentCache_float; } @@ -155,6 +156,7 @@ template<> inline PersistentCache>& getPersistentCacheR template<> inline PersistentCache& getPersistentCacheRef() { return persistentCache_paramVizStyle; } template<> inline PersistentCache& getPersistentCacheRef() { return persistentCache_BackFacePolicy; } template<> inline PersistentCache& getPersistentCacheRef() { return persistentCache_MeshNormalType; } +template<> inline PersistentCache& getPersistentCacheRef() { return persistentCache_FilterMode; } } // clang-format on diff --git a/include/polyscope/render/engine.h b/include/polyscope/render/engine.h index 8c66931aa..e5eb83493 100644 --- a/include/polyscope/render/engine.h +++ b/include/polyscope/render/engine.h @@ -36,7 +36,6 @@ enum class DrawMode { TriangleStripInstanced, }; -enum class FilterMode { Nearest = 0, Linear }; enum class TextureFormat { RGB8 = 0, RGBA8, RG16F, RGB16F, RGBA16F, RGBA32F, RGB32F, R32F, R16F, DEPTH24 }; enum class RenderBufferType { Color, ColorAlpha, Depth, Float4 }; enum class DepthMode { Less, LEqual, LEqualReadOnly, Greater, Disable, PassReadOnly }; @@ -207,7 +206,7 @@ class RenderBuffer { public: // abstract class: use the factory methods from the Engine class RenderBuffer(RenderBufferType type_, unsigned int sizeX_, unsigned int sizeY_); - virtual ~RenderBuffer(){}; + virtual ~RenderBuffer() {}; virtual void resize(unsigned int newX, unsigned int newY); @@ -228,7 +227,7 @@ class FrameBuffer { public: // abstract class: use the factory methods from the Engine class FrameBuffer(); - virtual ~FrameBuffer(){}; + virtual ~FrameBuffer() {}; virtual void bind() = 0; // Bind to this framebuffer so subsequent draw calls will go to it @@ -347,7 +346,7 @@ class ShaderProgram { public: ShaderProgram(DrawMode dm); - virtual ~ShaderProgram(){}; + virtual ~ShaderProgram() {}; // === Store data diff --git a/include/polyscope/surface_color_quantity.h b/include/polyscope/surface_color_quantity.h index 2ba01dd12..096a619ec 100644 --- a/include/polyscope/surface_color_quantity.h +++ b/include/polyscope/surface_color_quantity.h @@ -19,6 +19,7 @@ class SurfaceColorQuantity : public SurfaceMeshQuantity, public ColorQuantity& colorValues); virtual void draw() override; + virtual void buildCustomUI() override; virtual std::string niceName() override; virtual void refresh() override; @@ -40,6 +41,7 @@ class SurfaceVertexColorQuantity : public SurfaceColorQuantity { SurfaceVertexColorQuantity(std::string name, SurfaceMesh& mesh_, std::vector values_); virtual void createProgram() override; + virtual void buildColorOptionsUI() override; void buildVertexInfoGUI(size_t vInd) override; }; @@ -53,6 +55,7 @@ class SurfaceFaceColorQuantity : public SurfaceColorQuantity { SurfaceFaceColorQuantity(std::string name, SurfaceMesh& mesh_, std::vector values_); virtual void createProgram() override; + virtual void buildColorOptionsUI() override; void buildFaceInfoGUI(size_t fInd) override; }; @@ -68,11 +71,21 @@ class SurfaceTextureColorQuantity : public SurfaceColorQuantity { size_t dimX, size_t dimY, std::vector values_, ImageOrigin origin_); virtual void createProgram() override; + virtual void buildColorOptionsUI() override; + + // === Get/set visualization parameters + + // what kind of texture filtering is used + SurfaceTextureColorQuantity* setFilterMode(FilterMode newFilterMode); + FilterMode getFilterMode(); protected: SurfaceParameterizationQuantity& param; size_t dimX, dimY; ImageOrigin imageOrigin; + + // === Visualization parameters + PersistentValue filterMode; // default is FilterMode::Linear }; } // namespace polyscope diff --git a/include/polyscope/types.h b/include/polyscope/types.h index 6a85b225b..124a5afb7 100644 --- a/include/polyscope/types.h +++ b/include/polyscope/types.h @@ -24,6 +24,7 @@ enum class VolumeCellType { TET = 0, HEX }; enum class ImplicitRenderMode { SphereMarch, FixedStep }; enum class ImageOrigin { LowerLeft, UpperLeft }; +enum class FilterMode { Nearest = 0, Linear }; enum class ParamCoordsType { UNIT = 0, WORLD }; // UNIT -> [0,1], WORLD -> length-valued enum class ParamVizStyle { diff --git a/src/persistent_value.cpp b/src/persistent_value.cpp index c2f46af30..a87d060d4 100644 --- a/src/persistent_value.cpp +++ b/src/persistent_value.cpp @@ -20,6 +20,7 @@ PersistentCache> persistentCache_vectorstring; PersistentCache persistentCache_paramVizStyle; PersistentCache persistentCache_BackFacePolicy; PersistentCache persistentCache_MeshNormalType; +PersistentCache persistentCache_FilterMode; // clang-format on } // namespace detail } // namespace polyscope diff --git a/src/surface_color_quantity.cpp b/src/surface_color_quantity.cpp index ecd2518a2..16e028291 100644 --- a/src/surface_color_quantity.cpp +++ b/src/surface_color_quantity.cpp @@ -27,6 +27,24 @@ void SurfaceColorQuantity::draw() { program->draw(); } +void SurfaceColorQuantity::buildCustomUI() { + ImGui::SameLine(); + + // == Options popup + if (ImGui::Button("Options")) { + ImGui::OpenPopup("OptionsPopup"); + } + if (ImGui::BeginPopup("OptionsPopup")) { + + buildColorOptionsUI(); + + ImGui::EndPopup(); + } + + buildColorUI(); +} + + // ======================================================== // ========== Vertex Color ========== // ======================================================== @@ -56,6 +74,11 @@ void SurfaceVertexColorQuantity::createProgram() { render::engine->setMaterial(*program, parent.getMaterial()); } +void SurfaceVertexColorQuantity::buildColorOptionsUI() { + ColorQuantity::buildColorOptionsUI(); + ImGui::TextUnformatted("(no options available)"); // remove once there is something in this menu +} + void SurfaceVertexColorQuantity::buildVertexInfoGUI(size_t vInd) { ImGui::TextUnformatted(name.c_str()); ImGui::NextColumn(); @@ -104,6 +127,11 @@ void SurfaceFaceColorQuantity::createProgram() { render::engine->setMaterial(*program, parent.getMaterial()); } +void SurfaceFaceColorQuantity::buildColorOptionsUI() { + ColorQuantity::buildColorOptionsUI(); + ImGui::TextUnformatted("(no options available)"); // remove once there is something in this menu +} + void SurfaceFaceColorQuantity::buildFaceInfoGUI(size_t fInd) { ImGui::TextUnformatted(name.c_str()); ImGui::NextColumn(); @@ -126,7 +154,7 @@ SurfaceTextureColorQuantity::SurfaceTextureColorQuantity(std::string name, Surfa size_t dimY_, std::vector colorValues_, ImageOrigin origin_) : SurfaceColorQuantity(name, mesh_, "texture", colorValues_), param(param_), dimX(dimX_), dimY(dimY_), - imageOrigin(origin_) { + imageOrigin(origin_), filterMode(quantity.uniquePrefix() + "filterMode", FilterMode::Linear) { colors.setTextureSize(dimX, dimY); } @@ -162,8 +190,28 @@ void SurfaceTextureColorQuantity::createProgram() { program->setTextureFromBuffer("t_color", colors.getRenderTextureBuffer().get()); render::engine->setMaterial(*program, parent.getMaterial()); - colors.getRenderTextureBuffer()->setFilterMode(FilterMode::Linear); + colors.getRenderTextureBuffer()->setFilterMode(filterMode.get()); } +void SurfaceTextureColorQuantity::buildColorOptionsUI() { + ColorQuantity::buildColorOptionsUI(); + + if (ImGui::BeginMenu("Filter Mode")) { + if (ImGui::MenuItem("linear", NULL, filterMode.get() == FilterMode::Linear)) setFilterMode(FilterMode::Linear); + if (ImGui::MenuItem("nearest", NULL, filterMode.get() == FilterMode::Nearest)) setFilterMode(FilterMode::Nearest); + ImGui::EndMenu(); + } +} + +SurfaceTextureColorQuantity* SurfaceTextureColorQuantity::setFilterMode(FilterMode newFilterMode) { + filterMode = newFilterMode; + if (program) { + colors.getRenderTextureBuffer()->setFilterMode(filterMode.get()); + } + return this; +} + +FilterMode SurfaceTextureColorQuantity::getFilterMode() { return filterMode.get(); } + } // namespace polyscope From 618f2b1938dce2606d67625791398f860427c28a Mon Sep 17 00:00:00 2001 From: Nicholas Sharp Date: Tue, 24 Dec 2024 16:11:16 -0500 Subject: [PATCH 2/3] factor out texture map options --- include/polyscope/surface_color_quantity.h | 15 ++------ include/polyscope/texture_map_quantity.h | 43 ++++++++++++++++++++++ include/polyscope/texture_map_quantity.ipp | 32 ++++++++++++++++ src/CMakeLists.txt | 2 + src/surface_color_quantity.cpp | 21 ++--------- 5 files changed, 83 insertions(+), 30 deletions(-) create mode 100644 include/polyscope/texture_map_quantity.h create mode 100644 include/polyscope/texture_map_quantity.ipp diff --git a/include/polyscope/surface_color_quantity.h b/include/polyscope/surface_color_quantity.h index 096a619ec..d0b5a2313 100644 --- a/include/polyscope/surface_color_quantity.h +++ b/include/polyscope/surface_color_quantity.h @@ -5,6 +5,7 @@ #include "polyscope/color_quantity.h" #include "polyscope/render/engine.h" #include "polyscope/surface_mesh.h" +#include "polyscope/texture_map_quantity.h" namespace polyscope { @@ -65,7 +66,8 @@ class SurfaceFaceColorQuantity : public SurfaceColorQuantity { // ========== Texture Color ========== // ======================================================== -class SurfaceTextureColorQuantity : public SurfaceColorQuantity { +class SurfaceTextureColorQuantity : public SurfaceColorQuantity, + public TextureMapQuantity { public: SurfaceTextureColorQuantity(std::string name, SurfaceMesh& mesh_, SurfaceParameterizationQuantity& param_, size_t dimX, size_t dimY, std::vector values_, ImageOrigin origin_); @@ -73,19 +75,8 @@ class SurfaceTextureColorQuantity : public SurfaceColorQuantity { virtual void createProgram() override; virtual void buildColorOptionsUI() override; - // === Get/set visualization parameters - - // what kind of texture filtering is used - SurfaceTextureColorQuantity* setFilterMode(FilterMode newFilterMode); - FilterMode getFilterMode(); - protected: SurfaceParameterizationQuantity& param; - size_t dimX, dimY; - ImageOrigin imageOrigin; - - // === Visualization parameters - PersistentValue filterMode; // default is FilterMode::Linear }; } // namespace polyscope diff --git a/include/polyscope/texture_map_quantity.h b/include/polyscope/texture_map_quantity.h new file mode 100644 index 000000000..43ceb322e --- /dev/null +++ b/include/polyscope/texture_map_quantity.h @@ -0,0 +1,43 @@ +// Copyright 2017-2023, Nicholas Sharp and the Polyscope contributors. https://polyscope.run + +#pragma once + +#include "polyscope/persistent_value.h" +#include "polyscope/polyscope.h" +#include "polyscope/render/engine.h" +#include "polyscope/render/managed_buffer.h" +#include "polyscope/standardize_data_array.h" + +namespace polyscope { + +// Encapsulates logic which is common to all texture map quantities + +template +class TextureMapQuantity { +public: + TextureMapQuantity(QuantityT& parent, size_t dimX, size_t dimY, ImageOrigin origin_); + + // Build the ImGUI UIs for texture maps + virtual void buildTextureMapOptionsUI(); // called inside of an options menu + + // === Members + QuantityT& quantity; + + // NOTE: the main quantity types (scalar quantity, color quantity, etc) provide the buffer members, so this class just + // has secondary options and such + + // what kind of texture filtering is used + QuantityT* setFilterMode(FilterMode newFilterMode); + FilterMode getFilterMode(); + +protected: + size_t dimX, dimY; + ImageOrigin imageOrigin; + + // === Visualization parameters + PersistentValue filterMode; // default is FilterMode::Linear +}; + +} // namespace polyscope + +#include "polyscope/texture_map_quantity.ipp" \ No newline at end of file diff --git a/include/polyscope/texture_map_quantity.ipp b/include/polyscope/texture_map_quantity.ipp new file mode 100644 index 000000000..66a04323c --- /dev/null +++ b/include/polyscope/texture_map_quantity.ipp @@ -0,0 +1,32 @@ +// Copyright 2017-2023, Nicholas Sharp and the Polyscope contributors. https://polyscope.run + +namespace polyscope { + +template +TextureMapQuantity::TextureMapQuantity(QuantityT& quantity_, size_t dimX_, size_t dimY_, ImageOrigin origin_) + : quantity(quantity_), dimX(dimX_), dimY(dimY_), imageOrigin(origin_), + filterMode(quantity.uniquePrefix() + "filterMode", FilterMode::Linear) {} + +template +void TextureMapQuantity::buildTextureMapOptionsUI() { + + if (ImGui::BeginMenu("Filter Mode")) { + if (ImGui::MenuItem("linear", NULL, filterMode.get() == FilterMode::Linear)) setFilterMode(FilterMode::Linear); + if (ImGui::MenuItem("nearest", NULL, filterMode.get() == FilterMode::Nearest)) setFilterMode(FilterMode::Nearest); + ImGui::EndMenu(); + } +} + +template +QuantityT* TextureMapQuantity::setFilterMode(FilterMode newFilterMode) { + filterMode = newFilterMode; + quantity.refresh(); + return &quantity; +} + +template +FilterMode TextureMapQuantity::getFilterMode() { + return filterMode.get(); +} + +} // namespace polyscope \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9d03d9675..826051d96 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -336,6 +336,8 @@ SET(HEADERS ${INCLUDE_ROOT}/surface_parameterization_quantity.h ${INCLUDE_ROOT}/surface_scalar_quantity.h ${INCLUDE_ROOT}/surface_vector_quantity.h + ${INCLUDE_ROOT}/texture_map_quantity.h + ${INCLUDE_ROOT}/texture_map_quantity.ipp ${INCLUDE_ROOT}/types.h ${INCLUDE_ROOT}/utilities.h ${INCLUDE_ROOT}/view.h diff --git a/src/surface_color_quantity.cpp b/src/surface_color_quantity.cpp index 16e028291..4a6f1ef3d 100644 --- a/src/surface_color_quantity.cpp +++ b/src/surface_color_quantity.cpp @@ -153,8 +153,8 @@ SurfaceTextureColorQuantity::SurfaceTextureColorQuantity(std::string name, Surfa SurfaceParameterizationQuantity& param_, size_t dimX_, size_t dimY_, std::vector colorValues_, ImageOrigin origin_) - : SurfaceColorQuantity(name, mesh_, "texture", colorValues_), param(param_), dimX(dimX_), dimY(dimY_), - imageOrigin(origin_), filterMode(quantity.uniquePrefix() + "filterMode", FilterMode::Linear) { + : SurfaceColorQuantity(name, mesh_, "texture", colorValues_), TextureMapQuantity(*this, dimX_, dimY_, origin_), + param(param_) { colors.setTextureSize(dimX, dimY); } @@ -195,23 +195,8 @@ void SurfaceTextureColorQuantity::createProgram() { void SurfaceTextureColorQuantity::buildColorOptionsUI() { ColorQuantity::buildColorOptionsUI(); - - if (ImGui::BeginMenu("Filter Mode")) { - if (ImGui::MenuItem("linear", NULL, filterMode.get() == FilterMode::Linear)) setFilterMode(FilterMode::Linear); - if (ImGui::MenuItem("nearest", NULL, filterMode.get() == FilterMode::Nearest)) setFilterMode(FilterMode::Nearest); - ImGui::EndMenu(); - } -} - -SurfaceTextureColorQuantity* SurfaceTextureColorQuantity::setFilterMode(FilterMode newFilterMode) { - filterMode = newFilterMode; - if (program) { - colors.getRenderTextureBuffer()->setFilterMode(filterMode.get()); - } - return this; + buildTextureMapOptionsUI(); } -FilterMode SurfaceTextureColorQuantity::getFilterMode() { return filterMode.get(); } - } // namespace polyscope From 8237674092dd22fe4485faf6fe3c198b02b530ff Mon Sep 17 00:00:00 2001 From: Nicholas Sharp Date: Tue, 24 Dec 2024 16:33:38 -0500 Subject: [PATCH 3/3] templated texture options for scalars too --- include/polyscope/surface_scalar_quantity.h | 8 +++++--- src/surface_scalar_quantity.cpp | 9 ++++++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/include/polyscope/surface_scalar_quantity.h b/include/polyscope/surface_scalar_quantity.h index 3d73c8eb2..80260f114 100644 --- a/include/polyscope/surface_scalar_quantity.h +++ b/include/polyscope/surface_scalar_quantity.h @@ -10,6 +10,7 @@ #include "polyscope/render/engine.h" #include "polyscope/scalar_quantity.h" #include "polyscope/surface_mesh.h" +#include "polyscope/texture_map_quantity.h" namespace polyscope { @@ -25,6 +26,7 @@ class SurfaceScalarQuantity : public SurfaceMeshQuantity, public ScalarQuantity< virtual void draw() override; virtual void buildCustomUI() override; + virtual void buildSurfaceScalarOptionsUI() {}; virtual std::string niceName() override; virtual void refresh() override; @@ -117,20 +119,20 @@ class SurfaceCornerScalarQuantity : public SurfaceScalarQuantity { // ========== Texture Scalar ========== // ======================================================== -class SurfaceTextureScalarQuantity : public SurfaceScalarQuantity { +class SurfaceTextureScalarQuantity : public SurfaceScalarQuantity, + public TextureMapQuantity { public: SurfaceTextureScalarQuantity(std::string name, SurfaceMesh& mesh_, SurfaceParameterizationQuantity& param_, size_t dimX, size_t dimY, const std::vector& values_, ImageOrigin origin_, DataType dataType_ = DataType::STANDARD); virtual void createProgram() override; + virtual void buildSurfaceScalarOptionsUI() override; virtual std::shared_ptr getAttributeBuffer() override; protected: SurfaceParameterizationQuantity& param; - size_t dimX, dimY; - ImageOrigin imageOrigin; }; } // namespace polyscope diff --git a/src/surface_scalar_quantity.cpp b/src/surface_scalar_quantity.cpp index 86ace35e6..cad35b798 100644 --- a/src/surface_scalar_quantity.cpp +++ b/src/surface_scalar_quantity.cpp @@ -41,6 +41,7 @@ void SurfaceScalarQuantity::buildCustomUI() { if (ImGui::BeginPopup("OptionsPopup")) { buildScalarOptionsUI(); + buildSurfaceScalarOptionsUI(); ImGui::EndPopup(); } @@ -293,8 +294,8 @@ SurfaceTextureScalarQuantity::SurfaceTextureScalarQuantity(std::string name, Sur SurfaceParameterizationQuantity& param_, size_t dimX_, size_t dimY_, const std::vector& values_, ImageOrigin origin_, DataType dataType_) - : SurfaceScalarQuantity(name, mesh_, "vertex", values_, dataType_), param(param_), dimX(dimX_), dimY(dimY_), - imageOrigin(origin_) { + : SurfaceScalarQuantity(name, mesh_, "vertex", values_, dataType_), + TextureMapQuantity(*this, dimX_, dimY_, origin_), param(param_) { values.setTextureSize(dimX, dimY); values.ensureHostBufferPopulated(); hist.buildHistogram(values.data); @@ -334,9 +335,11 @@ void SurfaceTextureScalarQuantity::createProgram() { render::engine->setMaterial(*program, parent.getMaterial()); program->setTextureFromColormap("t_colormap", cMap.get()); - values.getRenderTextureBuffer()->setFilterMode(FilterMode::Linear); + values.getRenderTextureBuffer()->setFilterMode(filterMode.get()); } +void SurfaceTextureScalarQuantity::buildSurfaceScalarOptionsUI() { buildTextureMapOptionsUI(); } + std::shared_ptr SurfaceTextureScalarQuantity::getAttributeBuffer() { exception("unsupported operation -- cannot get attribute buffer for texture scalar quantity [" + this->name + "]"); return std::shared_ptr(nullptr);