Skip to content

Commit b48cc3a

Browse files
committed
add per-element depth for meshes and point clouds
1 parent 7ca5e0e commit b48cc3a

File tree

15 files changed

+335
-10
lines changed

15 files changed

+335
-10
lines changed

include/polyscope/point_cloud.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,13 @@ class PointCloud : public QuantityStructure<PointCloud> {
102102
void setPointRadiusQuantity(std::string name, bool autoScale = true);
103103
void clearPointRadiusQuantity();
104104

105+
// === Set transparency alpha from a scalar quantity
106+
// effect is multiplicative with other transparency values
107+
// values are clamped to [0,1]
108+
void setTransparencyQuantity(PointCloudScalarQuantity* quantity);
109+
void setTransparencyQuantity(std::string name);
110+
void clearTransparencyQuantity();
111+
105112
// The points that make up this point cloud
106113
// Normally, the values are stored here. But if the render buffer
107114
// is being manually updated, they will live only in the render buffer
@@ -174,9 +181,16 @@ class PointCloud : public QuantityStructure<PointCloud> {
174181

175182
// Manage varying point size
176183
// which (scalar) quantity to set point size from
184+
// TODO make these PersistentValue<>?
177185
std::string pointRadiusQuantityName = ""; // empty string means none
178186
bool pointRadiusQuantityAutoscale = true;
179187
PointCloudScalarQuantity& resolvePointRadiusQuantity(); // helper
188+
189+
// Manage per-element transparency
190+
// which (scalar) quantity to set point size from
191+
// TODO make these PersistentValue<>?
192+
std::string transparencyQuantityName = ""; // empty string means none
193+
PointCloudScalarQuantity& resolveTransparencyQuantity(); // helper
180194
};
181195

182196

include/polyscope/render/opengl/shaders/sphere_shaders.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ extern const ShaderStageSpecification FLEX_POINTQUAD_FRAG_SHADER;
1919

2020
// Rules specific to spheres
2121
extern const ShaderReplacementRule SPHERE_PROPAGATE_VALUE;
22+
extern const ShaderReplacementRule SPHERE_PROPAGATE_VALUEALPHA;
2223
extern const ShaderReplacementRule SPHERE_PROPAGATE_VALUE2;
2324
extern const ShaderReplacementRule SPHERE_PROPAGATE_COLOR;
2425
extern const ShaderReplacementRule SPHERE_VARIABLE_SIZE;

include/polyscope/render/opengl/shaders/surface_mesh_shaders.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ extern const ShaderReplacementRule MESH_BACKFACE_NORMAL_FLIP;
2424
extern const ShaderReplacementRule MESH_BACKFACE_DIFFERENT;
2525
extern const ShaderReplacementRule MESH_BACKFACE_DARKEN;
2626
extern const ShaderReplacementRule MESH_PROPAGATE_VALUE;
27+
extern const ShaderReplacementRule MESH_PROPAGATE_VALUEALPHA;
2728
extern const ShaderReplacementRule MESH_PROPAGATE_FLAT_VALUE;
2829
extern const ShaderReplacementRule MESH_PROPAGATE_INT;
2930
extern const ShaderReplacementRule MESH_PROPAGATE_VALUE2;

include/polyscope/surface_mesh.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ namespace polyscope {
2929
class SurfaceVertexColorQuantity;
3030
class SurfaceFaceColorQuantity;
3131
class SurfaceTextureColorQuantity;
32+
class SurfaceScalarQuantity;
3233
class SurfaceVertexScalarQuantity;
3334
class SurfaceFaceScalarQuantity;
3435
class SurfaceEdgeScalarQuantity;
@@ -176,6 +177,13 @@ class SurfaceMesh : public QuantityStructure<SurfaceMesh> {
176177
template <class V>
177178
void updateVertexPositions2D(const V& newPositions2D);
178179

180+
// === Set transparency alpha from a scalar quantity
181+
// effect is multiplicative with other transparency values
182+
// values are clamped to [0,1]
183+
void setTransparencyQuantity(SurfaceScalarQuantity* quantity);
184+
void setTransparencyQuantity(std::string name);
185+
void clearTransparencyQuantity();
186+
179187

180188
// === Indexing conventions
181189

@@ -376,6 +384,13 @@ class SurfaceMesh : public QuantityStructure<SurfaceMesh> {
376384
void buildHalfedgeInfoGui(size_t heInd);
377385
void buildCornerInfoGui(size_t cInd);
378386

387+
// Manage per-element transparency
388+
// which (scalar) quantity to set point size from
389+
// TODO make these PersistentValue<>?
390+
std::string transparencyQuantityName = ""; // empty string means none
391+
SurfaceScalarQuantity& resolveTransparencyQuantity(); // helper
392+
393+
379394
// ==== Gui implementation details
380395

381396
std::shared_ptr<render::ShaderProgram> program;

include/polyscope/surface_scalar_quantity.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,11 @@ class SurfaceScalarQuantity : public SurfaceMeshQuantity, public ScalarQuantity<
2828
virtual std::string niceName() override;
2929
virtual void refresh() override;
3030

31-
protected:
31+
virtual std::shared_ptr<render::AttributeBuffer> getAttributeBuffer() = 0;
32+
3233
const std::string definedOn;
34+
35+
protected:
3336
std::shared_ptr<render::ShaderProgram> program;
3437

3538
// Helpers
@@ -47,6 +50,8 @@ class SurfaceVertexScalarQuantity : public SurfaceScalarQuantity {
4750

4851
virtual void createProgram() override;
4952

53+
virtual std::shared_ptr<render::AttributeBuffer> getAttributeBuffer() override;
54+
5055
void buildVertexInfoGUI(size_t vInd) override;
5156
};
5257

@@ -61,7 +66,7 @@ class SurfaceFaceScalarQuantity : public SurfaceScalarQuantity {
6166
DataType dataType_ = DataType::STANDARD);
6267

6368
virtual void createProgram() override;
64-
69+
virtual std::shared_ptr<render::AttributeBuffer> getAttributeBuffer() override;
6570
void buildFaceInfoGUI(size_t fInd) override;
6671
};
6772

@@ -76,7 +81,7 @@ class SurfaceEdgeScalarQuantity : public SurfaceScalarQuantity {
7681
DataType dataType_ = DataType::STANDARD);
7782

7883
virtual void createProgram() override;
79-
84+
virtual std::shared_ptr<render::AttributeBuffer> getAttributeBuffer() override;
8085
void buildEdgeInfoGUI(size_t edgeInd) override;
8186
};
8287

@@ -90,7 +95,7 @@ class SurfaceHalfedgeScalarQuantity : public SurfaceScalarQuantity {
9095
DataType dataType_ = DataType::STANDARD);
9196

9297
virtual void createProgram() override;
93-
98+
virtual std::shared_ptr<render::AttributeBuffer> getAttributeBuffer() override;
9499
void buildHalfedgeInfoGUI(size_t heInd) override;
95100
};
96101

@@ -104,7 +109,7 @@ class SurfaceCornerScalarQuantity : public SurfaceScalarQuantity {
104109
DataType dataType_ = DataType::STANDARD);
105110

106111
virtual void createProgram() override;
107-
112+
virtual std::shared_ptr<render::AttributeBuffer> getAttributeBuffer() override;
108113
void buildCornerInfoGUI(size_t heInd) override;
109114
};
110115

@@ -119,6 +124,8 @@ class SurfaceTextureScalarQuantity : public SurfaceScalarQuantity {
119124
DataType dataType_ = DataType::STANDARD);
120125

121126
virtual void createProgram() override;
127+
virtual std::shared_ptr<render::AttributeBuffer> getAttributeBuffer() override;
128+
122129

123130
protected:
124131
SurfaceParameterizationQuantity& param;

src/point_cloud.cpp

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,10 @@ void PointCloud::setPointProgramGeometryAttributes(render::ShaderProgram& p) {
185185
PointCloudScalarQuantity& radQ = resolvePointRadiusQuantity();
186186
p.setAttribute("a_pointRadius", radQ.values.getRenderAttributeBuffer());
187187
}
188+
if (transparencyQuantityName != "") {
189+
PointCloudScalarQuantity& transparencyQ = resolveTransparencyQuantity();
190+
p.setAttribute("a_valueAlpha", transparencyQ.values.getRenderAttributeBuffer());
191+
}
188192
}
189193

190194
std::string PointCloud::getShaderNameForRenderMode() {
@@ -212,6 +216,9 @@ std::vector<std::string> PointCloud::addPointCloudRules(std::vector<std::string>
212216
else if (getPointRenderMode() == PointRenderMode::Quad)
213217
initRules.push_back("SPHERE_CULLPOS_FROM_CENTER_QUAD");
214218
}
219+
if (transparencyQuantityName != "") {
220+
initRules.push_back("SPHERE_PROPAGATE_VALUEALPHA");
221+
}
215222
}
216223
return initRules;
217224
}
@@ -268,6 +275,11 @@ void PointCloud::buildCustomUI() {
268275
}
269276

270277
void PointCloud::buildCustomOptionsUI() {
278+
if (render::buildMaterialOptionsGui(material.get())) {
279+
material.manuallyChanged();
280+
setMaterial(material.get()); // trigger the other updates that happen on set()
281+
}
282+
271283
if (ImGui::BeginMenu("Point Render Mode")) {
272284

273285
for (const PointRenderMode& m : {PointRenderMode::Sphere, PointRenderMode::Quad}) {
@@ -305,9 +317,21 @@ void PointCloud::buildCustomOptionsUI() {
305317
ImGui::EndMenu();
306318
}
307319

308-
if (render::buildMaterialOptionsGui(material.get())) {
309-
material.manuallyChanged();
310-
setMaterial(material.get()); // trigger the other updates that happen on set()
320+
// transparency quantity
321+
if (ImGui::BeginMenu("Per-Point Transparency")) {
322+
323+
if (ImGui::MenuItem("none", nullptr, transparencyQuantityName == "")) clearTransparencyQuantity();
324+
ImGui::Separator();
325+
326+
for (auto& q : quantities) {
327+
PointCloudScalarQuantity* scalarQ = dynamic_cast<PointCloudScalarQuantity*>(q.second.get());
328+
if (scalarQ != nullptr) {
329+
if (ImGui::MenuItem(scalarQ->name.c_str(), nullptr, transparencyQuantityName == scalarQ->name))
330+
setTransparencyQuantity(scalarQ);
331+
}
332+
}
333+
334+
ImGui::EndMenu();
311335
}
312336
}
313337

@@ -362,6 +386,42 @@ void PointCloud::clearPointRadiusQuantity() {
362386
refresh();
363387
}
364388

389+
void PointCloud::setTransparencyQuantity(PointCloudScalarQuantity* quantity) {
390+
setTransparencyQuantity(quantity->name);
391+
}
392+
393+
void PointCloud::setTransparencyQuantity(std::string name) {
394+
transparencyQuantityName = name;
395+
resolveTransparencyQuantity(); // do it once, just so we fail fast if it doesn't exist
396+
397+
// if transparency is disabled, enable it
398+
if (options::transparencyMode == TransparencyMode::None) {
399+
options::transparencyMode = TransparencyMode::Pretty;
400+
}
401+
402+
refresh();
403+
}
404+
405+
void PointCloud::clearTransparencyQuantity() {
406+
transparencyQuantityName = "";
407+
refresh();
408+
}
409+
410+
PointCloudScalarQuantity& PointCloud::resolveTransparencyQuantity() {
411+
PointCloudScalarQuantity* transparencyScalarQ = nullptr;
412+
PointCloudQuantity* anyQ = getQuantity(transparencyQuantityName);
413+
if (anyQ != nullptr) {
414+
transparencyScalarQ = dynamic_cast<PointCloudScalarQuantity*>(anyQ);
415+
if (transparencyScalarQ == nullptr) {
416+
exception("Cannot populate per-element transparency from quantity [" + name + "], it is not a scalar quantity");
417+
}
418+
} else {
419+
exception("Cannot populate per-element transparency from quantity [" + name + "], it does not exist");
420+
}
421+
422+
return *transparencyScalarQ;
423+
}
424+
365425
// === Quantities
366426

367427
// Quantity default methods

src/render/mock_opengl/mock_gl_engine.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1981,6 +1981,7 @@ void MockGLEngine::populateDefaultShadersAndRules() {
19811981
registerShaderRule("MESH_BACKFACE_DIFFERENT", MESH_BACKFACE_DIFFERENT);
19821982
registerShaderRule("MESH_BACKFACE_DARKEN", MESH_BACKFACE_DARKEN);
19831983
registerShaderRule("MESH_PROPAGATE_VALUE", MESH_PROPAGATE_VALUE);
1984+
registerShaderRule("MESH_PROPAGATE_VALUEALPHA", MESH_PROPAGATE_VALUEALPHA);
19841985
registerShaderRule("MESH_PROPAGATE_FLAT_VALUE", MESH_PROPAGATE_FLAT_VALUE);
19851986
registerShaderRule("MESH_PROPAGATE_VALUE2", MESH_PROPAGATE_VALUE2);
19861987
registerShaderRule("MESH_PROPAGATE_TCOORD", MESH_PROPAGATE_TCOORD);
@@ -2000,6 +2001,7 @@ void MockGLEngine::populateDefaultShadersAndRules() {
20002001

20012002
// sphere things
20022003
registerShaderRule("SPHERE_PROPAGATE_VALUE", SPHERE_PROPAGATE_VALUE);
2004+
registerShaderRule("SPHERE_PROPAGATE_VALUEALPHA", SPHERE_PROPAGATE_VALUEALPHA);
20032005
registerShaderRule("SPHERE_PROPAGATE_VALUE2", SPHERE_PROPAGATE_VALUE2);
20042006
registerShaderRule("SPHERE_PROPAGATE_COLOR", SPHERE_PROPAGATE_COLOR);
20052007
registerShaderRule("SPHERE_CULLPOS_FROM_CENTER", SPHERE_CULLPOS_FROM_CENTER);

src/render/opengl/gl_engine.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2540,6 +2540,7 @@ void GLEngine::populateDefaultShadersAndRules() {
25402540
registerShaderRule("MESH_BACKFACE_DIFFERENT", MESH_BACKFACE_DIFFERENT);
25412541
registerShaderRule("MESH_BACKFACE_DARKEN", MESH_BACKFACE_DARKEN);
25422542
registerShaderRule("MESH_PROPAGATE_VALUE", MESH_PROPAGATE_VALUE);
2543+
registerShaderRule("MESH_PROPAGATE_VALUEALPHA", MESH_PROPAGATE_VALUEALPHA);
25432544
registerShaderRule("MESH_PROPAGATE_FLAT_VALUE", MESH_PROPAGATE_FLAT_VALUE);
25442545
registerShaderRule("MESH_PROPAGATE_VALUE2", MESH_PROPAGATE_VALUE2);
25452546
registerShaderRule("MESH_PROPAGATE_TCOORD", MESH_PROPAGATE_TCOORD);
@@ -2559,6 +2560,7 @@ void GLEngine::populateDefaultShadersAndRules() {
25592560

25602561
// sphere things
25612562
registerShaderRule("SPHERE_PROPAGATE_VALUE", SPHERE_PROPAGATE_VALUE);
2563+
registerShaderRule("SPHERE_PROPAGATE_VALUEALPHA", SPHERE_PROPAGATE_VALUEALPHA);
25622564
registerShaderRule("SPHERE_PROPAGATE_VALUE2", SPHERE_PROPAGATE_VALUE2);
25632565
registerShaderRule("SPHERE_PROPAGATE_COLOR", SPHERE_PROPAGATE_COLOR);
25642566
registerShaderRule("SPHERE_CULLPOS_FROM_CENTER", SPHERE_CULLPOS_FROM_CENTER);

src/render/opengl/shaders/lighting_shaders.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ const ShaderReplacementRule TRANSPARENCY_STRUCTURE (
238238
uniform float u_transparency;
239239
)"},
240240
{"GENERATE_ALPHA", R"(
241-
alphaOut = u_transparency;
241+
alphaOut *= u_transparency;
242242
)"},
243243
},
244244
/* uniforms */ {
@@ -257,7 +257,7 @@ const ShaderReplacementRule TRANSPARENCY_PEEL_STRUCTURE (
257257
uniform vec2 u_viewportDim;
258258
)"},
259259
{"GENERATE_ALPHA", R"(
260-
alphaOut = u_transparency;
260+
alphaOut *= u_transparency;
261261
)"},
262262
{"GLOBAL_FRAGMENT_FILTER", R"(
263263
// assumption: "float depth" must be already set

src/render/opengl/shaders/sphere_shaders.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,37 @@ const ShaderReplacementRule SPHERE_PROPAGATE_VALUE (
386386
/* textures */ {}
387387
);
388388

389+
const ShaderReplacementRule SPHERE_PROPAGATE_VALUEALPHA (
390+
/* rule name */ "SPHERE_PROPAGATE_VALUEALPHA",
391+
{ /* replacement sources */
392+
{"VERT_DECLARATIONS", R"(
393+
in float a_valueAlpha;
394+
out float a_valueAlphaToGeom;
395+
)"},
396+
{"VERT_ASSIGNMENTS", R"(
397+
a_valueAlphaToGeom = a_valueAlpha;
398+
)"},
399+
{"GEOM_DECLARATIONS", R"(
400+
in float a_valueAlphaToGeom[];
401+
out float a_valueAlphaToFrag;
402+
)"},
403+
{"GEOM_PER_EMIT", R"(
404+
a_valueAlphaToFrag = a_valueAlphaToGeom[0];
405+
)"},
406+
{"FRAG_DECLARATIONS", R"(
407+
in float a_valueAlphaToFrag;
408+
)"},
409+
{"GENERATE_ALPHA", R"(
410+
alphaOut *= clamp(a_valueAlphaToFrag, 0.f, 1.f);
411+
)"},
412+
},
413+
/* uniforms */ {},
414+
/* attributes */ {
415+
{"a_valueAlpha", RenderDataType::Float},
416+
},
417+
/* textures */ {}
418+
);
419+
389420
const ShaderReplacementRule SPHERE_PROPAGATE_VALUE2 (
390421
/* rule name */ "SPHERE_PROPAGATE_VALUE2",
391422
{ /* replacement sources */

0 commit comments

Comments
 (0)