Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 34 additions & 2 deletions include/polyscope/slice_plane.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ class SlicePlane {
const std::string postfix;
std::string uniquePrefix();

// Remove the slice plane from the scene
// (destroys this object, pointer is now invalid)
void remove();

// Set the position and orientation of the plane
// planePosition is any 3D position which the plane touches (the center of the plane)
// planeNormal is a vector giving the normal direction of the plane, objects
Expand All @@ -52,6 +56,10 @@ class SlicePlane {
glm::vec3 getCenter();
glm::vec3 getNormal();

bool getEnabled();
void setEnabled(bool newVal);

// deprecated, should have been called 'enabled'
bool getActive();
void setActive(bool newVal);

Expand All @@ -78,7 +86,7 @@ class SlicePlane {

protected:
// = State
PersistentValue<bool> active; // is it actually slicing?
PersistentValue<bool> enabled; // is it actually slicing?
PersistentValue<bool> drawPlane; // do we draw the plane onscreen?
PersistentValue<bool> drawWidget; // do we draw the widget onscreen?
PersistentValue<glm::mat4> objectTransform;
Expand Down Expand Up @@ -109,10 +117,34 @@ class SlicePlane {
void updateWidgetEnabled();
};

SlicePlane* addSceneSlicePlane(bool initiallyVisible = false);
// Manually specify a name for the slice plane
SlicePlane* addSlicePlane(std::string name);

// Automatically generates a name for the plane like
// "Scene Slice Plane 0", "Scene Slice Plane 1", etc.
SlicePlane* addSlicePlane();

// DEPRECATED: there's on reason to offer this variant, it could be set manually
SlicePlane* addSceneSlicePlane(bool initiallyVisible=false);

// Get a slice plane by name
SlicePlane* getSlicePlane(std::string name);

// Remove a slice plane by name or pointer
void removeSlicePlane(std::string name);
void removeSlicePlane(SlicePlane* plane);

// Remove the last-added slice plane
void removeLastSceneSlicePlane();

// Remove all slice planes
void removeAllSlicePlanes();


// === Internal helpers

void buildSlicePlaneGUI();
void notifySlicePlanesChanged(); // call after adding/remove any slice plane

// flag to open the slice plane menu after adding a slice plane
extern bool openSlicePlaneMenu;
Expand Down
96 changes: 74 additions & 22 deletions src/slice_plane.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,64 @@ namespace polyscope {
// Storage for global options
bool openSlicePlaneMenu = false;

SlicePlane* addSceneSlicePlane(bool initiallyVisible) {
SlicePlane* addSlicePlane(std::string name) {
// check if the name is unique, throw an error if not
for (const std::unique_ptr<SlicePlane>& s : state::slicePlanes) {
if (s->name == name) {
error("Slice plane with name " + name + " already exists");
return nullptr;
}
}

state::slicePlanes.emplace_back(std::unique_ptr<SlicePlane>(new SlicePlane(name)));
SlicePlane* newPlane = state::slicePlanes.back().get();
notifySlicePlanesChanged();
return newPlane;
}

SlicePlane* addSlicePlane() {
size_t nPlanes = state::slicePlanes.size();
std::string newName = "Scene Slice Plane " + std::to_string(nPlanes);
state::slicePlanes.emplace_back(std::unique_ptr<SlicePlane>(new SlicePlane(newName)));
nPlanes++;
SlicePlane* newPlane = state::slicePlanes.back().get();
return addSlicePlane(newName);
}

// DEPRECATED: there's on reason to offer this variant, it could be set manually
SlicePlane* addSceneSlicePlane(bool initiallyVisible) {
SlicePlane* newPlane = addSlicePlane();
if (!initiallyVisible) {
newPlane->setDrawPlane(false);
newPlane->setDrawWidget(false);
}
for (std::unique_ptr<SlicePlane>& s : state::slicePlanes) {
s->resetVolumeSliceProgram();
}
return newPlane;
}

SlicePlane* getSlicePlane(std::string name) {
for (const std::unique_ptr<SlicePlane>& s : state::slicePlanes) {
if (s->name == name) {
return s.get();
}
}
error("No slice plane with name " + name + " exists");
return nullptr;
}

void removeSlicePlane(std::string name) {
for (auto it = state::slicePlanes.begin(); it != state::slicePlanes.end(); it++) {
if ((*it)->name == name) {
state::slicePlanes.erase(it);
notifySlicePlanesChanged();
return;
}
}
warning("No slice plane with name " + name + " exists, cannot remove");
}

void removeSlicePlane(SlicePlane* plane) { removeSlicePlane(plane->name); }

void removeLastSceneSlicePlane() {
if (state::slicePlanes.empty()) return;
state::slicePlanes.pop_back();
for (std::unique_ptr<SlicePlane>& s : state::slicePlanes) {
s->resetVolumeSliceProgram();
}
notifySlicePlanesChanged();
}

void removeAllSlicePlanes() {
Expand All @@ -43,6 +79,13 @@ void removeAllSlicePlanes() {
}
}

void notifySlicePlanesChanged() {
// NSHARP: I've forgotten why this is needed. Perhaps it is not?
for (std::unique_ptr<SlicePlane>& s : state::slicePlanes) {
s->resetVolumeSliceProgram();
}
}

void buildSlicePlaneGUI() {


Expand All @@ -53,7 +96,7 @@ void buildSlicePlaneGUI() {
}
if (ImGui::TreeNode("Slice Planes")) {
if (ImGui::Button("Add plane")) {
addSceneSlicePlane(true);
addSlicePlane();
}
ImGui::SameLine();
if (ImGui::Button("Remove plane")) {
Expand All @@ -68,7 +111,7 @@ void buildSlicePlaneGUI() {


SlicePlane::SlicePlane(std::string name_)
: name(name_), postfix(std::to_string(state::slicePlanes.size())), active(uniquePrefix() + "#active", true),
: name(name_), postfix(std::to_string(state::slicePlanes.size())), enabled(uniquePrefix() + "#enabled", true),
drawPlane(uniquePrefix() + "#drawPlane", true), drawWidget(uniquePrefix() + "#drawWidget", true),
objectTransform(uniquePrefix() + "#object_transform", glm::mat4(1.0)),
color(uniquePrefix() + "#color", getNextUniqueColor()),
Expand All @@ -94,6 +137,11 @@ SlicePlane::~SlicePlane() {

std::string SlicePlane::uniquePrefix() { return "SlicePlane#" + name + "#"; }

void SlicePlane::remove() {
removeSlicePlane(name);
// now invalid! can't do anything else
}

void SlicePlane::prepare() {

planeProgram = render::engine->requestShader("SLICE_PLANE", {}, render::ShaderReplacementDefaults::Process);
Expand Down Expand Up @@ -205,7 +253,7 @@ void SlicePlane::setSliceAttributes(render::ShaderProgram& p) {
}

void SlicePlane::drawGeometry() {
if (!active.get()) return;
if (!enabled.get()) return;

ensureVolumeInspectValid();

Expand Down Expand Up @@ -244,7 +292,7 @@ void SlicePlane::drawGeometry() {


void SlicePlane::draw() {
if (!active.get()) return;
if (!enabled.get()) return;

if (drawPlane.get()) {
// Set uniforms
Expand Down Expand Up @@ -272,8 +320,8 @@ void SlicePlane::draw() {
void SlicePlane::buildGUI() {
ImGui::PushID(name.c_str());

if (ImGui::Checkbox(name.c_str(), &active.get())) {
setActive(getActive());
if (ImGui::Checkbox(name.c_str(), &enabled.get())) {
setEnabled(getEnabled());
}

ImGui::SameLine();
Expand Down Expand Up @@ -355,7 +403,7 @@ void SlicePlane::setSceneObjectUniforms(render::ShaderProgram& p, bool alwaysPas
}

glm::vec3 SlicePlane::getCenter() {
if (active.get()) {
if (enabled.get()) {
glm::vec3 center{objectTransform.get()[3][0], objectTransform.get()[3][1], objectTransform.get()[3][2]};
return center;
} else {
Expand All @@ -365,7 +413,7 @@ glm::vec3 SlicePlane::getCenter() {
}

glm::vec3 SlicePlane::getNormal() {
if (active.get()) {
if (enabled.get()) {
glm::vec3 normal{objectTransform.get()[0][0], objectTransform.get()[0][1], objectTransform.get()[0][2]};
normal = glm::normalize(normal);
return normal;
Expand All @@ -376,10 +424,11 @@ glm::vec3 SlicePlane::getNormal() {
}

void SlicePlane::updateWidgetEnabled() {
bool enabled = getActive() && getDrawWidget();
bool enabled = getEnabled() && getDrawWidget();
transformGizmo.enabled = enabled;
}


void SlicePlane::setPose(glm::vec3 planePosition, glm::vec3 planeNormal) {

// Choose the other axes to be most similar to the current ones, which will make animations look smoother
Expand All @@ -406,13 +455,16 @@ void SlicePlane::setPose(glm::vec3 planePosition, glm::vec3 planeNormal) {
polyscope::requestRedraw();
}

bool SlicePlane::getActive() { return active.get(); }
void SlicePlane::setActive(bool newVal) {
active = newVal;
bool SlicePlane::getEnabled() { return enabled.get(); }
void SlicePlane::setEnabled(bool newVal) {
enabled = newVal;
updateWidgetEnabled();
polyscope::requestRedraw();
}

bool SlicePlane::getActive() { return getEnabled(); }
void SlicePlane::setActive(bool newVal) { return setEnabled(newVal); }

bool SlicePlane::getDrawPlane() { return drawPlane.get(); }
void SlicePlane::setDrawPlane(bool newVal) {
drawPlane = newVal;
Expand Down
2 changes: 1 addition & 1 deletion src/structure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ void Structure::buildUI() {
// if there are none, show a helpful message
if (ImGui::Button("Add slice plane")) {
openSlicePlaneMenu = true;
addSceneSlicePlane(true);
addSlicePlane();
}
} else {
// otherwise, show toggles for each
Expand Down
4 changes: 2 additions & 2 deletions test/src/combo_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ TEST_F(PolyscopeTest, SlicePlaneTest) {
polyscope::show(3);

// render with one slice plane
polyscope::addSceneSlicePlane();
polyscope::addSlicePlane();
polyscope::show(3);

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

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

Expand Down
18 changes: 9 additions & 9 deletions test/src/floating_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ TEST_F(PolyscopeTest, FloatingRenderImageTest) {
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));

// add a slice plane
polyscope::addSceneSlicePlane();
polyscope::addSlicePlane();
polyscope::show(3);
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));
polyscope::removeLastSceneSlicePlane();
Expand All @@ -120,7 +120,7 @@ TEST_F(PolyscopeTest, FloatingRenderImageTest) {
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));

// add a slice plane
polyscope::addSceneSlicePlane();
polyscope::addSlicePlane();
polyscope::show(3);
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));
polyscope::removeLastSceneSlicePlane();
Expand All @@ -135,7 +135,7 @@ TEST_F(PolyscopeTest, FloatingRenderImageTest) {
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));

// add a slice plane
polyscope::addSceneSlicePlane();
polyscope::addSlicePlane();
polyscope::show(3);
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));
polyscope::removeLastSceneSlicePlane();
Expand All @@ -149,7 +149,7 @@ TEST_F(PolyscopeTest, FloatingRenderImageTest) {
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));

// add a slice plane
polyscope::addSceneSlicePlane();
polyscope::addSlicePlane();
polyscope::show(3);
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));
polyscope::removeLastSceneSlicePlane();
Expand All @@ -164,7 +164,7 @@ TEST_F(PolyscopeTest, FloatingRenderImageTest) {
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));

// add a slice plane
polyscope::addSceneSlicePlane();
polyscope::addSlicePlane();
polyscope::show(3);
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));
polyscope::removeLastSceneSlicePlane();
Expand All @@ -178,7 +178,7 @@ TEST_F(PolyscopeTest, FloatingRenderImageTest) {
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));

// add a slice plane
polyscope::addSceneSlicePlane();
polyscope::addSlicePlane();
polyscope::show(3);
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));
polyscope::removeLastSceneSlicePlane();
Expand All @@ -194,7 +194,7 @@ TEST_F(PolyscopeTest, FloatingRenderImageTest) {
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));

// add a slice plane
polyscope::addSceneSlicePlane();
polyscope::addSlicePlane();
polyscope::show(3);
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));
polyscope::removeLastSceneSlicePlane();
Expand All @@ -209,7 +209,7 @@ TEST_F(PolyscopeTest, FloatingRenderImageTest) {
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));

// add a slice plane
polyscope::addSceneSlicePlane();
polyscope::addSlicePlane();
polyscope::show(3);
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));
polyscope::removeLastSceneSlicePlane();
Expand All @@ -226,7 +226,7 @@ TEST_F(PolyscopeTest, FloatingRenderImageTest) {
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));

// add a slice plane
polyscope::addSceneSlicePlane();
polyscope::addSlicePlane();
polyscope::show(3);
polyscope::pickAtScreenCoords(glm::vec2(0.3, 0.8));

Expand Down
Loading