LiangliangNan / Easy3D

A lightweight, easy-to-use, and efficient C++ library for processing and rendering 3D data
GNU General Public License v3.0
1.37k stars 245 forks source link

Wait for user input to draw an object #135

Closed esuig closed 2 years ago

esuig commented 2 years ago

Hello,

I'm using the Tutorial_201_Viewer_imgui as a basis and it works greatly. Now I want to use it to display a series of meshes. Let's suppose I want to display ten meshes, after the display of each mesh I would like to diplay a message dialog that blocks the execution of the code, then press a sort of "ok" button on the dialog, start the execution again and display the second mesh and so on. Do you think it would be possible?

LiangliangNan commented 2 years ago

Yes, it is possible, and there could be multiple ways to achieve this. Option 1: change the mesh and pop up the dialog in another thread. Option 2: for each mesh, you create a new viewer, load the mesh, and show the viewer and dialog. You close the viewer after the user's input. This can be easily implemented using a for loop.

LiangliangNan commented 2 years ago

I had some time and tested option 1 and it works well. You can try the code below:

#include <easy3d/viewer/viewer.h>
#include <easy3d/renderer/renderer.h>
#include <easy3d/fileio/resources.h>
#include <easy3d/util/logging.h>
#include <easy3d/util/timer.h>
#include <easy3d/util/dialogs.h>

using namespace easy3d;

void action_func(Viewer *viewer) {
    std::vector<std::string> file_names = {
            resource::directory() + "/data/easy3d/easy3d_e.ply",
            resource::directory() + "/data/easy3d/easy3d_a.ply",
            resource::directory() + "/data/easy3d/easy3d_s.ply",
            resource::directory() + "/data/easy3d/easy3d_y.ply",
            resource::directory() + "/data/easy3d/easy3d_3.ply",
            resource::directory() + "/data/easy3d/easy3d_d.ply"
    };

    for (const auto& name : file_names) {
        auto model = viewer->add_model(name);
        model->renderer()->update();// notify the renderer to update the OpenGL buffers
        viewer->fit_screen(model);

        auto answer = dialog::message("Please answer", "Do you like this model?", dialog::Choice::yes_no, dialog::Type::question);
        if (answer == dialog::Response::yes)
            std::cout << "Great like it :-)" << std::endl;
        else
            std::cout << "Sorry you don't like the model :-(" << std::endl;
    }
}

int main(int argc, char **argv) {
    // initialize logging.
    logging::initialize();

    // create the viewer
    Viewer viewer("MyApp");

    // run the process in another thread
    Timer<Viewer*>::single_shot(0, action_func, &viewer);

    // run the viewer
    return viewer.run();
}
esuig commented 2 years ago

Thank you, that worked! By the way, do you think your library could be implemented in a wxwidgets based app?

LiangliangNan commented 2 years ago

The visualization in Easy3D is based on OpenGL, so it can seamlessly work with wxWidgets to build more advanced GUI applications.