This example shows how to perform virtual scanning of a given model.
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>
38TutorialVirtualScanner::TutorialVirtualScanner(
const std::string &title)
42 camera()->setUpVector(
vec3(0, 1, 0));
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";
52 hint_ =
"press 'Space' to perform scanning\n"
53 "press 'n' to toggle Gaussian noise";
57bool TutorialVirtualScanner::key_press_event(
int key,
int modifiers) {
58 if (key == KEY_SPACE && modifiers == 0) {
60 framebuffer_size(fw, fh);
63 fbo.add_depth_buffer(GL_DEPTH_COMPONENT32F);
66 glClear(GL_DEPTH_BUFFER_BIT);
70 std::vector<float> depths;
71 fbo.read_depth(depths,
false);
73 const mat4& MVP = camera()->modelViewProjectionMatrix();
74 const mat4& invMVP = inverse(MVP);
75 const int viewport[] = { 0, 0, width_, height_};
77 std::vector<vec3> points;
78 for (
int x=0; x<width_; ++x) {
79 for (
int y=0; y<height_; ++y) {
82 const int idx =
static_cast<int>(
static_cast<float>(y) * dpi_scaling() *
static_cast<float>(fw) +
static_cast<float>(x) * dpi_scaling());
84 const int idx =
static_cast<int>(y * fw + x);
86 const float d = depths[idx];
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);
97 if (!points.empty()) {
99 for (
const auto& p : points)
100 cloud->add_vertex(p);
103 const float ratio = 0.0001f;
105 GaussianNoise::apply(cloud, sigma);
106 std::cout <<
"Gaussian noise added (sigma = " << ratio <<
" * model radius)" << std::endl;
108 add_model(std::shared_ptr<PointCloud>(cloud));
114 else if (key == KEY_N && modifiers == 0) {
115 add_noise_ = !add_noise_;
117 std::cout <<
"add_noise = ON" << std::endl;
119 std::cout <<
"add_noise = OFF" << std::endl;
123 return Viewer::key_press_event(key, modifiers);
An implementation of framebuffer object (FBO).
Definition framebuffer_object.h:122
FT radius() const
Return the radius of the box (i.e., half of its diagonal length).
Definition box.h:252
const Box3 & bounding_box(bool recompute=false) const
The bounding box of the model.
Definition model.cpp:44
A data structure for point clouds.
Definition point_cloud.h:45
Definition collider.cpp:182
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>
47int main(
int argc,
char **argv) {
52 TutorialVirtualScanner viewer(EXAMPLE_TITLE);
54 const std::string file_name = resource::directory() +
"/data/house/house.obj";
55 auto model = viewer.add_model(file_name,
true);
57 LOG(ERROR) <<
"failed to load model. Please make sure the file exists and format is correct.";
61 auto d = model->renderer()->get_points_drawable(
"locks");
63 d->set_visible(
false);