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
2 changes: 1 addition & 1 deletion deps/polyscope
Submodule polyscope updated 48 files
+1 −0 .gitignore
+1 −1 examples/demo-app/demo_app.cpp
+0 −1 include/polyscope/camera_view.h
+1 −1 include/polyscope/context.h
+18 −0 include/polyscope/internal.h
+7 −0 include/polyscope/options.h
+13 −6 include/polyscope/polyscope.h
+4 −0 include/polyscope/render/engine.h
+2 −0 include/polyscope/render/opengl/shaders/rules.h
+36 −4 include/polyscope/slice_plane.h
+2 −1 include/polyscope/vector_quantity.ipp
+3 −0 include/polyscope/view.h
+4 −2 src/camera_view.cpp
+6 −5 src/color_render_image_quantity.cpp
+8 −3 src/curve_network.cpp
+7 −4 src/depth_render_image_quantity.cpp
+16 −0 src/internal.cpp
+1 −0 src/options.cpp
+3 −0 src/point_cloud.cpp
+29 −31 src/polyscope.cpp
+10 −5 src/raw_color_alpha_render_image_quantity.cpp
+9 −5 src/raw_color_render_image_quantity.cpp
+9 −0 src/render/engine.cpp
+1 −1 src/render/ground_plane.cpp
+2 −0 src/render/mock_opengl/mock_gl_engine.cpp
+2 −0 src/render/opengl/gl_engine.cpp
+16 −2 src/render/opengl/gl_engine_glfw.cpp
+37 −0 src/render/opengl/shaders/common.cpp
+3 −3 src/render/opengl/shaders/cylinder_shaders.cpp
+35 −0 src/render/opengl/shaders/rules.cpp
+9 −5 src/render/opengl/shaders/sphere_shaders.cpp
+6 −6 src/render/opengl/shaders/texture_draw_shaders.cpp
+4 −4 src/render/opengl/shaders/vector_shaders.cpp
+7 −3 src/render_image_quantity_base.cpp
+5 −4 src/scalar_render_image_quantity.cpp
+74 −22 src/slice_plane.cpp
+5 −1 src/state.cpp
+1 −1 src/structure.cpp
+2 −0 src/transformation_gizmo.cpp
+25 −4 src/view.cpp
+19 −0 test/src/camera_view_test.cpp
+2 −2 test/src/combo_test.cpp
+15 −0 test/src/curve_network_test.cpp
+69 −7 test/src/floating_test.cpp
+67 −0 test/src/misc_test.cpp
+26 −0 test/src/point_cloud_test.cpp
+18 −0 test/src/volume_grid_test.cpp
+7 −2 test/src/volume_mesh_test.cpp
5 changes: 5 additions & 0 deletions src/cpp/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "polyscope/affine_remapper.h"
#include "polyscope/camera_parameters.h"
#include "polyscope/curve_network.h"
#include "polyscope/imgui_config.h"
#include "polyscope/messages.h"
#include "polyscope/pick.h"
#include "polyscope/point_cloud.h"
Expand Down Expand Up @@ -143,6 +144,10 @@ PYBIND11_MODULE(polyscope_bindings, m) {
m.def("set_hide_window_after_show", [](bool x) { ps::options::hideWindowAfterShow = x; });
m.def("set_warn_for_invalid_values", [](bool x) { ps::options::warnForInvalidValues = x; });
m.def("set_display_message_popups", [](bool x) { ps::options::displayMessagePopups = x; });
m.def("set_configure_imgui_style_callback", [](std::function<void()> x) { ps::options::configureImGuiStyleCallback = x; });
m.def("clear_configure_imgui_style_callback", []() {ps::options::configureImGuiStyleCallback = polyscope::configureImGuiStyle;});
m.def("set_files_dropped_callback", [](std::function<void(const std::vector<std::string>&)> x) { ps::state::filesDroppedCallback = x; });
m.def("clear_files_dropped_callback", []() {ps::state::filesDroppedCallback = nullptr;});


// === Scene extents
Expand Down
157 changes: 153 additions & 4 deletions src/cpp/imgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,12 +157,109 @@ void bind_imgui_structs(py::module& m) {
.def_readonly("SortDirection", &ImGuiTableColumnSortSpecs::SortDirection)
;

#define VEC2_PROPERTY(name) \
def_property(#name, [](const ImGuiStyle& style) { \
return from_vec2(style.name); \
}, [](ImGuiStyle& style, const Vec2T& value) { \
style.name = to_vec2(value); \
})


// Style
py::class_<ImGuiStyle>(m, "ImGuiStyle")
.def_readwrite("Alpha", &ImGuiStyle::Alpha) // float
.def_readwrite("DisabledAlpha", &ImGuiStyle::DisabledAlpha) // float
.VEC2_PROPERTY(WindowPadding) // ImVec2
.def_readwrite("WindowRounding", &ImGuiStyle::WindowRounding) // float
.def_readwrite("WindowBorderSize", &ImGuiStyle::WindowBorderSize) // float
.def_readwrite("WindowBorderHoverPadding", &ImGuiStyle::WindowBorderHoverPadding) // float
.VEC2_PROPERTY(WindowMinSize) // ImVec2
.VEC2_PROPERTY(WindowTitleAlign) // ImVec2
.def_readwrite("WindowMenuButtonPosition", &ImGuiStyle::WindowMenuButtonPosition) // ImGuiDir
.def_readwrite("ChildRounding", &ImGuiStyle::ChildRounding) // float
.def_readwrite("ChildBorderSize", &ImGuiStyle::ChildBorderSize) // float
.def_readwrite("PopupRounding", &ImGuiStyle::PopupRounding) // float
.def_readwrite("PopupBorderSize", &ImGuiStyle::PopupBorderSize) // float
.VEC2_PROPERTY(FramePadding) // ImVec2
.def_readwrite("FrameRounding", &ImGuiStyle::FrameRounding) // float
.def_readwrite("FrameBorderSize", &ImGuiStyle::FrameBorderSize) // float
.VEC2_PROPERTY(ItemSpacing) // ImVec2
.VEC2_PROPERTY(ItemInnerSpacing) // ImVec2
.VEC2_PROPERTY(CellPadding) // ImVec2
.VEC2_PROPERTY(TouchExtraPadding) // ImVec2
.def_readwrite("IndentSpacing", &ImGuiStyle::IndentSpacing) // float
.def_readwrite("ColumnsMinSpacing", &ImGuiStyle::ColumnsMinSpacing) // float
.def_readwrite("ScrollbarSize", &ImGuiStyle::ScrollbarSize) // float
.def_readwrite("ScrollbarRounding", &ImGuiStyle::ScrollbarRounding) // float
.def_readwrite("GrabMinSize", &ImGuiStyle::GrabMinSize) // float
.def_readwrite("GrabRounding", &ImGuiStyle::GrabRounding) // float
.def_readwrite("LogSliderDeadzone", &ImGuiStyle::LogSliderDeadzone) // float
.def_readwrite("ImageBorderSize", &ImGuiStyle::ImageBorderSize) // float
.def_readwrite("TabRounding", &ImGuiStyle::TabRounding) // float
.def_readwrite("TabBorderSize", &ImGuiStyle::TabBorderSize) // float
.def_readwrite("TabCloseButtonMinWidthSelected", &ImGuiStyle::TabCloseButtonMinWidthSelected) // float
.def_readwrite("TabCloseButtonMinWidthUnselected", &ImGuiStyle::TabCloseButtonMinWidthUnselected) // float
.def_readwrite("TabBarBorderSize", &ImGuiStyle::TabBarBorderSize) // float
.def_readwrite("TabBarOverlineSize", &ImGuiStyle::TabBarOverlineSize) // float
.def_readwrite("TableAngledHeadersAngle", &ImGuiStyle::TableAngledHeadersAngle) // float
.VEC2_PROPERTY(TableAngledHeadersTextAlign) // ImVec2
.def_readwrite("ColorButtonPosition", &ImGuiStyle::ColorButtonPosition) // ImGuiDir
.VEC2_PROPERTY(ButtonTextAlign) // ImVec2
.VEC2_PROPERTY(SelectableTextAlign) // ImVec2
.def_readwrite("SeparatorTextBorderSize", &ImGuiStyle::SeparatorTextBorderSize) // float
.VEC2_PROPERTY(SeparatorTextAlign) // ImVec2
.VEC2_PROPERTY(SeparatorTextPadding) // ImVec2
.VEC2_PROPERTY(DisplayWindowPadding) // ImVec2
.VEC2_PROPERTY(DisplaySafeAreaPadding) // ImVec2
.def_readwrite("MouseCursorScale", &ImGuiStyle::MouseCursorScale) // float
.def_readwrite("AntiAliasedLines", &ImGuiStyle::AntiAliasedLines) // bool
.def_readwrite("AntiAliasedLinesUseTex", &ImGuiStyle::AntiAliasedLinesUseTex) // bool
.def_readwrite("AntiAliasedFill", &ImGuiStyle::AntiAliasedFill) // bool
.def_readwrite("CurveTessellationTol", &ImGuiStyle::CurveTessellationTol) // float
.def_readwrite("CircleTessellationMaxError", &ImGuiStyle::CircleTessellationMaxError) // float

// Colors (ImVec4[ImGuiCol_COUNT])
// Note: having explicit getter and setter functions for colors will avoid accidental no-ops such as:
// style.Colors[2] = ...
.def("GetColors", [](const ImGuiStyle &o) {
py::list colors;
for (int i = 0; i < ImGuiCol_COUNT; i++) {
colors.append(from_vec4(o.Colors[i]));
}
return colors;
})
.def("SetColors", [](ImGuiStyle &o, const py::list& colors) {
if (colors.size() != ImGuiCol_COUNT) {
throw std::runtime_error("Expected " + std::to_string(ImGuiCol_COUNT)
+ " colors, got " + std::to_string(colors.size()));
}
for (int i = 0; i < ImGuiCol_COUNT; i++) {
if (py::len(colors[i]) != 4) {
throw std::runtime_error("Expected 4 elements for color " + std::to_string(i)
+ ", got " + std::to_string(py::len(colors[i])));
}
o.Colors[i] = to_vec4(py::cast<Vec4T>(colors[i]));
}
}, py::arg("colors"))

// Behaviors
// (It is possible to modify those fields mid-frame if specific behavior need it, unlike e.g. configuration fields in ImGuiIO)
.def_readwrite("HoverStationaryDelay", &ImGuiStyle::HoverStationaryDelay) // float
.def_readwrite("HoverDelayShort", &ImGuiStyle::HoverDelayShort) // float
.def_readwrite("HoverDelayNormal", &ImGuiStyle::HoverDelayNormal) // float
.def_readwrite("HoverFlagsForTooltipMouse", &ImGuiStyle::HoverFlagsForTooltipMouse) // ImGuiHoveredFlags
.def_readwrite("HoverFlagsForTooltipNav", &ImGuiStyle::HoverFlagsForTooltipNav) // ImGuiHoveredFlags

.def("ScaleAllSizes", &ImGuiStyle::ScaleAllSizes);

#undef VEC2_PROPERTY
}

void bind_imgui_methods(py::module& m) {

// Main
m.def("GetIO", &ImGui::GetIO, py::return_value_policy::reference);
m.def("GetStyle", &ImGui::GetStyle, py::return_value_policy::reference);

// Windows
m.def(
Expand Down Expand Up @@ -495,6 +592,10 @@ void bind_imgui_methods(py::module& m) {
"BulletText",
[](const char* fmt) { ImGui::BulletText("%s", fmt); },
py::arg("text"));
m.def(
"SeparatorText",
[](const char* label) { ImGui::SeparatorText(label); },
py::arg("label"));

// Widgets: Main
m.def(
Expand Down Expand Up @@ -558,6 +659,42 @@ void bind_imgui_methods(py::module& m) {
py::arg("size_arg") = std::make_tuple(-1.f, 0.f));
m.def("Bullet", []() { ImGui::Bullet(); });

// Widgets: Image
m.def(
"Image",
[](ImTextureID user_texture_id, const Vec2T& image_size, const Vec2T& uv0, const Vec2T& uv1) {
ImGui::Image(user_texture_id, to_vec2(image_size), to_vec2(uv0), to_vec2(uv1));
},
py::arg("user_texture_id"),
py::arg("image_size"),
py::arg("uv0") = Vec2T(0.0f, 0.0f),
py::arg("uv1") = Vec2T(1.0f, 1.0f));
m.def(
"ImageWithBg",
[](ImTextureID user_texture_id, const Vec2T& image_size, const Vec2T& uv0, const Vec2T& uv1, const Vec4T& bg_col, const Vec4T& tint_col) {
ImGui::ImageWithBg(user_texture_id, to_vec2(image_size), to_vec2(uv0), to_vec2(uv1), to_vec4(bg_col), to_vec4(tint_col));
},
py::arg("user_texture_id"),
py::arg("image_size"),
py::arg("uv0") = Vec2T(0.0f, 0.0f),
py::arg("uv1") = Vec2T(1.0f, 1.0f),
py::arg("bg_col") = Vec4T(0.0f, 0.0f, 0.0f, 0.0f),
py::arg("tint_col") = Vec4T(1.0f, 1.0f, 1.0f, 1.0f));

m.def(
"ImageButton",
[](const char* str_id, ImTextureID user_texture_id, const Vec2T& image_size, const Vec2T& uv0, const Vec2T& uv1, const Vec4T& bg_col, const Vec4T& tint_col) {
return ImGui::ImageButton(str_id, user_texture_id, to_vec2(image_size), to_vec2(uv0), to_vec2(uv1), to_vec4(bg_col), to_vec4(tint_col));
},
py::arg("str_id"),
py::arg("user_texture_id"),
py::arg("image_size"),
py::arg("uv0") = Vec2T(0.0f, 0.0f),
py::arg("uv1") = Vec2T(1.0f, 1.0f),
py::arg("bg_col") = Vec4T(0.0f, 0.0f, 0.0f, 0.0f),
py::arg("tint_col") = Vec4T(1.0f, 1.0f, 1.0f, 1.0f));


// Widgets: Combo Box
m.def(
"BeginCombo",
Expand Down Expand Up @@ -2472,6 +2609,7 @@ void bind_imgui_enums(py::module& m) {
m.attr("ImGuiCol_ScrollbarGrabActive") = static_cast<int>(ImGuiCol_ScrollbarGrabActive);
m.attr("ImGuiCol_CheckMark") = static_cast<int>(ImGuiCol_CheckMark);
m.attr("ImGuiCol_SliderGrab") = static_cast<int>(ImGuiCol_SliderGrab);
m.attr("ImGuiCol_ScrollbarGrabHovered") = static_cast<int>(ImGuiCol_ScrollbarGrabHovered);
m.attr("ImGuiCol_SliderGrabActive") = static_cast<int>(ImGuiCol_SliderGrabActive);
m.attr("ImGuiCol_Button") = static_cast<int>(ImGuiCol_Button);
m.attr("ImGuiCol_ButtonHovered") = static_cast<int>(ImGuiCol_ButtonHovered);
Expand All @@ -2485,19 +2623,31 @@ void bind_imgui_enums(py::module& m) {
m.attr("ImGuiCol_ResizeGrip") = static_cast<int>(ImGuiCol_ResizeGrip);
m.attr("ImGuiCol_ResizeGripHovered") = static_cast<int>(ImGuiCol_ResizeGripHovered);
m.attr("ImGuiCol_ResizeGripActive") = static_cast<int>(ImGuiCol_ResizeGripActive);
m.attr("ImGuiCol_Tab") = static_cast<int>(ImGuiCol_Tab);
m.attr("ImGuiCol_TabHovered") = static_cast<int>(ImGuiCol_TabHovered);
m.attr("ImGuiCol_TabActive") = static_cast<int>(ImGuiCol_TabActive);
m.attr("ImGuiCol_Tab") = static_cast<int>(ImGuiCol_Tab);
m.attr("ImGuiCol_TabSelected") = static_cast<int>(ImGuiCol_TabSelected);
m.attr("ImGuiCol_TabSelectedOverline") = static_cast<int>(ImGuiCol_TabSelectedOverline);
m.attr("ImGuiCol_TabDimmed") = static_cast<int>(ImGuiCol_TabDimmed);
m.attr("ImGuiCol_TabDimmedSelected") = static_cast<int>(ImGuiCol_TabDimmedSelected);
m.attr("ImGuiCol_TabDimmedSelectedOverline") = static_cast<int>(ImGuiCol_TabDimmedSelectedOverline);
m.attr("ImGuiCol_TabActive") = static_cast<int>(ImGuiCol_TabSelected); // Deprecated
m.attr("ImGuiCol_TabUnfocused") = static_cast<int>(ImGuiCol_TabUnfocused);
m.attr("ImGuiCol_TabUnfocusedActive") = static_cast<int>(ImGuiCol_TabUnfocusedActive);
m.attr("ImGuiCol_PlotLines") = static_cast<int>(ImGuiCol_PlotLines);
m.attr("ImGuiCol_PlotLinesHovered") = static_cast<int>(ImGuiCol_PlotLinesHovered);
m.attr("ImGuiCol_PlotHistogram") = static_cast<int>(ImGuiCol_PlotHistogram);
m.attr("ImGuiCol_PlotHistogramHovered") = static_cast<int>(ImGuiCol_PlotHistogramHovered);
m.attr("ImGuiCol_TableHeaderBg") = static_cast<int>(ImGuiCol_TableHeaderBg);
m.attr("ImGuiCol_TableBorderStrong") = static_cast<int>(ImGuiCol_TableBorderStrong);
m.attr("ImGuiCol_TableBorderLight") = static_cast<int>(ImGuiCol_TableBorderLight);
m.attr("ImGuiCol_TableRowBg") = static_cast<int>(ImGuiCol_TableRowBg);
m.attr("ImGuiCol_TableRowBgAlt") = static_cast<int>(ImGuiCol_TableRowBgAlt);
m.attr("ImGuiCol_TextLink") = static_cast<int>(ImGuiCol_TextLink);
m.attr("ImGuiCol_TextSelectedBg") = static_cast<int>(ImGuiCol_TextSelectedBg);
m.attr("ImGuiCol_DragDropTarget") = static_cast<int>(ImGuiCol_DragDropTarget);
m.attr("ImGuiCol_NavHighlight") = static_cast<int>(ImGuiCol_NavHighlight);
m.attr("ImGuiCol_NavCursor") = static_cast<int>(ImGuiCol_NavCursor);
m.attr("ImGuiCol_NavWindowingHighlight") = static_cast<int>(ImGuiCol_NavWindowingHighlight);
m.attr("ImGuiCol_NavHighlight") = static_cast<int>(ImGuiCol_NavCursor); // Deprecated
m.attr("ImGuiCol_NavWindowingDimBg") = static_cast<int>(ImGuiCol_NavWindowingDimBg);
m.attr("ImGuiCol_ModalWindowDimBg") = static_cast<int>(ImGuiCol_ModalWindowDimBg);
m.attr("ImGuiCol_COUNT") = static_cast<int>(ImGuiCol_COUNT);
Expand Down Expand Up @@ -2589,4 +2739,3 @@ void bind_imgui_enums(py::module& m) {
m.attr("ImDrawFlags_RoundCornersAll") = static_cast<int>(ImDrawFlags_RoundCornersAll);

}

12 changes: 12 additions & 0 deletions src/polyscope/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,18 @@ def set_warn_for_invalid_values(b):
def set_display_message_popups(b):
psb.set_display_message_popups(b)

def set_configure_imgui_style_callback(f):
return psb.set_configure_imgui_style_callback(f)

def clear_configure_imgui_style_callback():
return psb.clear_configure_imgui_style_callback()

def set_files_dropped_callback(f):
return psb.set_files_dropped_callback(f)

def clear_files_dropped_callback():
return psb.clear_files_dropped_callback()

def set_navigation_style(s):
psb.set_navigation_style(str_to_navigate_style(s))
def get_navigation_style():
Expand Down
24 changes: 14 additions & 10 deletions test/polyscope_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,18 +121,22 @@ def sample_callback():

ps.set_user_callback(sample_callback)
ps.show(3)

# Make sure the callback got called
self.assertEqual(3, counts[0])

self.assertEqual(3, counts[0]) # Make sure the callback got called
ps.clear_user_callback()
ps.show(3)

# Make sure the callback didn't get called any more
self.assertEqual(3, counts[0])

# Make sure clearing twice is ok
ps.clear_user_callback()
self.assertEqual(3, counts[0]) # Make sure the callback didn't get called any more
ps.clear_user_callback() # Make sure clearing twice is ok


## Test other callback functions
def do_nothing_callback():
pass
ps.set_configure_imgui_style_callback(do_nothing_callback)
ps.clear_configure_imgui_style_callback()
def do_nothing_callback_2(arg):
pass
ps.set_files_dropped_callback(do_nothing_callback)
ps.clear_files_dropped_callback()

def test_view_options(self):

Expand Down