Skip to content

Commit

Permalink
add isosurface support to volume grid scalars
Browse files Browse the repository at this point in the history
  • Loading branch information
nmwsharp committed Sep 24, 2023
1 parent 1da5d81 commit b250922
Show file tree
Hide file tree
Showing 14 changed files with 350 additions and 42 deletions.
4 changes: 2 additions & 2 deletions examples/demo-app/demo_app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -477,10 +477,10 @@ void addVolumeGrid() {
return (glm::length(q) - t.y) * scale;
};

polyscope::VolumeGridNodeScalarQuantity* qNode = psGrid->addNodeScalarQuantityFromCallable("torus sdf", torusSDF);
polyscope::VolumeGridNodeScalarQuantity* qNode = psGrid->addNodeScalarQuantityFromCallable("torus sdf node", torusSDF);
qNode->setEnabled(true);

polyscope::VolumeGridCellScalarQuantity* qCell = psGrid->addCellScalarQuantityFromCallable("torus sdf", torusSDF);
polyscope::VolumeGridCellScalarQuantity* qCell = psGrid->addCellScalarQuantityFromCallable("torus sdf cell", torusSDF);
qCell->setEnabled(true);
}

Expand Down
9 changes: 5 additions & 4 deletions include/polyscope/render/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -328,10 +328,11 @@ class ShaderReplacementRule {
std::vector<ShaderSpecTexture> textures;
};
enum class ShaderReplacementDefaults {
SceneObject, // an object in the scene, which gets lit via matcap (etc)
Pick, // rendering to a pick buffer
Process, // postprocessing effects, etc
None // no defaults applied
SceneObject, // an object in the scene, which gets lit via matcap (etc)
SceneObjectNoSlice, // like SceneObject, but omits slice-related rules
Pick, // rendering to a pick buffer
Process, // postprocessing effects, etc
None // no defaults applied
};

// Encapsulate a shader program
Expand Down
27 changes: 16 additions & 11 deletions include/polyscope/volume_grid.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,6 @@ class VolumeGrid : public QuantityStructure<VolumeGrid> {
virtual void buildCustomOptionsUI() override;
virtual void buildPickUI(size_t localPickID) override;

// Field data
glm::uvec3 gridNodeDim;
glm::uvec3 gridCellDim;
glm::vec3 boundMin, boundMax;

// Misc data
static const std::string structureTypeName;

Expand Down Expand Up @@ -96,12 +91,17 @@ class VolumeGrid : public QuantityStructure<VolumeGrid> {

// == Helpers for computing with the grid

// whole grid
uint64_t nNodes() const;
uint64_t nCells() const;
glm::vec3 gridSpacing() const;
glm::vec3 gridSpacingReference() const;
float minGridSpacing() const;
uint64_t nNodes() const; // total number of nodes
uint64_t nCells() const; // total number of cells
glm::vec3 gridSpacing() const; // space between nodes/cells, in world units
glm::vec3 gridSpacingReference() const; // space between nodes/cells, on [0,1]^3
float minGridSpacing() const; // smallest coordinate of gridSpacing()

// Field data
glm::uvec3 getGridNodeDim() const;
glm::uvec3 getGridCellDim() const;
glm::vec3 getBoundMin() const;
glm::vec3 getBoundMax() const;

// nodes
uint64_t flattenNodeIndex(glm::uvec3 inds) const;
Expand Down Expand Up @@ -140,6 +140,11 @@ class VolumeGrid : public QuantityStructure<VolumeGrid> {


private:

// Field data
glm::uvec3 gridNodeDim;
glm::uvec3 gridCellDim;
glm::vec3 boundMin, boundMax;

// === Storage for managed quantities
std::vector<glm::vec3> gridPlaneReferencePositionsData;
Expand Down
7 changes: 7 additions & 0 deletions include/polyscope/volume_grid.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ inline uint64_t VolumeGrid::nCells() const {
return static_cast<uint64_t>(gridCellDim.x) * gridCellDim.y * gridCellDim.z;
}


// Field data
inline glm::uvec3 VolumeGrid::getGridNodeDim() const { return gridNodeDim; }
inline glm::uvec3 VolumeGrid::getGridCellDim() const { return gridCellDim; }
inline glm::vec3 VolumeGrid::getBoundMin() const { return boundMin; }
inline glm::vec3 VolumeGrid::getBoundMax() const { return boundMax; }

inline uint64_t VolumeGrid::flattenNodeIndex(glm::uvec3 inds) const {
return static_cast<uint64_t>(gridNodeDim[1]) * gridNodeDim[2] * inds.x + gridNodeDim[2] * inds.y + inds.z;
}
Expand Down
3 changes: 2 additions & 1 deletion include/polyscope/volume_grid_quantity.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ class VolumeGridQuantity : public QuantityS<VolumeGrid> {
VolumeGridQuantity(std::string name, VolumeGrid& parentStructure, bool dominates = false);
~VolumeGridQuantity(){};

public:
virtual bool isDrawingGridcubes() = 0;

// Build GUI info about this element
virtual void buildNodeInfoGUI(size_t vInd);
virtual void buildCellInfoGUI(size_t vInd);
Expand Down
10 changes: 10 additions & 0 deletions include/polyscope/volume_grid_scalar_quantity.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "polyscope/histogram.h"
#include "polyscope/render/color_maps.h"
#include "polyscope/scalar_quantity.h"
#include "polyscope/surface_mesh.h"
#include "polyscope/volume_grid.h"

namespace polyscope {
Expand All @@ -29,6 +30,8 @@ class VolumeGridNodeScalarQuantity : public VolumeGridQuantity, public ScalarQua

virtual std::string niceName() override;

virtual bool isDrawingGridcubes() override;

// == Getters and setters

// Gridcube viz
Expand All @@ -48,6 +51,10 @@ class VolumeGridNodeScalarQuantity : public VolumeGridQuantity, public ScalarQua
VolumeGridNodeScalarQuantity* setIsosurfaceColor(glm::vec3 val);
glm::vec3 getIsosurfaceColor();

VolumeGridNodeScalarQuantity* setSlicePlanesAffectIsosurface(bool val);
bool getSlicePlanesAffectIsosurface();

SurfaceMesh* registerIsosurfaceAsMesh(std::string structureName = "");

protected:
// Visualize as a grid of cubes
Expand All @@ -60,6 +67,7 @@ class VolumeGridNodeScalarQuantity : public VolumeGridQuantity, public ScalarQua
PersistentValue<bool> isosurfaceVizEnabled;
PersistentValue<float> isosurfaceLevel;
PersistentValue<glm::vec3> isosurfaceColor;
PersistentValue<bool> slicePlanesAffectIsosurface;
std::shared_ptr<render::ShaderProgram> isosurfaceProgram;
void createIsosurfaceProgram();

Expand All @@ -85,6 +93,8 @@ class VolumeGridCellScalarQuantity : public VolumeGridQuantity, public ScalarQua

virtual std::string niceName() override;

virtual bool isDrawingGridcubes() override;

// == Getters and setters

// Gridcube viz
Expand Down
16 changes: 16 additions & 0 deletions src/render/mock_opengl/mock_gl_engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1906,6 +1906,14 @@ std::string MockGLEngine::programKeyFromRules(const std::string& programName, co
for (const std::string& s : defaultRules_sceneObject) builder << s << "# ";
break;
}
case ShaderReplacementDefaults::SceneObjectNoSlice: {
for (const std::string& s : defaultRules_sceneObject) {
if (s.rfind("SLICE_PLANE_", 0) != 0) {
builder << s << "# ";
}
}
break;
}
case ShaderReplacementDefaults::Pick: {
for (const std::string& s : defaultRules_pick) builder << s << "# ";
break;
Expand Down Expand Up @@ -1952,6 +1960,14 @@ std::shared_ptr<GLCompiledProgram> MockGLEngine::getCompiledProgram(const std::s
fullCustomRules.insert(fullCustomRules.begin(), defaultRules_sceneObject.begin(), defaultRules_sceneObject.end());
break;
}
case ShaderReplacementDefaults::SceneObjectNoSlice: {
for (const std::string& rule : defaultRules_sceneObject) {
if (rule.rfind("SLICE_PLANE_", 0) != 0) {
fullCustomRules.insert(fullCustomRules.begin(), rule);
}
}
break;
}
case ShaderReplacementDefaults::Pick: {
fullCustomRules.insert(fullCustomRules.begin(), defaultRules_pick.begin(), defaultRules_pick.end());
break;
Expand Down
17 changes: 17 additions & 0 deletions src/render/opengl/gl_engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2739,6 +2739,14 @@ std::string GLEngine::programKeyFromRules(const std::string& programName, const
for (const std::string& s : defaultRules_sceneObject) builder << s << "# ";
break;
}
case ShaderReplacementDefaults::SceneObjectNoSlice: {
for (const std::string& s : defaultRules_sceneObject) {
if (s.rfind("SLICE_PLANE_", 0) != 0) {
builder << s << "# ";
}
}
break;
}
case ShaderReplacementDefaults::Pick: {
for (const std::string& s : defaultRules_pick) builder << s << "# ";
break;
Expand Down Expand Up @@ -2779,11 +2787,20 @@ std::shared_ptr<GLCompiledProgram> GLEngine::getCompiledProgram(const std::strin

// Add in the default rules
std::vector<std::string> fullCustomRules = customRules;
// TODO this inefficiently inserts at front for no reason
switch (defaults) {
case ShaderReplacementDefaults::SceneObject: {
fullCustomRules.insert(fullCustomRules.begin(), defaultRules_sceneObject.begin(), defaultRules_sceneObject.end());
break;
}
case ShaderReplacementDefaults::SceneObjectNoSlice: {
for (const std::string& rule : defaultRules_sceneObject) {
if (rule.rfind("SLICE_PLANE_", 0) != 0) {
fullCustomRules.insert(fullCustomRules.begin(), rule);
}
}
break;
}
case ShaderReplacementDefaults::Pick: {
fullCustomRules.insert(fullCustomRules.begin(), defaultRules_pick.begin(), defaultRules_pick.end());
break;
Expand Down
6 changes: 5 additions & 1 deletion src/render/opengl/shaders/grid_shaders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,11 @@ const ShaderReplacementRule GRIDCUBE_CULLPOS_FROM_CENTER(
uniform vec3 u_boundMax;
)"},
{"GLOBAL_FRAGMENT_FILTER_PREP", R"(
vec3 cullPosRef = (0.5f + cellInd3f) * u_gridSpacingReference;
// NOTE: you would expect the constant below to be 0.5f, to cull from the center of the cell.
// We intentionally use 0.667 instead and slightly shift it, to avoid common default causes
// where the plane slices right through the center of the cell, and you get random patterns
// of cull/not-cull based on floating point error.
vec3 cullPosRef = (0.667f + cellInd3f) * u_gridSpacingReference;
vec3 cullPosWorld = mix(u_boundMin, u_boundMax, cullPosRef);
vec3 cullPos = (u_modelView * vec4(cullPosWorld, 1.f)).xyz;
Expand Down
19 changes: 16 additions & 3 deletions src/volume_grid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,16 @@ namespace polyscope {
const std::string VolumeGrid::structureTypeName = "Volume Grid";

VolumeGrid::VolumeGrid(std::string name, glm::uvec3 gridNodeDim_, glm::vec3 boundMin_, glm::vec3 boundMax_)
: QuantityStructure<VolumeGrid>(name, typeName()), gridNodeDim(gridNodeDim_), gridCellDim(gridNodeDim_ - 1u),
boundMin(boundMin_), boundMax(boundMax_),
: QuantityStructure<VolumeGrid>(name, typeName()),

// clang-format off
// == managed quantities
gridPlaneReferencePositions(this, uniquePrefix() + "#gridPlaneReferencePositions", gridPlaneReferencePositionsData, std::bind(&VolumeGrid::computeGridPlaneReferenceGeometry, this)),
gridPlaneReferenceNormals(this, uniquePrefix() + "#gridPlaneReferenceNormals", gridPlaneReferenceNormalsData, [](){/* do nothing, gets handled by position func */} ),
gridPlaneAxisInds(this, uniquePrefix() + "#gridPlaneAxisInds", gridPlaneAxisIndsData, [](){/* do nothing, gets handled by position func */} ),
gridNodeDim(gridNodeDim_), gridCellDim(gridNodeDim_ - 1u), boundMin(boundMin_), boundMax(boundMax_),
// == persistent options
color( uniquePrefix() + "color", getNextUniqueColor()),
edgeColor( uniquePrefix() + "edgeColor", glm::vec3{0., 0., 0.}),
Expand Down Expand Up @@ -100,9 +101,13 @@ void VolumeGrid::buildCustomOptionsUI() {
}

void VolumeGrid::draw() {
// For now, do nothing for the actual grid
if (!enabled.get()) return;

// Write now none of this class supports cullWholeElements = false, so just always force it to true
if (!getCullWholeElements()) {
setCullWholeElements(true);
}

// If there is no dominant quantity, then this class is responsible for the grid
if (dominantQuantity == nullptr) {

Expand Down Expand Up @@ -147,6 +152,14 @@ void VolumeGrid::drawPick() {
return;
}

// only draw pick if the grid is actually being draw
if (dominantQuantity != nullptr) {
VolumeGridQuantity* g = dynamic_cast<VolumeGridQuantity*>(dominantQuantity);
if (g && !g->isDrawingGridcubes()) {
return;
}
}

ensureGridCubePickProgramPrepared();

// Set program uniforms
Expand Down
Loading

0 comments on commit b250922

Please sign in to comment.