Skip to content

Commit 24ec7e3

Browse files
authored
improve slice plane API, allow custom names (#371)
* improve slice plane API, allow custom names * change slice plane 'active' to 'enabled'
1 parent dc0c7c2 commit 24ec7e3

File tree

7 files changed

+189
-38
lines changed

7 files changed

+189
-38
lines changed

include/polyscope/slice_plane.h

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ class SlicePlane {
4242
const std::string postfix;
4343
std::string uniquePrefix();
4444

45+
// Remove the slice plane from the scene
46+
// (destroys this object, pointer is now invalid)
47+
void remove();
48+
4549
// Set the position and orientation of the plane
4650
// planePosition is any 3D position which the plane touches (the center of the plane)
4751
// planeNormal is a vector giving the normal direction of the plane, objects
@@ -52,6 +56,10 @@ class SlicePlane {
5256
glm::vec3 getCenter();
5357
glm::vec3 getNormal();
5458

59+
bool getEnabled();
60+
void setEnabled(bool newVal);
61+
62+
// deprecated, should have been called 'enabled'
5563
bool getActive();
5664
void setActive(bool newVal);
5765

@@ -78,7 +86,7 @@ class SlicePlane {
7886

7987
protected:
8088
// = State
81-
PersistentValue<bool> active; // is it actually slicing?
89+
PersistentValue<bool> enabled; // is it actually slicing?
8290
PersistentValue<bool> drawPlane; // do we draw the plane onscreen?
8391
PersistentValue<bool> drawWidget; // do we draw the widget onscreen?
8492
PersistentValue<glm::mat4> objectTransform;
@@ -109,10 +117,34 @@ class SlicePlane {
109117
void updateWidgetEnabled();
110118
};
111119

112-
SlicePlane* addSceneSlicePlane(bool initiallyVisible = false);
120+
// Manually specify a name for the slice plane
121+
SlicePlane* addSlicePlane(std::string name);
122+
123+
// Automatically generates a name for the plane like
124+
// "Scene Slice Plane 0", "Scene Slice Plane 1", etc.
125+
SlicePlane* addSlicePlane();
126+
127+
// DEPRECATED: there's on reason to offer this variant, it could be set manually
128+
SlicePlane* addSceneSlicePlane(bool initiallyVisible=false);
129+
130+
// Get a slice plane by name
131+
SlicePlane* getSlicePlane(std::string name);
132+
133+
// Remove a slice plane by name or pointer
134+
void removeSlicePlane(std::string name);
135+
void removeSlicePlane(SlicePlane* plane);
136+
137+
// Remove the last-added slice plane
113138
void removeLastSceneSlicePlane();
139+
140+
// Remove all slice planes
114141
void removeAllSlicePlanes();
142+
143+
144+
// === Internal helpers
145+
115146
void buildSlicePlaneGUI();
147+
void notifySlicePlanesChanged(); // call after adding/remove any slice plane
116148

117149
// flag to open the slice plane menu after adding a slice plane
118150
extern bool openSlicePlaneMenu;

src/slice_plane.cpp

Lines changed: 74 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,28 +13,64 @@ namespace polyscope {
1313
// Storage for global options
1414
bool openSlicePlaneMenu = false;
1515

16-
SlicePlane* addSceneSlicePlane(bool initiallyVisible) {
16+
SlicePlane* addSlicePlane(std::string name) {
17+
// check if the name is unique, throw an error if not
18+
for (const std::unique_ptr<SlicePlane>& s : state::slicePlanes) {
19+
if (s->name == name) {
20+
error("Slice plane with name " + name + " already exists");
21+
return nullptr;
22+
}
23+
}
24+
25+
state::slicePlanes.emplace_back(std::unique_ptr<SlicePlane>(new SlicePlane(name)));
26+
SlicePlane* newPlane = state::slicePlanes.back().get();
27+
notifySlicePlanesChanged();
28+
return newPlane;
29+
}
30+
31+
SlicePlane* addSlicePlane() {
1732
size_t nPlanes = state::slicePlanes.size();
1833
std::string newName = "Scene Slice Plane " + std::to_string(nPlanes);
19-
state::slicePlanes.emplace_back(std::unique_ptr<SlicePlane>(new SlicePlane(newName)));
20-
nPlanes++;
21-
SlicePlane* newPlane = state::slicePlanes.back().get();
34+
return addSlicePlane(newName);
35+
}
36+
37+
// DEPRECATED: there's on reason to offer this variant, it could be set manually
38+
SlicePlane* addSceneSlicePlane(bool initiallyVisible) {
39+
SlicePlane* newPlane = addSlicePlane();
2240
if (!initiallyVisible) {
2341
newPlane->setDrawPlane(false);
2442
newPlane->setDrawWidget(false);
2543
}
26-
for (std::unique_ptr<SlicePlane>& s : state::slicePlanes) {
27-
s->resetVolumeSliceProgram();
28-
}
2944
return newPlane;
3045
}
3146

47+
SlicePlane* getSlicePlane(std::string name) {
48+
for (const std::unique_ptr<SlicePlane>& s : state::slicePlanes) {
49+
if (s->name == name) {
50+
return s.get();
51+
}
52+
}
53+
error("No slice plane with name " + name + " exists");
54+
return nullptr;
55+
}
56+
57+
void removeSlicePlane(std::string name) {
58+
for (auto it = state::slicePlanes.begin(); it != state::slicePlanes.end(); it++) {
59+
if ((*it)->name == name) {
60+
state::slicePlanes.erase(it);
61+
notifySlicePlanesChanged();
62+
return;
63+
}
64+
}
65+
warning("No slice plane with name " + name + " exists, cannot remove");
66+
}
67+
68+
void removeSlicePlane(SlicePlane* plane) { removeSlicePlane(plane->name); }
69+
3270
void removeLastSceneSlicePlane() {
3371
if (state::slicePlanes.empty()) return;
3472
state::slicePlanes.pop_back();
35-
for (std::unique_ptr<SlicePlane>& s : state::slicePlanes) {
36-
s->resetVolumeSliceProgram();
37-
}
73+
notifySlicePlanesChanged();
3874
}
3975

4076
void removeAllSlicePlanes() {
@@ -43,6 +79,13 @@ void removeAllSlicePlanes() {
4379
}
4480
}
4581

82+
void notifySlicePlanesChanged() {
83+
// NSHARP: I've forgotten why this is needed. Perhaps it is not?
84+
for (std::unique_ptr<SlicePlane>& s : state::slicePlanes) {
85+
s->resetVolumeSliceProgram();
86+
}
87+
}
88+
4689
void buildSlicePlaneGUI() {
4790

4891

@@ -53,7 +96,7 @@ void buildSlicePlaneGUI() {
5396
}
5497
if (ImGui::TreeNode("Slice Planes")) {
5598
if (ImGui::Button("Add plane")) {
56-
addSceneSlicePlane(true);
99+
addSlicePlane();
57100
}
58101
ImGui::SameLine();
59102
if (ImGui::Button("Remove plane")) {
@@ -68,7 +111,7 @@ void buildSlicePlaneGUI() {
68111

69112

70113
SlicePlane::SlicePlane(std::string name_)
71-
: name(name_), postfix(std::to_string(state::slicePlanes.size())), active(uniquePrefix() + "#active", true),
114+
: name(name_), postfix(std::to_string(state::slicePlanes.size())), enabled(uniquePrefix() + "#enabled", true),
72115
drawPlane(uniquePrefix() + "#drawPlane", true), drawWidget(uniquePrefix() + "#drawWidget", true),
73116
objectTransform(uniquePrefix() + "#object_transform", glm::mat4(1.0)),
74117
color(uniquePrefix() + "#color", getNextUniqueColor()),
@@ -94,6 +137,11 @@ SlicePlane::~SlicePlane() {
94137
95138
std::string SlicePlane::uniquePrefix() { return "SlicePlane#" + name + "#"; }
96139
140+
void SlicePlane::remove() {
141+
removeSlicePlane(name);
142+
// now invalid! can't do anything else
143+
}
144+
97145
void SlicePlane::prepare() {
98146
99147
planeProgram = render::engine->requestShader("SLICE_PLANE", {}, render::ShaderReplacementDefaults::Process);
@@ -205,7 +253,7 @@ void SlicePlane::setSliceAttributes(render::ShaderProgram& p) {
205253
}
206254
207255
void SlicePlane::drawGeometry() {
208-
if (!active.get()) return;
256+
if (!enabled.get()) return;
209257
210258
ensureVolumeInspectValid();
211259
@@ -244,7 +292,7 @@ void SlicePlane::drawGeometry() {
244292
245293
246294
void SlicePlane::draw() {
247-
if (!active.get()) return;
295+
if (!enabled.get()) return;
248296
249297
if (drawPlane.get()) {
250298
// Set uniforms
@@ -272,8 +320,8 @@ void SlicePlane::draw() {
272320
void SlicePlane::buildGUI() {
273321
ImGui::PushID(name.c_str());
274322
275-
if (ImGui::Checkbox(name.c_str(), &active.get())) {
276-
setActive(getActive());
323+
if (ImGui::Checkbox(name.c_str(), &enabled.get())) {
324+
setEnabled(getEnabled());
277325
}
278326
279327
ImGui::SameLine();
@@ -355,7 +403,7 @@ void SlicePlane::setSceneObjectUniforms(render::ShaderProgram& p, bool alwaysPas
355403
}
356404
357405
glm::vec3 SlicePlane::getCenter() {
358-
if (active.get()) {
406+
if (enabled.get()) {
359407
glm::vec3 center{objectTransform.get()[3][0], objectTransform.get()[3][1], objectTransform.get()[3][2]};
360408
return center;
361409
} else {
@@ -365,7 +413,7 @@ glm::vec3 SlicePlane::getCenter() {
365413
}
366414
367415
glm::vec3 SlicePlane::getNormal() {
368-
if (active.get()) {
416+
if (enabled.get()) {
369417
glm::vec3 normal{objectTransform.get()[0][0], objectTransform.get()[0][1], objectTransform.get()[0][2]};
370418
normal = glm::normalize(normal);
371419
return normal;
@@ -376,10 +424,11 @@ glm::vec3 SlicePlane::getNormal() {
376424
}
377425
378426
void SlicePlane::updateWidgetEnabled() {
379-
bool enabled = getActive() && getDrawWidget();
427+
bool enabled = getEnabled() && getDrawWidget();
380428
transformGizmo.enabled = enabled;
381429
}
382430
431+
383432
void SlicePlane::setPose(glm::vec3 planePosition, glm::vec3 planeNormal) {
384433
385434
// Choose the other axes to be most similar to the current ones, which will make animations look smoother
@@ -406,13 +455,16 @@ void SlicePlane::setPose(glm::vec3 planePosition, glm::vec3 planeNormal) {
406455
polyscope::requestRedraw();
407456
}
408457
409-
bool SlicePlane::getActive() { return active.get(); }
410-
void SlicePlane::setActive(bool newVal) {
411-
active = newVal;
458+
bool SlicePlane::getEnabled() { return enabled.get(); }
459+
void SlicePlane::setEnabled(bool newVal) {
460+
enabled = newVal;
412461
updateWidgetEnabled();
413462
polyscope::requestRedraw();
414463
}
415464
465+
bool SlicePlane::getActive() { return getEnabled(); }
466+
void SlicePlane::setActive(bool newVal) { return setEnabled(newVal); }
467+
416468
bool SlicePlane::getDrawPlane() { return drawPlane.get(); }
417469
void SlicePlane::setDrawPlane(bool newVal) {
418470
drawPlane = newVal;

src/structure.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ void Structure::buildUI() {
9393
// if there are none, show a helpful message
9494
if (ImGui::Button("Add slice plane")) {
9595
openSlicePlaneMenu = true;
96-
addSceneSlicePlane(true);
96+
addSlicePlane();
9797
}
9898
} else {
9999
// otherwise, show toggles for each

test/src/combo_test.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ TEST_F(PolyscopeTest, SlicePlaneTest) {
111111
polyscope::show(3);
112112

113113
// render with one slice plane
114-
polyscope::addSceneSlicePlane();
114+
polyscope::addSlicePlane();
115115
polyscope::show(3);
116116

117117
// try a few variations of point cloud settings
@@ -126,7 +126,7 @@ TEST_F(PolyscopeTest, SlicePlaneTest) {
126126
polyscope::show(3);
127127

128128
// add another and rotate it
129-
polyscope::SlicePlane* p = polyscope::addSceneSlicePlane();
129+
polyscope::SlicePlane* p = polyscope::addSlicePlane();
130130
p->setTransform(glm::translate(p->getTransform(), glm::vec3{-1., 0., 0.}));
131131
polyscope::show(3);
132132

test/src/floating_test.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ TEST_F(PolyscopeTest, FloatingRenderImageTest) {
106106
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));
107107

108108
// add a slice plane
109-
polyscope::addSceneSlicePlane();
109+
polyscope::addSlicePlane();
110110
polyscope::show(3);
111111
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));
112112
polyscope::removeLastSceneSlicePlane();
@@ -120,7 +120,7 @@ TEST_F(PolyscopeTest, FloatingRenderImageTest) {
120120
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));
121121

122122
// add a slice plane
123-
polyscope::addSceneSlicePlane();
123+
polyscope::addSlicePlane();
124124
polyscope::show(3);
125125
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));
126126
polyscope::removeLastSceneSlicePlane();
@@ -135,7 +135,7 @@ TEST_F(PolyscopeTest, FloatingRenderImageTest) {
135135
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));
136136

137137
// add a slice plane
138-
polyscope::addSceneSlicePlane();
138+
polyscope::addSlicePlane();
139139
polyscope::show(3);
140140
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));
141141
polyscope::removeLastSceneSlicePlane();
@@ -149,7 +149,7 @@ TEST_F(PolyscopeTest, FloatingRenderImageTest) {
149149
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));
150150

151151
// add a slice plane
152-
polyscope::addSceneSlicePlane();
152+
polyscope::addSlicePlane();
153153
polyscope::show(3);
154154
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));
155155
polyscope::removeLastSceneSlicePlane();
@@ -164,7 +164,7 @@ TEST_F(PolyscopeTest, FloatingRenderImageTest) {
164164
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));
165165

166166
// add a slice plane
167-
polyscope::addSceneSlicePlane();
167+
polyscope::addSlicePlane();
168168
polyscope::show(3);
169169
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));
170170
polyscope::removeLastSceneSlicePlane();
@@ -178,7 +178,7 @@ TEST_F(PolyscopeTest, FloatingRenderImageTest) {
178178
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));
179179

180180
// add a slice plane
181-
polyscope::addSceneSlicePlane();
181+
polyscope::addSlicePlane();
182182
polyscope::show(3);
183183
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));
184184
polyscope::removeLastSceneSlicePlane();
@@ -194,7 +194,7 @@ TEST_F(PolyscopeTest, FloatingRenderImageTest) {
194194
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));
195195

196196
// add a slice plane
197-
polyscope::addSceneSlicePlane();
197+
polyscope::addSlicePlane();
198198
polyscope::show(3);
199199
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));
200200
polyscope::removeLastSceneSlicePlane();
@@ -209,7 +209,7 @@ TEST_F(PolyscopeTest, FloatingRenderImageTest) {
209209
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));
210210

211211
// add a slice plane
212-
polyscope::addSceneSlicePlane();
212+
polyscope::addSlicePlane();
213213
polyscope::show(3);
214214
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));
215215
polyscope::removeLastSceneSlicePlane();
@@ -226,7 +226,7 @@ TEST_F(PolyscopeTest, FloatingRenderImageTest) {
226226
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));
227227

228228
// add a slice plane
229-
polyscope::addSceneSlicePlane();
229+
polyscope::addSlicePlane();
230230
polyscope::show(3);
231231
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));
232232

0 commit comments

Comments
 (0)