Easy3D 2.6.1
Loading...
Searching...
No Matches
Tutorial_301_Drawables/main.cpp

Drawables are typically for rendering 3D models (e.g., point clouds, meshes, graphs) that are loaded from files or generated by some algorithms. The use of drawables for visualization is quite flexible. Drawables are normally attached to a 3D model. For example, you can attach a TrianglesDrawable to a surface mesh to visualize its surface and a PointsDrawable to visualize its vertices. Easy3D also allows visualizing stand-alone drawables (without creating a model).

This example shows how to

1/********************************************************************
2 * Copyright (C) 2015 Liangliang Nan <liangliang.nan@gmail.com>
3 * https://3d.bk.tudelft.nl/liangliang/
4 *
5 * This file is part of Easy3D. If it is useful in your research/work,
6 * I would be grateful if you show your appreciation by citing it:
7 * ------------------------------------------------------------------
8 * Liangliang Nan.
9 * Easy3D: a lightweight, easy-to-use, and efficient C++ library
10 * for processing and rendering 3D data.
11 * Journal of Open Source Software, 6(64), 3255, 2021.
12 * ------------------------------------------------------------------
13 *
14 * Easy3D is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License Version 3
16 * as published by the Free Software Foundation.
17 *
18 * Easy3D is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 ********************************************************************/
26
27#include <easy3d/viewer/viewer.h>
28#include <easy3d/renderer/drawable_lines.h>
29#include <easy3d/renderer/drawable_points.h>
30#include <easy3d/renderer/drawable_triangles.h>
31#include <easy3d/core/types.h>
32#include <easy3d/util/resource.h>
33#include <easy3d/util/initializer.h>
34
54
55using namespace easy3d;
56
57
58#if 1 // use the built-in drawables of Easy3D.
59
60int main(int argc, char **argv) {
61 // initialize Easy3D.
62 initialize();
63
64 //-------------------------------------------------------------
65
66 // Create the default Easy3D viewer.
67 // Note: a viewer must be created before creating any drawables.
68 Viewer viewer(EXAMPLE_TITLE);
69 viewer.set_usage("");
70
71 //-------------------------------------------------------------
72
73 // We visualize the "bunny".
74
75 // The coordinates of the vertices.
76 const std::vector<vec3> &points = resource::bunny_vertices;
77 // The indices represent how the vertices are connected to form triangles. The "bunny" is a triangle mesh, and thus
78 // each consecutive three indices represent a triangle.
79 const std::vector<unsigned int> &indices = resource::bunny_indices;
80
81 //-------------------------------------------------------------
82 // Create a TrianglesDrawable to visualize the surface of the "bunny".
83 // For visualization, the point positions and the vertex indices of the faces have to be sent to the GPU.
84 auto surface = new TrianglesDrawable("faces");
85 // Upload the vertex positions of the surface to the GPU.
86 surface->update_vertex_buffer(points);
87 // Upload the vertex indices of the surface to the GPU.
88 surface->update_element_buffer(indices);
89 // Add the drawable to the viewer
90 viewer.add_drawable(std::shared_ptr<TrianglesDrawable>(surface));
91
92 //-------------------------------------------------------------
93 // Create a PointsDrawable to visualize the vertices of the "bunny".
94 // Only the vertex positions have to be sent to the GPU for visualization.
95 auto vertices = new PointsDrawable("vertices");
96 // Upload the vertex positions to the GPU.
97 vertices->update_vertex_buffer(points);
98 // Set a color for the vertices (here we want a red color).
99 vertices->set_uniform_coloring(vec4(1.0f, 0.0f, 0.0f, 1.0f)); // RBGA
100 // Three options are available for visualizing points:
101 // - PLAIN: plain points (i.e., each point is a square on the screen);
102 // - SPHERE: each point is visualized a sphere;
103 // - SURFEL: each point is visualized an oriented disk.
104 // In this example, let's render the vertices as spheres.
105 vertices->set_impostor_type(PointsDrawable::SPHERE);
106 // Set the vertices size (here 10 pixels).
107 vertices->set_point_size(10);
108 // Add the drawable to the viewer
109 viewer.add_drawable(std::shared_ptr<PointsDrawable>(vertices));
110
111 //-------------------------------------------------------------
112 // Create a LinesDrawable to visualize the bounding box of the "bunny".
113
114 // Compute the bounding box.
115 auto bbox_drawable = new LinesDrawable("bbox");
117 float xmin = box.min_coord(0);
118 float xmax = box.max_coord(0);
119 float ymin = box.min_coord(1);
120 float ymax = box.max_coord(1);
121 float zmin = box.min_coord(2);
122 float zmax = box.max_coord(2);
123 // The eight vertices of the bounding box.
124 const std::vector<vec3> bbox_points = {
125 vec3(xmin, ymin, zmax), vec3(xmax, ymin, zmax),
126 vec3(xmin, ymax, zmax), vec3(xmax, ymax, zmax),
127 vec3(xmin, ymin, zmin), vec3(xmax, ymin, zmin),
128 vec3(xmin, ymax, zmin), vec3(xmax, ymax, zmin)
129 };
130 // The vertex indices of the twelve edges of the bounding box (each consecutive two numbers represent an edge).
131 const std::vector<unsigned int> bbox_indices = {
132 0, 1, 2, 3, 4, 5, 6, 7,
133 0, 2, 4, 6, 1, 3, 5, 7,
134 0, 4, 2, 6, 1, 5, 3, 7
135 };
136 // Upload the vertex positions of the bounding box to the GPU.
137 bbox_drawable->update_vertex_buffer(bbox_points);
138 // Upload the vertex indices of the bounding box to the GPU.
139 bbox_drawable->update_element_buffer(bbox_indices);
140 // Set a color for the edges of the bounding box (here we want a blue color).
141 bbox_drawable->set_uniform_coloring(vec4(0.0f, 0.0f, 1.0f, 1.0f)); // r, g, b, a
142 // Set the width of the edges (here 5 pixels).
143 bbox_drawable->set_line_width(5.0f);
144 // Add the drawable to the viewer
145 viewer.add_drawable(std::shared_ptr<LinesDrawable>(bbox_drawable));
146
147 //-------------------------------------------------------------
148
149 // Make sure everything is within the visible region of the viewer.
150 viewer.fit_screen();
151
152 // run the viewer
153 return viewer.run();
154}
155
156#elif 0 // use the built-in drawables of Easy3D, but we provide customized update functions
157
158int main(int argc, char **argv) {
159 // initialize Easy3D.
160 initialize();
161
162 //-------------------------------------------------------------
163
164 // Create the default Easy3D viewer.
165 // Note: a viewer must be created before creating any drawables.
166 Viewer viewer(EXAMPLE_TITLE);
167 viewer.set_usage("");
168
169 //-------------------------------------------------------------
170
171 // We visualize the "bunny".
172
173 // The coordinates of the vertices.
174 const std::vector<vec3> &points = resource::bunny_vertices;
175 // The indices represent how the vertices are connected to form triangles. The "bunny" is a triangle mesh, and thus
176 // each consecutive three indices represent a triangle.
177 const std::vector<unsigned int> &indices = resource::bunny_indices;
178
179 //-------------------------------------------------------------
180 // Create a TrianglesDrawable to visualize the surface of the "bunny".
181 // For visualization, the point positions and the vertex indices of the faces have to be sent to the GPU.
182 auto surface = new TrianglesDrawable("faces");
183 surface->set_update_func([&points, &indices](Model* m, Drawable* d) {
184 // Upload the vertex positions of the surface to the GPU.
185 d->update_vertex_buffer(points);
186 // Upload the vertex indices of the surface to the GPU.
187 d->update_element_buffer(indices);
188 });
189
190 // Add the drawable to the viewer
191 viewer.add_drawable(std::shared_ptr<TrianglesDrawable>(surface));
192
193 //-------------------------------------------------------------
194 // Create a PointsDrawable to visualize the vertices of the "bunny".
195 // Only the vertex positions have to be sent to the GPU for visualization.
196 auto vertices = new PointsDrawable("vertices");
197 vertices->set_update_func([&points](Model* m, Drawable* d) {
198 // Upload the vertex positions to the GPU.
199 d->update_vertex_buffer(points);
200 });
201
202 // Set a color for the vertices (here we want a red color).
203 vertices->set_uniform_coloring(vec4(1.0f, 0.0f, 0.0f, 1.0f)); // r, g, b, a
204 // Three options are available for visualizing points:
205 // - PLAIN: plain points (i.e., each point is a square on the screen);
206 // - SPHERE: each point is visualized a sphere;
207 // - SURFEL: each point is visualized an oriented disk.
208 // In this example, let's render the vertices as spheres.
209 vertices->set_impostor_type(PointsDrawable::SPHERE);
210 // Set the vertices size (here 10 pixels).
211 vertices->set_point_size(10);
212 // Add the drawable to the viewer
213 viewer.add_drawable(std::shared_ptr<PointsDrawable>(vertices));
214
215 //-------------------------------------------------------------
216 // Create a LinesDrawable to visualize the bounding box of the "bunny".
217
218 // Compute the bounding box.
219 auto bbox_drawable = new LinesDrawable("bbox");
220 bbox_drawable->set_update_func([&points](Model* m, Drawable* d) {
222 float xmin = box.min_coord(0);
223 float xmax = box.max_coord(0);
224 float ymin = box.min_coord(1);
225 float ymax = box.max_coord(1);
226 float zmin = box.min_coord(2);
227 float zmax = box.max_coord(2);
228 // The eight vertices of the bounding box.
229 const std::vector<vec3> bbox_points = {
230 vec3(xmin, ymin, zmax), vec3(xmax, ymin, zmax),
231 vec3(xmin, ymax, zmax), vec3(xmax, ymax, zmax),
232 vec3(xmin, ymin, zmin), vec3(xmax, ymin, zmin),
233 vec3(xmin, ymax, zmin), vec3(xmax, ymax, zmin)
234 };
235 // The vertex indices of the twelve edges of the bounding box (each consecutive two numbers represent an edge).
236 const std::vector<unsigned int> bbox_indices = {
237 0, 1, 2, 3, 4, 5, 6, 7,
238 0, 2, 4, 6, 1, 3, 5, 7,
239 0, 4, 2, 6, 1, 5, 3, 7
240 };
241
242 // Upload the vertex positions of the bounding box to the GPU.
243 d->update_vertex_buffer(bbox_points);
244 // Upload the vertex indices of the bounding box to the GPU.
245 d->update_element_buffer(bbox_indices);
246 });
247
248 // Set a color for the edges of the bounding box (here we want a blue color).
249 bbox_drawable->set_uniform_coloring(vec4(0.0f, 0.0f, 1.0f, 1.0f)); // r, g, b, a
250 // Set the width of the edges (here 5 pixels).
251 bbox_drawable->set_line_width(5.0f);
252 // Add the drawable to the viewer
253 viewer.add_drawable(std::shared_ptr<LinesDrawable>(bbox_drawable));
254
255 //-------------------------------------------------------------
256
257 // Make sure everything is within the visible region of the viewer.
258 viewer.fit_screen();
259
260 // run the viewer
261 return viewer.run();
262}
263
264#else // inherit customized drawables from Easy3D drawables, and we reimplement "void update_buffers_internal()"
265
266class MyTrianglesDrawable : public TrianglesDrawable {
267public:
268 MyTrianglesDrawable(const std::string& name = "") : TrianglesDrawable(name) {}
269
270protected:
271 void update_buffers_internal() {
272 // The coordinates of the vertices.
273 const std::vector<vec3> &points = resource::bunny_vertices;
274 // The indices represent how the vertices are connected to form triangles. The "bunny" is a triangle mesh, and thus
275 // each consecutive three indices represent a triangle.
276 const std::vector<unsigned int> &indices = resource::bunny_indices;
277
278 // Upload the vertex positions of the surface to the GPU.
279 update_vertex_buffer(points);
280 // Upload the vertex indices of the surface to the GPU.
281 update_element_buffer(indices);
282 }
283};
284
285
286class MyLinesDrawable : public LinesDrawable {
287public:
288 MyLinesDrawable(const std::string& name = "") : LinesDrawable(name) {}
289
290protected:
291 void update_buffers_internal() {
292 // The coordinates of the vertices.
293 const std::vector<vec3> &points = resource::bunny_vertices;
294 const Box3 &box = geom::bounding_box<Box3, std::vector<vec3> >(points);
295 float xmin = box.min_coord(0);
296 float xmax = box.max_coord(0);
297 float ymin = box.min_coord(1);
298 float ymax = box.max_coord(1);
299 float zmin = box.min_coord(2);
300 float zmax = box.max_coord(2);
301 // The eight vertices of the bounding box.
302 const std::vector<vec3> bbox_points = {
303 vec3(xmin, ymin, zmax), vec3(xmax, ymin, zmax),
304 vec3(xmin, ymax, zmax), vec3(xmax, ymax, zmax),
305 vec3(xmin, ymin, zmin), vec3(xmax, ymin, zmin),
306 vec3(xmin, ymax, zmin), vec3(xmax, ymax, zmin)
307 };
308 // The vertex indices of the twelve edges of the bounding box (each consecutive two numbers represent an edge).
309 const std::vector<unsigned int> bbox_indices = {
310 0, 1, 2, 3, 4, 5, 6, 7,
311 0, 2, 4, 6, 1, 3, 5, 7,
312 0, 4, 2, 6, 1, 5, 3, 7
313 };
314 // Upload the vertex positions of the bounding box to the GPU.
315 update_vertex_buffer(bbox_points);
316 // Upload the vertex indices of the bounding box to the GPU.
317 update_element_buffer(bbox_indices);
318 }
319};
320
321
322class MyPointsDrawable : public PointsDrawable {
323public:
324 MyPointsDrawable(const std::string& name = "") : PointsDrawable(name) {}
325
326protected:
327 void update_buffers_internal() {
328 // The coordinates of the vertices.
329 const std::vector<vec3> &points = resource::bunny_vertices;
330 // Upload the vertex positions to the GPU.
331 update_vertex_buffer(points);
332 }
333};
334
335
336int main(int argc, char **argv) {
337 // initialize Easy3D.
338 initialize();
339
340 //-------------------------------------------------------------
341
342 // Create the default Easy3D viewer.
343 // Note: a viewer must be created before creating any drawables.
344 Viewer viewer(EXAMPLE_TITLE);
345 viewer.set_usage("");
346
347 //-------------------------------------------------------------
348
349 // We visualize the "bunny".
350
351 //-------------------------------------------------------------
352 // Create a TrianglesDrawable to visualize the surface of the "bunny".
353 // For visualization, the point positions and the vertex indices of the faces have to be sent to the GPU.
354 auto surface = new MyTrianglesDrawable("faces");
355 // Add the drawable to the viewer
356 viewer.add_drawable(std::shared_ptr<MyTrianglesDrawable>(surface));
357
358 //-------------------------------------------------------------
359 // Create a PointsDrawable to visualize the vertices of the "bunny".
360 // Only the vertex positions have to be sent to the GPU for visualization.
361 auto vertices = new MyPointsDrawable("vertices");
362 // Add the drawable to the viewer
363 viewer.add_drawable(std::shared_ptr<MyPointsDrawable>(vertices));
364 // Set a color for the vertices (here we want a red color).
365 vertices->set_uniform_coloring(vec4(1.0f, 0.0f, 0.0f, 1.0f)); // r, g, b, a
366 // Three options are available for visualizing points:
367 // - PLAIN: plain points (i.e., each point is a square on the screen);
368 // - SPHERE: each point is visualized a sphere;
369 // - SURFEL: each point is visualized an oriented disk.
370 // In this example, let's render the vertices as spheres.
371 vertices->set_impostor_type(PointsDrawable::SPHERE);
372 // Set the vertices size (here 10 pixels).
373 vertices->set_point_size(10);
374
375 //-------------------------------------------------------------
376 // Create a LinesDrawable to visualize the bounding box of the "bunny".
377
378 // Compute the bounding box.
379 auto bbox_drawable = new MyLinesDrawable("bbox");
380 // Add the drawable to the viewer
381 viewer.add_drawable(std::shared_ptr<MyLinesDrawable>(bbox_drawable));
382 // Set a color for the edges of the bounding box (here we want a blue color).
383 bbox_drawable->set_uniform_coloring(vec4(0.0f, 0.0f, 1.0f, 1.0f)); // r, g, b, a
384 // Set the width of the edges (here 5 pixels).
385 bbox_drawable->set_line_width(5.0f);
386
387 //-------------------------------------------------------------
388
389 // Make sure everything is within the visible region of the viewer.
390 viewer.fit_screen();
391
392 // run the viewer
393 return viewer.run();
394}
395
396#endif
The base class for drawable objects. A drawable represent a set of points, line segments,...
Definition drawable.h:58
void update_vertex_buffer(const std::vector< vec3 > &vertices, bool dynamic=false)
Creates/Updates the vertex buffer.
Definition drawable.cpp:139
void update_element_buffer(const std::vector< unsigned int > &elements)
Updates the element buffer.
Definition drawable.cpp:190
FT max_coord(unsigned int axis) const
Return a component of the coordinates of the max corner.
Definition box.h:141
FT min_coord(unsigned int axis) const
Return a component of the coordinates of the min corner.
Definition box.h:129
The drawable for rendering a set of line segments, e.g., edges of a mesh, vector fields.
Definition drawable_lines.h:40
The base class of renderable 3D models.
Definition model.h:50
The drawable for rendering a set of points, e.g., point clouds, vertices of a mesh.
Definition drawable_points.h:42
@ SPHERE
The points will be drawn as spheres.
Definition drawable_points.h:62
The drawable for rendering a set of triangles, e.g., the surface of a triangular mesh.
Definition drawable_triangles.h:46
The built-in Easy3D viewer.
Definition viewer.h:63
Box bounding_box(const Container &points)
Computes the bounding box of a set of points.
Definition types.h:179
EASY3D_UTIL_EXPORT const std::vector< unsigned int > bunny_indices
EASY3D_UTIL_EXPORT const std::vector< vec3 > bunny_vertices
Definition collider.cpp:182
Vec< 3, float > vec3
A 3D point/vector of float type.
Definition types.h:44
void initialize(bool info_to_stdout, bool use_log_file, bool use_setting_file, const std::string &resource_dir)
Initialization of Easy3D.
Definition initializer.cpp:39
GenericBox< 3, float > Box3
A 3D axis-aligned bounding box of float type.
Definition types.h:108
Vec< 4, float > vec4
A 4D point/vector of float type.
Definition types.h:46