diff --git a/include/polyscope/color_quantity.h b/include/polyscope/color_quantity.h index 63c97d83..e880bb87 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 d42678de..cd20821b 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 fc7dca8f..daa9449f 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 8c66931a..e5eb8349 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 2ba01dd1..d0b5a231 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 { @@ -19,6 +20,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 +42,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 +56,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; }; @@ -62,17 +66,17 @@ 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_); virtual void createProgram() override; + virtual void buildColorOptionsUI() override; protected: SurfaceParameterizationQuantity& param; - size_t dimX, dimY; - ImageOrigin imageOrigin; }; } // namespace polyscope diff --git a/include/polyscope/surface_scalar_quantity.h b/include/polyscope/surface_scalar_quantity.h index 3d73c8eb..80260f11 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/include/polyscope/texture_map_quantity.h b/include/polyscope/texture_map_quantity.h new file mode 100644 index 00000000..43ceb322 --- /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 00000000..66a04323 --- /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/include/polyscope/types.h b/include/polyscope/types.h index 6a85b225..124a5afb 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/CMakeLists.txt b/src/CMakeLists.txt index 9d03d967..826051d9 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/persistent_value.cpp b/src/persistent_value.cpp index c2f46af3..a87d060d 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 ecd2518a..4a6f1ef3 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(); @@ -125,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_) { + : SurfaceColorQuantity(name, mesh_, "texture", colorValues_), TextureMapQuantity(*this, dimX_, dimY_, origin_), + param(param_) { colors.setTextureSize(dimX, dimY); } @@ -162,7 +190,12 @@ 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(); + buildTextureMapOptionsUI(); } diff --git a/src/surface_scalar_quantity.cpp b/src/surface_scalar_quantity.cpp index 86ace35e..cad35b79 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);