The new imguizmo and selection plugins inherit from igl::opengl::glfw::imgui::ImGuiMenu.
Unfortunately, due to how imgui+plugins behave, this means you can only have at most one of these plugins active at a time.
Here's a minimal example:
#include <igl/read_triangle_mesh.h>
#include <igl/opengl/glfw/Viewer.h>
#include <igl/opengl/glfw/imgui/ImGuiMenu.h>
#include <igl/opengl/glfw/imgui/ImGuizmoPlugin.h>
#define WITH_IMGUIZMO
#define WITH_MENU
int main(int argc, char *argv[])
{
// Load a mesh from file
Eigen::MatrixXd V;
Eigen::MatrixXi F;
igl::read_triangle_mesh(argv[1],V,F);
// Set up viewer
igl::opengl::glfw::Viewer vr;
vr.data().set_mesh(V,F);
// Attach a menu plugin
#ifdef WITH_MENU
igl::opengl::glfw::imgui::ImGuiMenu menu;
vr.plugins.push_back(&menu);
#endif
#ifdef WITH_IMGUIZMO
igl::opengl::glfw::imgui::ImGuizmoPlugin imguizmo;
vr.plugins.push_back(&imguizmo);
// Initialize ImGuizmo at mesh centroid
imguizmo.T.block(0,3,3,1) =
0.5*(V.colwise().maxCoeff() + V.colwise().minCoeff()).transpose().cast<float>();
// Update can be applied relative to this remembered initial transform
const Eigen::Matrix4f T0 = imguizmo.T;
// Attach callback to apply imguizmo's transform to mesh
imguizmo.callback = [&](const Eigen::Matrix4f & T)
{
const Eigen::Matrix4d TT = (T*T0.inverse()).cast<double>().transpose();
vr.data().set_vertices(
(V.rowwise().homogeneous()*TT).rowwise().hnormalized());
vr.data().compute_normals();
};
#endif
vr.launch();
}
This crashes on an imgui assertion:
Assertion failed: ((g.FrameCount == 0 || g.FrameCountEnded == g.FrameCount) && "Forgot to call Render() or EndFrame() at the end of the previous frame?"), function ErrorCheckNewFrameSanityChecks, file /Users/ajx/Repos/libigl/external/imgui/imgui.cpp, line 6733.
Process 60128 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = hit program assert
frame #4: 0x00000001001bc2c4 example`ImGui::ErrorCheckNewFrameSanityChecks() at imgui.cpp:6733:5
6730 // (We pass an error message in the assert expression to make it visible to programmers who are not using a debugger, as most assert handlers display their argument)
6731 IM_ASSERT(g.Initialized);
6732 IM_ASSERT((g.IO.DeltaTime > 0.0f || g.FrameCount == 0) && "Need a positive DeltaTime!");
-> 6733 IM_ASSERT((g.FrameCount == 0 || g.FrameCountEnded == g.FrameCount) && "Forgot to call Render() or EndFrame() at the end of the previous frame?");
6734 IM_ASSERT(g.IO.DisplaySize.x >= 0.0f && g.IO.DisplaySize.y >= 0.0f && "Invalid DisplaySize value!");
6735 IM_ASSERT(g.IO.Fonts->Fonts.Size > 0 && "Font Atlas not built. Did you call io.Fonts->GetTexDataAsRGBA32() / GetTexDataAsAlpha8() ?");
6736 IM_ASSERT(g.IO.Fonts->Fonts[0]->IsLoaded() && "Font Atlas not built. Did you call io.Fonts->GetTexDataAsRGBA32() / GetTexDataAsAlpha8() ?");
Target 0: (example) stopped.
This appears to be a consequence with how drawing plugins is handled in the Viewer. The viewer will loop over all of the plugins calling their pre_draw functions, then the Viewer draws itself, then the Viewer loops over all of the plugins calling their post_draw functions.
Each of these imgui-based plugins initializes the imgui "context" during its pre_draw, e.g., `ImGuiMenu::predraw contains:
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
So with 3 plugins, this gets called 3 times, then the Viewer draws, and then each plugin calls imgui "de-initialization"/"render" routines in their post_draw. E.g.,
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
What's a good fix here?
Do we really need to sandwich the pre/post draw?
The new imguizmo and selection plugins inherit from igl::opengl::glfw::imgui::ImGuiMenu.
Unfortunately, due to how imgui+plugins behave, this means you can only have at most one of these plugins active at a time.
Here's a minimal example:
This crashes on an imgui assertion:
This appears to be a consequence with how drawing plugins is handled in the Viewer. The viewer will loop over all of the plugins calling their
pre_drawfunctions, then the Viewer draws itself, then the Viewer loops over all of the plugins calling theirpost_drawfunctions.Each of these imgui-based plugins initializes the imgui "context" during its
pre_draw, e.g., `ImGuiMenu::predraw contains:So with 3 plugins, this gets called 3 times, then the Viewer draws, and then each plugin calls imgui "de-initialization"/"render" routines in their
post_draw. E.g.,What's a good fix here?
Do we really need to sandwich the pre/post draw?