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.

109 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();
}