Skip to content

Commit

Permalink
implement SimpleTriangleMesh structure, make gl buffers resizable (#241)
Browse files Browse the repository at this point in the history
* initial implementation of SimpleTriangleMesh, clean up some buffers and rules

* implement resizable render attribute buffers

* clean up attribute buffer accessors to use templates internally

* resizable buffers for simple triangle mesh

* fix bad size check
  • Loading branch information
nmwsharp authored Nov 2, 2023
1 parent 2be9e09 commit 2cd38b7
Show file tree
Hide file tree
Showing 23 changed files with 1,065 additions and 733 deletions.
9 changes: 7 additions & 2 deletions examples/demo-app/demo_app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "polyscope/pick.h"
#include "polyscope/point_cloud.h"
#include "polyscope/render/managed_buffer.h"
#include "polyscope/simple_triangle_mesh.h"
#include "polyscope/surface_mesh.h"
#include "polyscope/types.h"
#include "polyscope/view.h"
Expand Down Expand Up @@ -103,6 +104,8 @@ void processFileOBJ(std::string filename) {
}
auto psMesh = polyscope::registerSurfaceMesh(niceName, vertexPositionsGLM, faceIndices);

auto psSimpleMesh = polyscope::registerSimpleTriangleMesh(niceName, vertexPositionsGLM, faceIndices);

// Useful data
size_t nVertices = psMesh->nVertices();
size_t nFaces = psMesh->nFaces();
Expand Down Expand Up @@ -477,10 +480,12 @@ void addVolumeGrid() {
return (glm::length(q) - t.y) * scale;
};

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

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

Expand Down
39 changes: 11 additions & 28 deletions include/polyscope/render/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ enum class RenderDataType {
Float,
Int,
UInt,
Index,
Vector2UInt,
Vector3UInt,
Vector4UInt
Expand Down Expand Up @@ -100,7 +99,7 @@ class AttributeBuffer {
int64_t getDataSize() const { return dataSize; }
int64_t getDataSizeInBytes() const { return dataSize * sizeInBytes(dataType) * getArrayCount(); }
uint64_t getUniqueID() const { return uniqueID; }
bool isSet() const { return dataSize > 0; }
bool isSet() const { return setFlag; }

// get data at a single index from the buffer
virtual float getData_float(size_t ind) = 0;
Expand Down Expand Up @@ -129,7 +128,10 @@ class AttributeBuffer {
protected:
RenderDataType dataType;
int arrayCount;
int64_t dataSize = -1; // the size of the data currently stored in this attribute (-1 if nothing)
bool setFlag = false;
int64_t dataSize = -1; // the size of the data currently stored in this attribute (-1 if nothing)
// this counts # elements of the specified type, s.t. array'd mulitpliers are still just one
uint64_t bufferSize = 0; // the size of the allocated buffer (which might be larger than the data sixze)
uint64_t uniqueID;
};

Expand Down Expand Up @@ -382,11 +384,6 @@ class ShaderProgram {
virtual void setAttribute(std::string name, const std::vector<uint32_t>& data) = 0;
// clang-format on

// Convenience method to set an array-valued attrbute, such as 'in vec3 vertexVal[3]'. Applies interleaving then
// forwards to the usual setAttribute
template <typename T, unsigned int C>
void setAttribute(std::string name, const std::vector<std::array<T, C>>& data);


// Textures
virtual bool hasTexture(std::string name) = 0;
Expand All @@ -400,9 +397,7 @@ class ShaderProgram {


// Indices
virtual void setIndex(std::vector<std::array<unsigned int, 3>>& indices) = 0;
virtual void setIndex(std::vector<unsigned int>& indices) = 0;
virtual void setIndex(std::vector<glm::uvec3>& indices) = 0;
virtual void setIndex(std::shared_ptr<AttributeBuffer> externalBuffer) = 0;
virtual void setPrimitiveRestartIndex(unsigned int restartIndex) = 0;

// Indices
Expand All @@ -425,14 +420,17 @@ class ShaderProgram {
// How much data is there to draw
uint32_t drawDataLength;

// Does this program use indexed drawing?
// Indexed drawing
bool useIndex = false;
long int indexSize = -1;
uint32_t indexSizeMult = -1;
bool usePrimitiveRestart = false;
bool primitiveRestartIndexSet = false;
unsigned int restartIndex = -1;

uint64_t uniqueID;

std::shared_ptr<AttributeBuffer> indexBuffer;

// instancing
uint32_t instanceCount = INVALID_IND_32;
};
Expand Down Expand Up @@ -662,21 +660,6 @@ class Engine {
};


// Implementation of template functions
template <typename T, unsigned int C>
inline void ShaderProgram::setAttribute(std::string name, const std::vector<std::array<T, C>>& data) {

// Unpack and forward
std::vector<T> entryData;
entryData.reserve(C * data.size());
for (auto& x : data) {
for (size_t i = 0; i < C; i++) {
entryData.push_back(x[i]);
}
}
setAttribute(name, entryData);
}

// === Public API
// Callers should basically only interact via these methods and variables

Expand Down
21 changes: 11 additions & 10 deletions include/polyscope/render/mock_opengl/mock_gl_engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,16 @@ class GLAttributeBuffer : public AttributeBuffer {
private:
void checkType(RenderDataType targetType);
void checkArray(int arrayCount);

// internal implementation helpers
template <typename T>
void setData_helper(const std::vector<T>& data);

template <typename T>
T getData_helper(size_t ind);

template <typename T>
std::vector<T> getDataRange_helper(size_t start, size_t count);
};

class GLTextureBuffer : public TextureBuffer {
Expand Down Expand Up @@ -266,17 +276,8 @@ class GLShaderProgram : public ShaderProgram {
void setAttribute(std::string name, const std::vector<uint32_t>& data) override;
// clang-format on

// Convenience method to set an array-valued attrbute, such as 'in vec3 vertexVal[3]'. Applies interleaving then
// forwards to the usual setAttribute
template <typename T, unsigned int C>
void setAttribute(std::string name, const std::vector<std::array<T, C>>& data, bool update = false, int offset = 0,
int size = -1);


// Indices
void setIndex(std::vector<std::array<unsigned int, 3>>& indices) override;
void setIndex(std::vector<unsigned int>& indices) override;
void setIndex(std::vector<glm::uvec3>& indices) override;
void setIndex(std::shared_ptr<AttributeBuffer> externalBuffer) override;
void setPrimitiveRestartIndex(unsigned int restartIndex) override;

// Indices
Expand Down
22 changes: 12 additions & 10 deletions include/polyscope/render/opengl/gl_engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,17 @@ class GLAttributeBuffer : public AttributeBuffer {
void checkType(RenderDataType targetType);
void checkArray(int arrayCount);
GLenum getTarget();


// internal implementation helpers
template <typename T>
void setData_helper(const std::vector<T>& data);

template <typename T>
T getData_helper(size_t ind);

template <typename T>
std::vector<T> getDataRange_helper(size_t start, size_t count);
};

class GLTextureBuffer : public TextureBuffer {
Expand Down Expand Up @@ -317,17 +328,9 @@ class GLShaderProgram : public ShaderProgram {
void setAttribute(std::string name, const std::vector<uint32_t>& data) override;
// clang-format on

// Convenience method to set an array-valued attrbute, such as 'in vec3 vertexVal[3]'. Applies interleaving then
// forwards to the usual setAttribute
template <typename T, unsigned int C>
void setAttribute(std::string name, const std::vector<std::array<T, C>>& data, bool update = false, int offset = 0,
int size = -1);


// Indices
void setIndex(std::vector<std::array<unsigned int, 3>>& indices) override;
void setIndex(std::vector<unsigned int>& indices) override;
void setIndex(std::vector<glm::uvec3>& indices) override;
void setIndex(std::shared_ptr<AttributeBuffer> externalBuffer) override;
void setPrimitiveRestartIndex(unsigned int restartIndex) override;

// Instancing
Expand Down Expand Up @@ -368,7 +371,6 @@ class GLShaderProgram : public ShaderProgram {
// GL pointers for various useful things
std::shared_ptr<GLCompiledProgram> compiledProgram;
AttributeHandle vaoHandle;
AttributeHandle indexVBO;
};


Expand Down
1 change: 1 addition & 0 deletions include/polyscope/render/opengl/shaders/rules.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ extern const ShaderReplacementRule LIGHT_PASSTHRU;
// all of these generate or modify `vec3 albedoColor` from some other data
extern const ShaderReplacementRule SHADE_BASECOLOR; // constant from u_baseColor
extern const ShaderReplacementRule SHADE_COLOR; // from shadeColor
extern const ShaderReplacementRule SHADECOLOR_FROM_UNIFORM;
extern const ShaderReplacementRule SHADE_COLORMAP_VALUE; // colormapped from shadeValue
extern const ShaderReplacementRule SHADE_COLORMAP_ANGULAR2; // colormapped from angle of shadeValue2
extern const ShaderReplacementRule SHADE_GRID_VALUE2; // generate a two-color grid with lines from shadeValue2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ namespace backend_openGL3_glfw {
extern const ShaderStageSpecification FLEX_MESH_VERT_SHADER;
extern const ShaderStageSpecification FLEX_MESH_FRAG_SHADER;

// Minimal mesh renders
extern const ShaderStageSpecification SIMPLE_MESH_VERT_SHADER;
extern const ShaderStageSpecification SIMPLE_MESH_FRAG_SHADER;

// Rules specific to meshes
extern const ShaderReplacementRule MESH_WIREFRAME_FROM_BARY;
extern const ShaderReplacementRule MESH_WIREFRAME;
Expand Down
134 changes: 134 additions & 0 deletions include/polyscope/simple_triangle_mesh.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
// Copyright 2017-2023, Nicholas Sharp and the Polyscope contributors. https://polyscope.run

#pragma once

#include "polyscope/color_management.h"
#include "polyscope/persistent_value.h"
#include "polyscope/polyscope.h"
#include "polyscope/render/engine.h"
#include "polyscope/render/managed_buffer.h"
#include "polyscope/scaled_value.h"
#include "polyscope/structure.h"

#include <vector>

namespace polyscope {

// Forward declare simple triangle mesh
class SimpleTriangleMesh;

// Forward declare quantity types

// template <> // Specialize the quantity type
// struct QuantityTypeHelper<SimpleTriangleMesh> {
// typedef SimpleTriangleMeshQuantity type;
// };

class SimpleTriangleMesh : public QuantityStructure<SimpleTriangleMesh> {
public:
// === Member functions ===

// Construct a new simple triangle mesh structure
SimpleTriangleMesh(std::string name, std::vector<glm::vec3> vertices, std::vector<glm::uvec3> faces);

// === Overrides

// Build the imgui display
virtual void buildCustomUI() override;
virtual void buildCustomOptionsUI() override;
virtual void buildPickUI(size_t localPickID) override;

// Standard structure overrides
virtual void draw() override;
virtual void drawDelayed() override;
virtual void drawPick() override;
virtual void updateObjectSpaceBounds() override;
virtual std::string typeName() override;
virtual void refresh() override;

// === Geometry members
render::ManagedBuffer<glm::vec3> vertices;
render::ManagedBuffer<glm::uvec3> faces;

// === Quantities

// === Mutate

template <class V>
void updateVertices(const V& newPositions);

template <class V, class F>
void update(const V& newVertices, const F& newFaces);

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

// === Get/set visualization parameters

// set the base color of the surface
SimpleTriangleMesh* setSurfaceColor(glm::vec3 newVal);
glm::vec3 getSurfaceColor();

// Material
SimpleTriangleMesh* setMaterial(std::string name);
std::string getMaterial();

// Backface color
SimpleTriangleMesh* setBackFaceColor(glm::vec3 val);
glm::vec3 getBackFaceColor();

// Backface policy
SimpleTriangleMesh* setBackFacePolicy(BackFacePolicy newPolicy);
BackFacePolicy getBackFacePolicy();

// Rendering helpers used by quantities
void setSimpleTriangleMeshUniforms(render::ShaderProgram& p, bool withSurfaceShade = true);
void setSimpleTriangleMeshProgramGeometryAttributes(render::ShaderProgram& p);
std::vector<std::string> addSimpleTriangleMeshRules(std::vector<std::string> initRules, bool withSurfaceShade = true);

// === ~DANGER~ experimental/unsupported functions


private:
// Storage for the managed buffers above. You should generally interact with this directly through them.
std::vector<glm::vec3> verticesData;
std::vector<glm::uvec3> facesData;

// === Visualization parameters
PersistentValue<glm::vec3> surfaceColor;
PersistentValue<std::string> material;
PersistentValue<BackFacePolicy> backFacePolicy;
PersistentValue<glm::vec3> backFaceColor;

// Drawing related things
// if nullptr, prepare() (resp. preparePick()) needs to be called
std::shared_ptr<render::ShaderProgram> program;
std::shared_ptr<render::ShaderProgram> pickProgram;

// === Helpers
// Do setup work related to drawing, including allocating openGL data
void ensureRenderProgramPrepared();
void ensurePickProgramPrepared();
void setPickUniforms(render::ShaderProgram& p);

// === Quantity adder implementations

// == Picking related things
size_t pickStart;
glm::vec3 pickColor;
};


// Shorthand to add a simple triangle mesh to polyscope
template <class V, class F>
SimpleTriangleMesh* registerSimpleTriangleMesh(std::string name, const V& vertices, const F& faces);

// Shorthand to get a simple triangle mesh from polyscope
inline SimpleTriangleMesh* getSimpleTriangleMesh(std::string name = "");
inline bool hasSimpleTriangleMesh(std::string name = "");
inline void removeSimpleTriangleMesh(std::string name = "", bool errorIfAbsent = false);


} // namespace polyscope

#include "polyscope/simple_triangle_mesh.ipp"
Loading

0 comments on commit 2cd38b7

Please sign in to comment.