Extend test with checking simplified model distance to original model

This commit is contained in:
Filip Sykala 2021-07-08 08:33:06 +02:00
parent ed9152d004
commit 35a906139e

View File

@ -103,6 +103,93 @@ TEST_CASE("Split two watertight meshes", "[its_split][its]") {
}
#include <libslic3r/QuadricEdgeCollapse.hpp>
static float triangle_area(const Vec3f &v0, const Vec3f &v1, const Vec3f &v2)
{
Vec3f ab = v1 - v0;
Vec3f ac = v2 - v0;
return ab.cross(ac).norm() / 2.f;
}
static float triangle_area(const Vec3crd &triangle_inices, const std::vector<Vec3f> &vertices)
{
return triangle_area(vertices[triangle_inices[0]],
vertices[triangle_inices[1]],
vertices[triangle_inices[2]]);
}
static std::mt19937 create_random_generator() {
std::random_device rd;
std::mt19937 gen(rd());
return gen;
}
std::vector<Vec3f> its_sample_surface(const indexed_triangle_set &its,
double sample_per_mm2,
std::mt19937 &random_generator = create_random_generator())
{
std::vector<Vec3f> samples;
std::uniform_real_distribution<float> rand01(0.f, 1.f);
for (const auto &triangle_indices : its.indices) {
float area = triangle_area(triangle_indices, its.vertices);
float countf;
float fractional = std::modf(area * sample_per_mm2, &countf);
int count = static_cast<int>(countf);
float generate = rand01(random_generator);
if (generate < fractional) ++count;
if (count == 0) continue;
const Vec3f &v0 = its.vertices[triangle_indices[0]];
const Vec3f &v1 = its.vertices[triangle_indices[1]];
const Vec3f &v2 = its.vertices[triangle_indices[2]];
for (int c = 0; c < count; c++) {
// barycentric coordinate
Vec3f b;
b[0] = rand01(random_generator);
b[1] = rand01(random_generator);
if ((b[0] + b[1]) > 1.f) {
b[0] = 1.f - b[0];
b[1] = 1.f - b[1];
}
b[2] = 1.f - b[0] - b[1];
Vec3f pos;
for (int i = 0; i < 3; i++) {
pos[i] = b[0] * v0[i] + b[1] * v1[i] + b[2] * v2[i];
}
samples.push_back(pos);
}
}
return samples;
}
#include "libslic3r/AABBTreeIndirect.hpp"
// return Average abs distance to original
float compare(const indexed_triangle_set &original,
const indexed_triangle_set &simplified,
double sample_per_mm2)
{
// create ABBTree
auto tree = AABBTreeIndirect::build_aabb_tree_over_indexed_triangle_set(
original.vertices, original.indices);
unsigned int init = 0;
std::mt19937 rnd(init);
auto samples = its_sample_surface(simplified, sample_per_mm2, rnd);
float sumDistance = 0;
for (const Vec3f &sample : samples) {
size_t hit_idx;
Vec3f hit_point;
float distance2 = AABBTreeIndirect::squared_distance_to_indexed_triangle_set(
original.vertices, original.indices, tree, sample, hit_idx,
hit_point);
sumDistance += sqrt(distance2);
}
return sumDistance / samples.size();
}
TEST_CASE("Reduce one edge by Quadric Edge Collapse", "[its]")
{
indexed_triangle_set its;
@ -139,6 +226,8 @@ TEST_CASE("Reduce one edge by Quadric Edge Collapse", "[its]")
(v[i] > v4[i] && v[i] < v2[i]);
CHECK(is_between);
}
float avg_distance = compare(its_, its, 10);
CHECK(avg_distance < 8e-3f);
}
#include "test_utils.hpp"
@ -154,4 +243,7 @@ TEST_CASE("Symplify mesh by Quadric edge collapse to 5%", "[its]")
CHECK(its.indices.size() <= wanted_count);
double volume = its_volume(its);
CHECK(fabs(original_volume - volume) < 30.);
float avg_distance = compare(mesh.its, its, 10);
CHECK(avg_distance < 0.021f); // 0.02022 | 0.0199614074
}