* Copyright (C) 2015 Liangliang Nan <liangliang.nan@gmail.com>
* https://3d.bk.tudelft.nl/liangliang/
*
* This file is part of Easy3D. If it is useful in your research/work,
* I would be grateful if you show your appreciation by citing it:
* ------------------------------------------------------------------
* Liangliang Nan.
* Easy3D: a lightweight, easy-to-use, and efficient C++ library
* for processing and rendering 3D data.
* Journal of Open Source Software, 6(64), 3255, 2021.
* ------------------------------------------------------------------
*
* Easy3D is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License Version 3
* as published by the Free Software Foundation.
*
* Easy3D is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
********************************************************************/
#include <easy3d/viewer/viewer.h>
#include <easy3d/core/surface_mesh.h>
#include <easy3d/renderer/drawable_points.h>
#include <easy3d/renderer/drawable_lines.h>
#include <easy3d/renderer/drawable_triangles.h>
#include <easy3d/renderer/renderer.h>
#include <easy3d/util/resource.h>
#include <easy3d/util/initializer.h>
* \example{lineno} Tutorial_302_Imposters/main.cpp
* This example shows how to render imposters, e.g.,
* - points as spheres and surfels;
* - lines as cylinders;
* - lines as cones.
*/
using namespace easy3d;
void create_spheres(SurfaceMesh *mesh) {
PointsDrawable *drawable = mesh->renderer()->add_points_drawable("vertices");
drawable->set_uniform_coloring(vec4(1.0f, 0.0f, 0.0f, 1.0f));
drawable->set_point_size(24.0f);
drawable->set_impostor_type(PointsDrawable::SPHERE);
}
void create_cylinders(SurfaceMesh *mesh) {
LinesDrawable *drawable = mesh->renderer()->add_lines_drawable("edges");
drawable->set_uniform_coloring(vec4(1.0f, 0.67f, 0.5f, 1.0f));
drawable->set_impostor_type(LinesDrawable::CYLINDER);
drawable->set_line_width(6);
}
void create_cones(SurfaceMesh *mesh) {
auto points = mesh->get_vertex_property<vec3>("v:point");
mesh->update_vertex_normals();
auto normals = mesh->get_vertex_property<vec3>("v:normal");
float length = mesh->bounding_box().diagonal_length() * 0.15f;
std::vector<vec3> normal_points;
for (auto v : mesh->vertices()) {
const vec3 &s = points[v];
const vec3 &t = points[v] + normals[v] * length;
normal_points.push_back(s);
normal_points.push_back(t);
}
LinesDrawable *drawable = mesh->renderer()->add_lines_drawable("normals");
drawable->update_vertex_buffer(normal_points);
drawable->set_uniform_coloring(vec4(0.0f, 1.0f, 0.0f, 1.0f));
drawable->set_impostor_type(LinesDrawable::CONE);
drawable->set_line_width(8);
}
void create_surfels(SurfaceMesh *mesh) {
PointsDrawable *drawable = mesh->renderer()->add_points_drawable("vertices");
drawable->set_uniform_coloring(vec4(1.0f, 0.0f, 0.0f, 1.0f));
drawable->set_point_size(24.0f);
drawable->set_impostor_type(PointsDrawable::SURFEL);
}
int main(int argc, char **argv) {
initialize();
Viewer viewer(EXAMPLE_TITLE);
const std::string file_name = resource::directory() + "/data/sphere.obj";
auto mesh = dynamic_cast<SurfaceMesh *>(viewer.add_model(file_name, false));
if (!mesh) {
LOG(ERROR) << "failed to load model. Please make sure the file exists and format is correct.";
return EXIT_FAILURE;
}
create_spheres(mesh);
create_cylinders(mesh);
create_cones(mesh);
auto copy = new SurfaceMesh(*mesh);
const vec3 trans = vec3(0, 1, 0) * mesh->bounding_box().diagonal_length() * 0.7f;
auto points = copy->get_vertex_property<vec3>("v:point");
for (auto v : copy->vertices())
points[v] += trans;
viewer.add_model(std::shared_ptr<SurfaceMesh>(copy), false);
create_surfels(copy);
return viewer.run();
}