You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
108 lines
2.9 KiB
108 lines
2.9 KiB
// This file is part of libigl, a simple c++ geometry processing library.
|
|
//
|
|
// Copyright (C) 2020 Alec Jacobson <alecjacobson@gmail.com>
|
|
//
|
|
// This Source Code Form is subject to the terms of the Mozilla Public License
|
|
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
|
// obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
#include <igl/opengl/glfw/Viewer.h>
|
|
#include <igl/read_triangle_mesh.h>
|
|
#include <igl/blue_noise.h>
|
|
#include <igl/per_vertex_normals.h>
|
|
#include <igl/barycentric_interpolation.h>
|
|
#include <igl/blue_noise.h>
|
|
#include <igl/doublearea.h>
|
|
#include <igl/random_points_on_mesh.h>
|
|
#include <igl/PI.h>
|
|
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
|
|
Eigen::MatrixXd V;
|
|
Eigen::MatrixXi F;
|
|
igl::read_triangle_mesh(
|
|
argc>1?argv[1]: TUTORIAL_SHARED_PATH "/elephant.obj",V,F);
|
|
Eigen::MatrixXd N;
|
|
igl::per_vertex_normals(V,F,N);
|
|
const double bbd = (V.colwise().maxCoeff()- V.colwise().minCoeff()).norm();
|
|
|
|
Eigen::MatrixXd P_blue;
|
|
Eigen::MatrixXd N_blue;
|
|
Eigen::VectorXd A_blue;
|
|
Eigen::MatrixXd C_blue;
|
|
{
|
|
const int n_desired = argc>2?atoi(argv[2]):50000;
|
|
// Heuristic to determine radius from desired number
|
|
const double r = [&V,&F](const int n)
|
|
{
|
|
Eigen::VectorXd A;
|
|
igl::doublearea(V,F,A);
|
|
return sqrt(((A.sum()*0.5/(n*0.6162910373))/igl::PI));
|
|
}(n_desired);
|
|
printf("blue noise radius: %g\n",r);
|
|
Eigen::MatrixXd B;
|
|
Eigen::VectorXi I;
|
|
igl::blue_noise(V,F,r,B,I,P_blue);
|
|
igl::barycentric_interpolation(N,F,B,I,N_blue);
|
|
N_blue.rowwise().normalize();
|
|
}
|
|
Eigen::MatrixXd P_white;
|
|
Eigen::MatrixXd N_white;
|
|
Eigen::VectorXd A_white;
|
|
Eigen::MatrixXd C_white;
|
|
{
|
|
Eigen::MatrixXd B;
|
|
Eigen::VectorXi I;
|
|
igl::random_points_on_mesh(P_blue.rows(),V,F,B,I,P_white);
|
|
igl::barycentric_interpolation(N,F,B,I,N_white);
|
|
N_white.rowwise().normalize();
|
|
}
|
|
|
|
// Color
|
|
Eigen::RowVector3d C(1,1,1);
|
|
|
|
// Plot the mesh
|
|
igl::opengl::glfw::Viewer viewer;
|
|
viewer.data().set_mesh(V,F);
|
|
viewer.data().show_lines = false;
|
|
viewer.data().show_faces = false;
|
|
viewer.data().point_size = 4;
|
|
|
|
bool use_blue = true;
|
|
const auto update = [&]()
|
|
{
|
|
const Eigen::RowVector3d orange(1.0,0.7,0.2);
|
|
if(use_blue)
|
|
{
|
|
viewer.data().set_points(P_blue,Eigen::RowVector3d(0.3,0.4,1.0));
|
|
viewer.data().set_edges_from_vector_field(P_blue,bbd*0.01*N_blue,orange);
|
|
}else
|
|
{
|
|
viewer.data().set_points(P_white,Eigen::RowVector3d(1,1,1));
|
|
viewer.data().set_edges_from_vector_field(P_white,bbd*0.01*N_white,orange);
|
|
}
|
|
};
|
|
update();
|
|
|
|
viewer.callback_key_pressed =
|
|
[&](igl::opengl::glfw::Viewer &,unsigned char key,int)->bool
|
|
{
|
|
switch(key)
|
|
{
|
|
case ' ':
|
|
{
|
|
use_blue = !use_blue;
|
|
update();
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
std::cout<<R"(
|
|
[space] toggle between blue and white noise samplings
|
|
)";
|
|
|
|
viewer.launch();
|
|
}
|
|
|