nmwsharp / polyscope

A C++ & Python viewer for 3D data like meshes and point clouds
https://polyscope.run
MIT License
1.81k stars 196 forks source link

Visualize indexed quantities using a fixed color palette #289

Open jdumas opened 2 months ago

jdumas commented 2 months ago

Hi! I was wondering if there's an easy to visualize discrete scalar attributes (e.g. facet coloring/clustering). It seems that scalar quantities are associated a continuous color map (like Viridis), but I'd like to use a discrete color palette instead (maybe using something from https://colorbrewer2.org?).

nmwsharp commented 2 months ago

There isn't a magic built-in function for this, but it's at the top of my to-implement list :)

I actually started some work for it, there's a shader function here https://github.com/nmwsharp/polyscope/blob/3f52c5ec9adf8fd872d4e1f5cdbaf6f074175f0d/src/render/opengl/shaders/common.cpp#L116-L143 that's used map integer values into distinct discrete values that can be sampled from the colormap. Right now it is only used for distinctly coloring UV map islands, however.

I want to expose this as an option for arbitrary scalar values which happen to be integers, but have not done so yet. There is also another (slightly more-difficult) step needed, to change the interpolation policy e.g. for vertex-valued integers on the mesh, so they get nearest-neighbor interpolated rather than linearly interpolated. That is possible within Polyscope's shaders but not implemented yet.

jdumas commented 2 months ago

Thanks for the quick answer! I think an important feature for discrete colormaps is to have a way to either detect or specify the number of discrete values you want to use in the color palette. I'm not sure you need the intToDistinctReal function though, wouldn't it be enough to resize the colormap texture to have a width = to the number of discrete values you need?

Maybe once you have the nearest-neighbor interpolation, it's mostly a matter of having more helper functions to create custom discrete colormap textures (e.g. load from a 1D array instead of from a file, or create some colorbrewer palettes).