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
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,6 @@
[submodule "deps/imgui/implot"]
path = deps/imgui/implot
url = https://github.com/epezent/implot
[submodule "deps/imgui/ImGuizmo"]
path = deps/imgui/ImGuizmo
url = https://github.com/CedricGuillemet/ImGuizmo.git
17 changes: 15 additions & 2 deletions deps/imgui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,26 @@ endif()
if("${POLYSCOPE_BACKEND_OPENGL3_GLFW}")

# imgui sources
list(APPEND SRCS imgui/imgui.cpp imgui/imgui_draw.cpp imgui/imgui_tables.cpp imgui/imgui_widgets.cpp imgui/imgui_demo.cpp imgui/backends/imgui_impl_glfw.cpp imgui/backends/imgui_impl_opengl3.cpp)
list(APPEND SRCS
imgui/imgui.cpp
imgui/imgui_draw.cpp
imgui/imgui_tables.cpp
imgui/imgui_widgets.cpp
imgui/imgui_demo.cpp
imgui/backends/imgui_impl_glfw.cpp
imgui/backends/imgui_impl_opengl3.cpp
)

# implot sources
list(APPEND SRCS
implot/implot.cpp
implot/implot_items.cpp
)

# imguizmosources
list(APPEND SRCS
ImGuizmo/ImGuizmo.cpp
)

add_library(
imgui
Expand All @@ -35,7 +48,7 @@ if("${POLYSCOPE_BACKEND_OPENGL3_GLFW}")

target_include_directories(imgui PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/imgui/")
target_include_directories(imgui PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/implot/")
target_include_directories(imgui PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../glfw/include/")
target_include_directories(imgui PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/ImGuizmo/")
target_include_directories(imgui PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../glad/include/")

target_link_libraries(imgui PRIVATE glfw)
Expand Down
1 change: 1 addition & 0 deletions deps/imgui/ImGuizmo
Submodule ImGuizmo added at df1c30
1 change: 1 addition & 0 deletions include/polyscope/color_bar.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class OnscreenColorBarWidget : public Widget {
public:
OnscreenColorBarWidget(ColorBar& parent_);
virtual void draw() override;
std::string uniquePrefix() override;

private:
ColorBar& parent;
Expand Down
11 changes: 11 additions & 0 deletions include/polyscope/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class Structure;
class Group;
class SlicePlane;
class Widget;
class TransformationGizmo;
class FloatingQuantityStructure;
namespace view {
extern const double defaultNearClipRatio;
Expand Down Expand Up @@ -115,6 +116,16 @@ struct Context {

bool pointCloudEfficiencyWarningReported = false;
FloatingQuantityStructure* globalFloatingQuantityStructure = nullptr;

// ======================================================
// === Other various global lists
// ======================================================

// Transformation gizmos that were created by hte user for the secne
// Note: this does _not_ include all gizmos, such as the one which exists
// for each structure. This is just storage for gizmos explicitly created
// like with addTransformationGizmo()
std::vector<std::unique_ptr<TransformationGizmo>> createdTransformationGizmos;
};


Expand Down
1 change: 1 addition & 0 deletions include/polyscope/structure.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ class Structure : public render::ManagedBufferRegistry, public virtual WeakRefer
void translate(glm::vec3 vec); // *adds* vec to the position
glm::mat4x4 getTransform();
glm::vec3 getPosition();
TransformationGizmo& getTransformGizmo();

void setStructureUniforms(render::ShaderProgram& p);
bool wantsCullPosition();
Expand Down
128 changes: 81 additions & 47 deletions include/polyscope/transformation_gizmo.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include "polyscope/utilities.h"
#include "polyscope/widget.h"

#include "ImGuizmo.h"

namespace polyscope {

// A visual widget with handles for translations/rotations
Expand All @@ -16,76 +18,108 @@ class TransformationGizmo : public Widget {
public:
// == Constructors

TransformationGizmo(std::string name, glm::mat4& T, PersistentValue<glm::mat4>* Tpers = nullptr);
// Construct a gizmo.
//
// If T is null, this gizmo owns its transform matrix which can be accessed via set/getTransform().
// If T is non-null, the gizmo will manipulate that external transform. Optionally, a pointer can also be passed to a
// PersistentValue<glm::mat4>, which will be updated as the transform is changed.
//
// Users creating additional gizmos should not call this, use addTransformationGizmo() instead.
TransformationGizmo(std::string name, glm::mat4* T = nullptr, PersistentValue<glm::mat4>* Tpers = nullptr);


// == Key members

// a unique name
const std::string name;

// the main transform encoded by the gizmo
PersistentValue<bool> enabled;
// NOTE: this is only meaningful to call on use-created gizmos from addTransformationGizmo(),
// it will have no effect on gizmos created other ways
// After removing, the object is destructed
void remove();

// the main transform encoded by the gizmo
// note that this is a reference set on construction; the gizmo wraps a transform defined somewhere else
glm::mat4& T;
PersistentValue<glm::mat4>* Tpers; // optional, a persistent value defined elsewhere that goes with T
// == Getters and setters

// == Member functions
glm::mat4 getTransform();
void setTransform(glm::mat4 newT);

void prepare();
void draw() override;
bool interact() override;
// the are helpers which access/update only the position component of the transform
glm::vec3 getPosition();
void setPosition(glm::vec3 newPos);

protected:
enum class TransformHandle { None, Rotation, Translation, Scale };
bool getEnabled();
void setEnabled(bool newVal);

bool getAllowTranslation();
void setAllowTranslation(bool newVal);

// parameters
const float gizmoSizeRel = 0.08;
const float diskWidthObj = 0.1; // in object coordinates, before transformation
const float vecLength = 1.5;
const float sphereRad = 0.32;
const std::string material = "wax";
bool getAllowRotation();
void setAllowRotation(bool newVal);

// state
int selectedDim = -1; // must be {0,1,2} if selectedType == Rotation/Translation
TransformHandle selectedType = TransformHandle::None;
bool currentlyDragging = false;
glm::vec3 dragPrevVec{1., 0.,
0.}; // the normal vector from the previous frame of the drag OR previous translation center
bool getAllowScaling();
void setAllowScaling(bool newVal);

std::array<glm::vec3, 3> niceRGB = {{glm::vec3{211 / 255., 45 / 255., 62 / 255.},
glm::vec3{65 / 255., 121 / 255., 225 / 255.},
glm::vec3{95 / 255., 175 / 255., 35 / 255.}}};
// sadly this is not really supported by ImGuizmo
// bool getUniformScaling();
// void setUniformScaling(bool newVal);

void markUpdated();
bool getInteractInLocalSpace();
void setInteractInLocalSpace(bool newVal);

// Render stuff
std::shared_ptr<render::ShaderProgram> ringProgram;
std::shared_ptr<render::ShaderProgram> arrowProgram;
std::shared_ptr<render::ShaderProgram> sphereProgram;
// Size is relative, with 1.0 as the default size
float getGizmoSize();
void setGizmoSize(float newVal);

// Geometry helpers used to test hits
// == Member functions

// returns <tRay, distNearest, nearestPoint>
std::tuple<float, float, glm::vec3> circleTest(glm::vec3 raySource, glm::vec3 rayDir, glm::vec3 center,
glm::vec3 normal, float radius);
std::tuple<float, float, glm::vec3> lineTest(glm::vec3 raySource, glm::vec3 rayDir, glm::vec3 center,
glm::vec3 tangent, float length);
std::tuple<float, float, glm::vec3> sphereTest(glm::vec3 raySource, glm::vec3 rayDir, glm::vec3 center, float radius,
bool allowHitSurface = true);
std::string uniquePrefix() override;
void draw() override;
bool interact() override;
void buildUI() override;
void buildInlineTransformUI();
void buildMenuItems();
void markUpdated();

protected:
// The main transform encoded by the gizmo
// This can be either a reference to an external wrapped transform, or the internal storage below
glm::mat4& Tref;

std::tuple<std::vector<glm::vec3>, std::vector<glm::vec3>, std::vector<glm::vec3>, std::vector<glm::vec2>,
std::vector<glm::vec3>>
triplePlaneCoords();
// Optional, a persistent value defined elsewhere that goes with T, which
// will be marked as updated when the gizmo changes the transform.
PersistentValue<glm::mat4>* Tpers;

std::tuple<std::vector<glm::vec3>, std::vector<glm::vec3>, std::vector<glm::vec3>, std::vector<glm::vec3>>
tripleArrowCoords();
// Local stoarage for a transformation.
// This may or may not be used; based on the constructor args this class may wrap an external transform, or simply use
// this one.
glm::mat4 Towned = glm::mat4(1.0);

// std::tuple<std::vector<glm::vec3>, std::vector<glm::vec3>> unitCubeCoords();
// options
PersistentValue<bool> enabled;
PersistentValue<bool> allowTranslation;
PersistentValue<bool> allowRotation;
PersistentValue<bool> allowScaling;
// PersistentValue<bool> uniformScaling; // not really supported by the ImGuizmo
PersistentValue<bool> interactInLocalSpace;
PersistentValue<bool> showUIWindow;
PersistentValue<float> gizmoSize;

// internal
bool lastInteractResult = false;
};

// Create a user-defined transformation gizmo in the scene.
// By default, the gizmo maintains its own transformation matrix which
// can be accessed by by .getTransform(). Optionally, it can instead wrap
// and existin transform passed as transformToWrap.
TransformationGizmo* addTransformationGizmo(std::string name = "", glm::mat4* transformToWrap = nullptr);

// Get a user-created transformation gizmo by name
TransformationGizmo* getTransformationGizmo(std::string name);

// Remove a user-created transformation gizmo
void removeTransformationGizmo(TransformationGizmo* gizmo);
void removeTransformationGizmo(std::string name);
void removeAllTransformationGizmos();

} // namespace polyscope
3 changes: 2 additions & 1 deletion include/polyscope/widget.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ class Widget : public virtual WeakReferrable {

virtual void draw();
virtual bool interact(); // returns true if the mouse input was consumed
virtual void buildGUI();
virtual void buildUI();
virtual std::string uniquePrefix() = 0;

}; // namespace polyscope
} // namespace polyscope
4 changes: 4 additions & 0 deletions src/color_bar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,10 @@ void ColorBar::prepareOnscreenColorBar() {

OnscreenColorBarWidget::OnscreenColorBarWidget(ColorBar& parent_) : parent(parent_) {}

std::string OnscreenColorBarWidget::uniquePrefix() {
return "#widget#OnscreenColorBarWidget#" + parent.parent.uniquePrefix();
}

void OnscreenColorBarWidget::draw() {
if (!parent.parent.isEnabled()) return;
if (!parent.getOnscreenColorbarEnabled()) return;
Expand Down
3 changes: 2 additions & 1 deletion src/polyscope.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1032,7 +1032,7 @@ void draw(bool withUI, bool withContextCallback) {
for (WeakHandle<Widget> wHandle : state::widgets) {
if (wHandle.isValid()) {
Widget& w = wHandle.get();
w.buildGUI();
w.buildUI();
}
}
}
Expand Down Expand Up @@ -1171,6 +1171,7 @@ void shutdown(bool allowMidFrameShutdown) {
removeAllStructures();
removeAllGroups();
removeAllSlicePlanes();
removeAllTransformationGizmos();
clearMessages();
state::userCallback = nullptr;
state::filesDroppedCallback = nullptr;
Expand Down
11 changes: 6 additions & 5 deletions src/render/mock_opengl/mock_gl_engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1576,12 +1576,12 @@ void MockGLEngine::initialize() {

void MockGLEngine::initializeImGui() {
ImGui::CreateContext(); // must call once at start
ImPlot::CreateContext();
ImPlot::CreateContext();
configureImGui();
}

void MockGLEngine::configureImGui() {

// don't both calling the style callbacks, there is no UI

if (options::uiScale < 0) {
Expand All @@ -1598,9 +1598,9 @@ void MockGLEngine::shutdown() {
shutdownImGui();
}

void MockGLEngine::shutdownImGui() {
ImPlot::DestroyContext();
ImGui::DestroyContext();
void MockGLEngine::shutdownImGui() {
ImPlot::DestroyContext();
ImGui::DestroyContext();
}

void MockGLEngine::swapDisplayBuffers() {}
Expand Down Expand Up @@ -1675,6 +1675,7 @@ void MockGLEngine::ImGuiNewFrame() {
io.DisplaySize.y = view::bufferHeight;

ImGui::NewFrame();
ImGuizmo::BeginFrame();
}

void MockGLEngine::ImGuiRender() {
Expand Down
1 change: 1 addition & 0 deletions src/render/opengl/gl_engine_egl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,7 @@ void GLEngineEGL::ImGuiNewFrame() {
io.DisplaySize.y = view::bufferHeight;

ImGui::NewFrame();
ImGuizmo::BeginFrame();
}

void GLEngineEGL::ImGuiRender() {
Expand Down
8 changes: 5 additions & 3 deletions src/render/opengl/gl_engine_glfw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

#include "stb_image.h"

#include "ImGuizmo.h"

#include <algorithm>
#include <set>
#include <sstream>
Expand Down Expand Up @@ -82,8 +84,7 @@ void GLEngineGLFW::initialize() {

// Drag & drop support
glfwSetDropCallback(mainWindow, [](GLFWwindow* window, int path_count, const char* paths[]) {
if (!state::filesDroppedCallback)
return;
if (!state::filesDroppedCallback) return;

std::vector<std::string> pathsVec(path_count);
for (int i = 0; i < path_count; i++) {
Expand Down Expand Up @@ -162,7 +163,7 @@ void GLEngineGLFW::initializeImGui() {
bindDisplay();

ImGui::CreateContext(); // must call once at start
ImPlot::CreateContext();
ImPlot::CreateContext();

// Set up ImGUI glfw bindings
ImGui_ImplGlfw_InitForOpenGL(mainWindow, true);
Expand Down Expand Up @@ -220,6 +221,7 @@ void GLEngineGLFW::ImGuiNewFrame() {
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
ImGuizmo::BeginFrame();
}

void GLEngineGLFW::ImGuiRender() {
Expand Down
7 changes: 4 additions & 3 deletions src/slice_plane.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,15 +117,16 @@ SlicePlane::SlicePlane(std::string name_)
color(uniquePrefix() + "#color", getNextUniqueColor()),
gridLineColor(uniquePrefix() + "#gridLineColor", glm::vec3{.97, .97, .97}),
transparency(uniquePrefix() + "#transparency", 0.5), shouldInspectMesh(false), inspectedMeshName(""),
transformGizmo(uniquePrefix() + "#transformGizmo", objectTransform.get(), &objectTransform),
transformGizmo(uniquePrefix() + "#transformGizmo", &objectTransform.get(), &objectTransform),
sliceBufferArr{{{nullptr, uniquePrefix() + "#slice1", sliceBufferDataArr[0]},
{nullptr, uniquePrefix() + "#slice2", sliceBufferDataArr[1]},
{nullptr, uniquePrefix() + "#slice3", sliceBufferDataArr[2]},
{nullptr, uniquePrefix() + "#slice4", sliceBufferDataArr[3]}}}

{
render::engine->addSlicePlane(postfix);
transformGizmo.enabled = true;
transformGizmo.setEnabled(true);
transformGizmo.setInteractInLocalSpace(true);
prepare();
}

Expand Down Expand Up @@ -425,7 +426,7 @@ glm::vec3 SlicePlane::getNormal() {

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


Expand Down
Loading