@@ -13,28 +13,64 @@ namespace polyscope {
1313// Storage for global options
1414bool 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+
3270void 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
4076void 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+
4689void 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
70113SlicePlane::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
95138std::string SlicePlane::uniquePrefix() { return " SlicePlane#" + name + " #" ; }
96139
140+ void SlicePlane::remove() {
141+ removeSlicePlane(name);
142+ // now invalid! can't do anything else
143+ }
144+
97145void 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
207255void 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
246294void 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() {
272320void 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
357405glm::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
367415glm::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
378426void SlicePlane::updateWidgetEnabled() {
379- bool enabled = getActive () && getDrawWidget();
427+ bool enabled = getEnabled () && getDrawWidget();
380428 transformGizmo.enabled = enabled;
381429}
382430
431+
383432void 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+
416468bool SlicePlane::getDrawPlane() { return drawPlane.get(); }
417469void SlicePlane::setDrawPlane(bool newVal) {
418470 drawPlane = newVal;
0 commit comments