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

Please add more tutorial code for Viewer_Qt about adding new drawable about makeCurrent() and doneCurrent() #143

Closed xiaowuga closed 1 year ago

xiaowuga commented 1 year ago

makeCurrent() // OpenGL Code doneCurrent()

When Qt as viewer for easy3D,if we add a drawable for some model or new a drawable, we must embed code between function makeCurrent() and doneCurrent(). I think it is necessary to add some description in example code for Tutorial_204_Viewer_Qt to prevent users from making mistakes. Thank you!

LiangliangNan commented 1 year ago

Thanks for the suggestion! Now it has been implemented. The following functions are available for adding/deleting models or drawables:

      void addModel(easy3d::Model *model);
      void deleteModel(easy3d::Model *model);

      bool add_drawable(Drawable* drawable);
      bool delete_drawable(Drawable* drawable);
xiaowuga commented 1 year ago

it is not work in my Win10 system. I need to write code like follow:

makeCurrent();
LinesDrawable* drawable = new LinesDrawable("line");
drawable->update_vertex_buffer(points);
drawable->set_uniform_coloring(vec4(0.0f, 0.0f, 1.0f, 1.0f));
drawable->set_line_width(0.1f);
drawable->set_visible(true);

doneCurrent();
add_drawable(drawable);

otherwise, drawable 's vertex buffer can not be updated by function updae_vertex_buffer().

LiangliangNan commented 1 year ago

There are three options to achieve your goal. Choose the one easier for you:

1) implement your drawable creation in the Viewer class, i.e., your above code becomes one member function of Viewer.

2) provide a customized drawable update function by calling: Drawable::set_update_func(...). Check the description of this function.

3) call viewer_->makeCurrent(); before you update the buffers and viewer_->doneCurrent(); after. This seems the easiest, so your code will look like

```c++
viewer_->makeCurrent();  //   <------ changed here
LinesDrawable* drawable = new LinesDrawable("line");
drawable->update_vertex_buffer(points);
drawable->set_uniform_coloring(vec4(0.0f, 0.0f, 1.0f, 1.0f));
drawable->set_line_width(0.1f);
drawable->set_visible(true);
viewer_->add_drawable(drawable);
viewer_->doneCurrent();  //   <------ changed here
```
xiaowuga commented 1 year ago

Option one does not work. I implement a function in Viewer for controling whether the normal is rendered or not.

  void Viewer::render_normals(bool v) {

      PointCloud *cloud = get_point_cloud();
      if (cloud) {
          auto drawable = find_drawable("normals");
          if (drawable) {
              drawable->set_visible(v);
          } else {
              auto normals = cloud->get_vertex_property<vec3>("v:normal");
              if (!normals) {
                  LOG(WARNING) << "normals info do noe exist! " << std::endl;
                  return;
              } else {
                  auto points = cloud->get_vertex_property<vec3>("v:point");
                  double length = cloud->bounding_box().diagonal_length() * 0.05;

                  std::vector<vec3> vertex;
                  for (auto v: cloud->vertices()) {
                      vertex.emplace_back(points[v]);
                      vertex.emplace_back(points[v] + normals[v].normalize() * length);
                  }
                  makeCurrent();
                  LinesDrawable *drawable = new LinesDrawable("normals");

                  drawable->update_vertex_buffer(vertex);
                  drawable->set_uniform_coloring(vec4(0.0f, 0.0f, 0.5f, 1.0f));
                  drawable->set_line_width(0.1f);
                  drawable->set_visible(v);
                  doneCurrent();
                  add_drawable(drawable);
              }
          }
      }
  }

However, if the uodate_vertex_buffer do not embed between make/doneCurrent(), it still not work.

LiangliangNan commented 1 year ago

That is due to the function may not be implemented or called properly :-)

I saw your function is named "render_normals()", so I assume it is used for rendering the normals and is thus called by "Viewer::draw()". I saw several things that may not work:

xiaowuga commented 1 year ago

ok, Thanks a lot