Closed xiaowuga closed 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);
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().
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
```
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.
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:
you already have a 'Model' (the point cloud), so you can directly link your drawable to your point cloud. This way, you can easily query the drawable and change its visibility (See the code below). If you still want a stand-alone drawable, you should keep a pointer of that drawable, then later you can call its "set_visible(...)" to change its visibility.
void Viewer::show_normals(bool visible) {
PointCloud *cloud = ...; // I don't know how your model is stored
if (!cloud)
return;
auto drawable = cloud->renderer()->get_lines_drawable("normals");
if (drawable) {
drawable->set_visible(visible);
return;
}
// the drawable doesn't exist yet, let's create it
auto normals = cloud->get_vertex_property<vec3>("v:normal");
if (!normals) {
LOG(WARNING) << "normals info do not exist! " << std::endl;
return;
}
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();
drawable = cloud->renderer()->add_lines_drawable("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(true);
doneCurrent();
}
ok, Thanks a lot
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!