in src/PreprocessMesh.cpp [87:174]
void SampleSDFNearSurface(
KdVertexListTree& kdTree,
std::vector<Eigen::Vector3f>& vertices,
std::vector<Eigen::Vector3f>& xyz_surf,
std::vector<Eigen::Vector3f>& normals,
std::vector<Eigen::Vector3f>& xyz,
std::vector<float>& sdfs,
int num_rand_samples,
float variance,
float second_variance,
float bounding_cube_dim,
int num_votes) {
float stdv = sqrt(variance);
std::random_device seeder;
std::mt19937 generator(seeder());
std::uniform_real_distribution<float> rand_dist(0.0, 1.0);
std::vector<Eigen::Vector3f> xyz_used;
std::vector<Eigen::Vector3f> second_samples;
std::random_device rd;
std::mt19937 rng(rd());
std::uniform_int_distribution<int> vert_ind(0, vertices.size() - 1);
std::normal_distribution<float> perterb_norm(0, stdv);
std::normal_distribution<float> perterb_second(0, sqrt(second_variance));
for (unsigned int i = 0; i < xyz_surf.size(); i++) {
Eigen::Vector3f surface_p = xyz_surf[i];
Eigen::Vector3f samp1 = surface_p;
Eigen::Vector3f samp2 = surface_p;
for (int j = 0; j < 3; j++) {
samp1[j] += perterb_norm(rng);
samp2[j] += perterb_second(rng);
}
xyz.push_back(samp1);
xyz.push_back(samp2);
}
for (int s = 0; s < (int)(num_rand_samples); s++) {
xyz.push_back(Eigen::Vector3f(
rand_dist(generator) * bounding_cube_dim - bounding_cube_dim / 2,
rand_dist(generator) * bounding_cube_dim - bounding_cube_dim / 2,
rand_dist(generator) * bounding_cube_dim - bounding_cube_dim / 2));
}
// now compute sdf for each xyz sample
for (int s = 0; s < (int)xyz.size(); s++) {
Eigen::Vector3f samp_vert = xyz[s];
std::vector<int> cl_indices(num_votes);
std::vector<float> cl_distances(num_votes);
kdTree.knnSearch(samp_vert.data(), num_votes, cl_indices.data(), cl_distances.data());
int num_pos = 0;
float sdf;
for (int ind = 0; ind < num_votes; ind++) {
uint32_t cl_ind = cl_indices[ind];
Eigen::Vector3f cl_vert = vertices[cl_ind];
Eigen::Vector3f ray_vec = samp_vert - cl_vert;
float ray_vec_leng = ray_vec.norm();
if (ind == 0) {
// if close to the surface, use point plane distance
if (ray_vec_leng < stdv)
sdf = fabs(normals[cl_ind].dot(ray_vec));
else
sdf = ray_vec_leng;
}
float d = normals[cl_ind].dot(ray_vec / ray_vec_leng);
if (d > 0)
num_pos++;
}
// all or nothing , else ignore the point
if ((num_pos == 0) || (num_pos == num_votes)) {
xyz_used.push_back(samp_vert);
if (num_pos <= (num_votes / 2)) {
sdf = -sdf;
}
sdfs.push_back(sdf);
}
}
xyz = xyz_used;
}