This example shows how to perform virtual scanning of a given model.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#include "viewer.h"
28#include <easy3d/core/point_cloud.h>
29#include <easy3d/renderer/camera.h>
30#include <easy3d/renderer/framebuffer_object.h>
31#include <easy3d/algo/gaussian_noise.h>
32
33
35
36
37
38TutorialVirtualScanner::TutorialVirtualScanner(const std::string &title)
40 , add_noise_(false)
41{
42 camera()->setUpVector(
vec3(0, 1, 0));
43
44 manual_ =
45 "-------------- Virtual Scanner usage -------------- \n"
46 "- change the view using the mouse.\n"
47 "- press the 'Space' key to perform scanning. Everything (and only those) visible\n"
48 " will be captured in a point cloud.\n"
49 "- press 'n' to toggle Gaussian noise.\n"
50 "---------------------------------------------------------- \n";
51
52 hint_ = "press 'Space' to perform scanning\n"
53 "press 'n' to toggle Gaussian noise";
54}
55
56
57bool TutorialVirtualScanner::key_press_event(int key, int modifiers) {
58 if (key == KEY_SPACE && modifiers == 0) {
59 int fw, fh;
60 framebuffer_size(fw, fh);
61
63 fbo.add_depth_buffer(GL_DEPTH_COMPONENT32F);
64 fbo.bind();
65 glClearDepth(1.0f);
66 glClear(GL_DEPTH_BUFFER_BIT);
67 draw();
68 fbo.release();
69
70 std::vector<float> depths;
71 fbo.read_depth(depths, false);
72
73 const mat4& MVP = camera()->modelViewProjectionMatrix();
75 const int viewport[] = { 0, 0, width_, height_};
76
77 std::vector<vec3> points;
78 for (int x=0; x<width_; ++x) {
79 for (int y=0; y<height_; ++y) {
80
81#if defined(__APPLE__)
82 const int idx = static_cast<int>(static_cast<float>(y) * dpi_scaling() * static_cast<float>(fw) + static_cast<float>(x) * dpi_scaling());
83#else
84 const int idx = static_cast<int>(y * fw + x);
85#endif
86 const float d = depths[idx];
87 if (d < 1.0f) {
88 vec3 vs(
static_cast<float>(x),
static_cast<float>(y), d);
89 vs.x =
static_cast<float>(vs.x -
static_cast<float>(
viewport[0])) /
static_cast<float>(viewport[2]) * 2.0f - 1.0f;
90 vs.y =
static_cast<float>(vs.y -
static_cast<float>(
viewport[1])) /
static_cast<float>(viewport[3]) * 2.0f - 1.0f;
91 vs.z = vs.z * 2.0f - 1.0f;
92 points.push_back(invMVP * vs);
93 }
94 }
95 }
96
97 if (!points.empty()) {
99 for (const auto& p : points)
101
102 if (add_noise_) {
103 const float ratio = 0.0001f;
104 const float sigma = current_model()->bounding_box().radius() * ratio;
106 std::cout << "Gaussian noise added (sigma = " << ratio << " * model radius)" << std::endl;
107 }
108 add_model(std::shared_ptr<PointCloud>(cloud));
109 update();
110 }
111
112 return false;
113 }
114 else if (key == KEY_N && modifiers == 0) {
115 add_noise_ = !add_noise_;
116 if (add_noise_)
117 std::cout << "add_noise = ON" << std::endl;
118 else
119 std::cout << "add_noise = OFF" << std::endl;
120 return false;
121 }
122 else
123 return Viewer::key_press_event(key, modifiers);
124}
125
126
An implementation of framebuffer object (FBO).
Definition framebuffer_object.h:122
static void apply(SurfaceMesh *mesh, float sigma)
Add Gaussian noise (that has a normal distribution) to the surface mesh.
Definition gaussian_noise.cpp:41
A data structure for point clouds.
Definition point_cloud.h:45
Vertex add_vertex(const vec3 &p)
Add a new vertex with position p.
Definition point_cloud.cpp:177
Definition collider.cpp:182
Vec< 3, float > vec3
A 3D point/vector of float type.
Definition types.h:44
Mat< N, N, T > inverse(const Mat< N, N, T > &m)
Returns the inverse of an N x N (square) matrix.
Definition mat.h:1190
Mat4< float > mat4
A 4 by 4 matrix of float type.
Definition types.h:67
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#include "viewer.h"
28#include <easy3d/core/model.h>
29#include <easy3d/renderer/renderer.h>
30#include <easy3d/renderer/drawable_points.h>
31#include <easy3d/util/resource.h>
32#include <easy3d/util/initializer.h>
33
44
46
47int main(int argc, char **argv) {
48
50
51
52 TutorialVirtualScanner viewer(EXAMPLE_TITLE);
53
55 auto model = viewer.add_model(file_name, true);
56 if (!model) {
57 LOG(ERROR) << "failed to load model. Please make sure the file exists and format is correct.";
58 return EXIT_FAILURE;
59 }
60
61 auto d = model->renderer()->get_points_drawable("locks");
62 if (d)
63 d->set_visible(false);
64
65
66 return viewer.run();
67}
68
std::string directory()
Returns the resource directory (containing color maps, shaders, textures, fonts, etc....
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