nmwsharp / polyscope

A C++ & Python viewer for 3D data like meshes and point clouds
https://polyscope.run
MIT License
1.8k stars 196 forks source link

Allow ImGui initial settings before show() #133

Closed xarthurx closed 2 years ago

xarthurx commented 2 years ago

Similar to the questions https://github.com/nmwsharp/polyscope/issues/124, but more general.

Main Issue: We need a callback function or an "overridable" function to allow initializing imgui settings, for things like: style, font, etc., before the polyscole::init(). (To be more specific, ImGui::CreateContext() need to be called so that an ImGuiContext* is created first.)

These settings don't need to be set in every loop using the callback mechanism, but only once.

Additional Info:

  1. Actually, if using sth like the following:
  ImGuiStyle& style = ImGui::GetStyle();
  // scale UI 1.5 times
  style.ScaleAllSizes(1.3);

The menu will explode if we do it inside the loop.

  1. For font settings, ImGui only allow setting them once and will lock them afterwards.
xarthurx commented 2 years ago

Perhaps adding a callback to the GUI configuration func: https://github.com/nmwsharp/polyscope/blob/8a22cf8693cc045128992a63f67cbb98d893f42b/src/render/engine.cpp?_pjax=%23js-repo-pjax-container%2C%20div%5Bitemtype%3D%22http%3A%2F%2Fschema.org%2FSoftwareSourceCode%22%5D%20main%2C%20%5Bdata-pjax-container%5D#L923

or make it into an overridable virtual func?

In general, UI customization possibility is needed for we the user to design our own UI system...

xarthurx commented 2 years ago

Looking deeper into the source code, I think it is not possible to modify the style based on the current code structure. There seems no way to redefine the configureImGui() unless making a derived class of the GlEngine and re-define the virtual function initializeImGui(), and add the new Engine as a backend... which is too much for achieving the UI edit goal.

@nmwsharp Any idea how you would implement the feature?

xarthurx commented 2 years ago

Some update FYI.

I tried to use a customized init() instead of the default polyscope::init() to bypass the default mechanism:

void xInit() {
  auto tmpEngine = new xEngine();
  tmpEngine->initialize();
  polyscope::render::engine = tmpEngine;
  polyscope::render::engine->allocateGlobalBuffersAndPrograms();

  IMGUI_CHECKVERSION();
  polyscope::render::engine->initializeImGui();

  xViewer.initFont();
  xViewer.setupOptStyle();

  // push a fake context which will never be used (but dodges some invalidation
  // issues)
  // polyscope::<unnamed>::contextStack.push_back(ContextEntry{ImGui::GetCurrentContext(),
  // nullptr, false});

  polyscope::view::invalidateView();

  polyscope::state::initialized = true;
}

Where I encounter several issues:

  1. When deriving the GlEngine class by #include "gl_engine.h", MSVC reports glad/glad.h cannot be found. Somehow the dependency is not correctly resolved.
#include "polyscope/polyscope.h"
#include "polyscope/render/engine.h"
#include "polyscope/render/opengl/gl_engine.h"

class xEngine : public polyscope::render::backend_openGL3_glfw::GLEngine {
  void initializeImGui() override;
};
  1. The ContextEntry is existed in an unnamed namespace inside polyscope, here: https://github.com/nmwsharp/polyscope/blob/8a22cf8693cc045128992a63f67cbb98d893f42b/src/polyscope.cpp#L26 Which created some issues when using it in my own projects. (Perhaps this is not meant to be done?)

Since too many issues occur, I will stop here to prevent unnecessary efforts until you @nmwsharp have further updates (or suggestions/agreements so that I can possibly contribute some PR).

xarthurx commented 2 years ago

Following up with this issue.

The styles of the UI can be set up in the user callback function as a temporary bypass, though we don't need to do it in every loop. But the font settings, if I want to load a customized font, does not work in this way. It has to be set up earlier inside the init mechanism.

nmwsharp commented 2 years ago

Now supported here: https://polyscope.run/features/callbacks_and_UIs/#custom-uis