Add triangle mesh split to perf comparison
This commit is contained in:
parent
c8be2cdceb
commit
b14b000c73
@ -24,50 +24,71 @@ static MeasureResult measure_index(const indexed_triangle_set &its, IndexCreator
|
|||||||
{
|
{
|
||||||
Benchmark b;
|
Benchmark b;
|
||||||
|
|
||||||
b.start();
|
|
||||||
ItsNeighborsWrapper itsn{its, fn(its)};
|
|
||||||
b.stop();
|
|
||||||
|
|
||||||
MeasureResult r;
|
MeasureResult r;
|
||||||
r.t_index_create = b.getElapsedSec();
|
for (int i = 0; i < 10; ++i) {
|
||||||
|
b.start();
|
||||||
|
ItsNeighborsWrapper itsn{its, fn(its)};
|
||||||
|
b.stop();
|
||||||
|
|
||||||
b.start();
|
r.t_index_create += b.getElapsedSec();
|
||||||
its_split(itsn);
|
|
||||||
b.stop();
|
|
||||||
|
|
||||||
r.t_split = b.getElapsedSec();
|
b.start();
|
||||||
|
its_split(itsn);
|
||||||
|
b.stop();
|
||||||
|
|
||||||
|
r.t_split += b.getElapsedSec();
|
||||||
|
}
|
||||||
|
|
||||||
|
r.t_index_create /= 10;
|
||||||
|
r.t_split /= 10;
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static TriangleMesh two_spheres(double detail)
|
static indexed_triangle_set two_spheres(double detail)
|
||||||
{
|
{
|
||||||
TriangleMesh sphere1 = make_sphere(10., 2 * PI / detail), sphere2 = sphere1;
|
auto sphere1 = its_make_sphere(10., 2 * PI / detail), sphere2 = sphere1;
|
||||||
|
|
||||||
sphere1.translate(-5.f, 0.f, 0.f);
|
its_transform(sphere1, Transform3f{}.translate(Vec3f{-5.f, 0.f, 0.f}));
|
||||||
sphere2.translate( 5.f, 0.f, 0.f);
|
its_transform(sphere2, Transform3f{}.translate(Vec3f{5.f, 0.f, 0.f}));
|
||||||
|
|
||||||
sphere1.merge(sphere2);
|
its_merge(sphere1, sphere2);
|
||||||
sphere1.require_shared_vertices();
|
|
||||||
|
|
||||||
return sphere1;
|
return sphere1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const std::map<std::string, TriangleMesh> ToMeasure = {
|
static const std::map<std::string, indexed_triangle_set> ToMeasure = {
|
||||||
{"simple", make_cube(10., 10., 10.) },
|
{"simple", its_make_cube(10., 10., 10.) }, // this has 12 faces, 8 vertices
|
||||||
{"two_spheres", two_spheres(200.)},
|
{"two_spheres_1x", two_spheres(60.)},
|
||||||
{"two_spheres_detail", two_spheres(360.)},
|
{"two_spheres_2x", two_spheres(120.)},
|
||||||
{"two_spheres_high_detail", two_spheres(3600.)},
|
{"two_spheres_4x", two_spheres(240.)},
|
||||||
|
{"two_spheres_8x", two_spheres(480.)},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const auto IndexFunctions = std::make_tuple(
|
static const auto IndexFunctions = std::make_tuple(
|
||||||
std::make_pair("tamas's unordered_map based", its_create_neighbors_index_1),
|
std::make_pair("tamas's unordered_map based", [](const auto &its) { return measure_index(its, its_create_neighbors_index_1); }),
|
||||||
std::make_pair("vojta std::sort based", its_create_neighbors_index_2),
|
std::make_pair("vojta std::sort based", [](const auto &its) { return measure_index(its, its_create_neighbors_index_2); }),
|
||||||
std::make_pair("vojta tbb::parallel_sort based", its_create_neighbors_index_3),
|
std::make_pair("vojta tbb::parallel_sort based", [](const auto &its) { return measure_index(its, its_create_neighbors_index_3); }),
|
||||||
std::make_pair("filip's vertex->face based", its_create_neighbors_index_5),
|
std::make_pair("filip's vertex->face based", [](const auto &its) { return measure_index(its, its_create_neighbors_index_5); }),
|
||||||
std::make_pair("tamas's std::sort based", its_create_neighbors_index_6),
|
std::make_pair("tamas's std::sort based", [](const auto &its) { return measure_index(its, its_create_neighbors_index_6); }),
|
||||||
std::make_pair("tamas's tbb::parallel_sort based", its_create_neighbors_index_7),
|
std::make_pair("tamas's tbb::parallel_sort based", [](const auto &its) { return measure_index(its, its_create_neighbors_index_7); }),
|
||||||
std::make_pair("tamas's map based", its_create_neighbors_index_8)
|
std::make_pair("tamas's map based", [](const auto &its) { return measure_index(its, its_create_neighbors_index_8); }),
|
||||||
|
std::make_pair("TriangleMesh split", [](const auto &its) {
|
||||||
|
TriangleMesh m{its};
|
||||||
|
|
||||||
|
MeasureResult ret;
|
||||||
|
for (int i = 0; i < 10; ++i) {
|
||||||
|
Benchmark b;
|
||||||
|
b.start();
|
||||||
|
m.repair();
|
||||||
|
m.split();
|
||||||
|
b.stop();
|
||||||
|
ret.t_split += b.getElapsedSec();
|
||||||
|
}
|
||||||
|
ret.t_split /= 10;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
static constexpr size_t IndexFuncNum = std::tuple_size_v<decltype (IndexFunctions)>;
|
static constexpr size_t IndexFuncNum = std::tuple_size_v<decltype (IndexFunctions)>;
|
||||||
@ -85,13 +106,12 @@ int main(const int argc, const char * argv[])
|
|||||||
auto &name = m.first;
|
auto &name = m.first;
|
||||||
auto &mesh = m.second;
|
auto &mesh = m.second;
|
||||||
libnest2d::opt::metaloop::apply([&mesh, &name, &results, &funcnames](int N, auto &e) {
|
libnest2d::opt::metaloop::apply([&mesh, &name, &results, &funcnames](int N, auto &e) {
|
||||||
MeasureResult r = measure_index(mesh.its, e.second);
|
MeasureResult r = e.second(mesh);
|
||||||
funcnames[N] = e.first;
|
funcnames[N] = e.first;
|
||||||
results[name][N] = r;
|
results[name][N] = r;
|
||||||
}, IndexFunctions);
|
}, IndexFunctions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string outfilename = "out.csv";
|
std::string outfilename = "out.csv";
|
||||||
std::fstream outfile;
|
std::fstream outfile;
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
|
@ -968,20 +968,22 @@ Polygon its_convex_hull_2d_above(const indexed_triangle_set &its, const Transfor
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate the vertex list for a cube solid of arbitrary size in X/Y/Z.
|
// Generate the vertex list for a cube solid of arbitrary size in X/Y/Z.
|
||||||
|
indexed_triangle_set its_make_cube(double xd, double yd, double zd)
|
||||||
|
{
|
||||||
|
auto x = float(xd), y = float(yd), z = float(zd);
|
||||||
|
indexed_triangle_set mesh;
|
||||||
|
mesh.vertices = {{x, y, 0}, {x, 0, 0}, {0, 0, 0}, {0, y, 0},
|
||||||
|
{x, y, z}, {0, y, z}, {0, 0, z}, {x, 0, z}};
|
||||||
|
mesh.indices = {{0, 1, 2}, {0, 2, 3}, {4, 5, 6}, {4, 6, 7},
|
||||||
|
{0, 4, 7}, {0, 7, 1}, {1, 7, 6}, {1, 6, 2},
|
||||||
|
{2, 6, 5}, {2, 5, 3}, {4, 0, 3}, {4, 3, 5}};
|
||||||
|
|
||||||
|
return mesh;
|
||||||
|
}
|
||||||
|
|
||||||
TriangleMesh make_cube(double x, double y, double z)
|
TriangleMesh make_cube(double x, double y, double z)
|
||||||
{
|
{
|
||||||
TriangleMesh mesh(
|
TriangleMesh mesh(its_make_cube(x, y, z));
|
||||||
{
|
|
||||||
{x, y, 0}, {x, 0, 0}, {0, 0, 0},
|
|
||||||
{0, y, 0}, {x, y, z}, {0, y, z},
|
|
||||||
{0, 0, z}, {x, 0, z}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
{0, 1, 2}, {0, 2, 3}, {4, 5, 6},
|
|
||||||
{4, 6, 7}, {0, 4, 7}, {0, 7, 1},
|
|
||||||
{1, 7, 6}, {1, 6, 2}, {2, 6, 5},
|
|
||||||
{2, 5, 3}, {4, 0, 3}, {4, 3, 5}
|
|
||||||
});
|
|
||||||
mesh.repair();
|
mesh.repair();
|
||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
@ -989,31 +991,32 @@ TriangleMesh make_cube(double x, double y, double z)
|
|||||||
// Generate the mesh for a cylinder and return it, using
|
// Generate the mesh for a cylinder and return it, using
|
||||||
// the generated angle to calculate the top mesh triangles.
|
// the generated angle to calculate the top mesh triangles.
|
||||||
// Default is 360 sides, angle fa is in radians.
|
// Default is 360 sides, angle fa is in radians.
|
||||||
TriangleMesh make_cylinder(double r, double h, double fa)
|
indexed_triangle_set its_make_cylinder(double r, double h, double fa)
|
||||||
{
|
{
|
||||||
|
indexed_triangle_set mesh;
|
||||||
size_t n_steps = (size_t)ceil(2. * PI / fa);
|
size_t n_steps = (size_t)ceil(2. * PI / fa);
|
||||||
double angle_step = 2. * PI / n_steps;
|
double angle_step = 2. * PI / n_steps;
|
||||||
|
|
||||||
Pointf3s vertices;
|
auto &vertices = mesh.vertices;
|
||||||
std::vector<Vec3i> facets;
|
auto &facets = mesh.indices;
|
||||||
vertices.reserve(2 * n_steps + 2);
|
vertices.reserve(2 * n_steps + 2);
|
||||||
facets.reserve(4 * n_steps);
|
facets.reserve(4 * n_steps);
|
||||||
|
|
||||||
// 2 special vertices, top and bottom center, rest are relative to this
|
// 2 special vertices, top and bottom center, rest are relative to this
|
||||||
vertices.emplace_back(Vec3d(0.0, 0.0, 0.0));
|
vertices.emplace_back(Vec3f(0.f, 0.f, 0.f));
|
||||||
vertices.emplace_back(Vec3d(0.0, 0.0, h));
|
vertices.emplace_back(Vec3f(0.f, 0.f, float(h)));
|
||||||
|
|
||||||
// for each line along the polygon approximating the top/bottom of the
|
// for each line along the polygon approximating the top/bottom of the
|
||||||
// circle, generate four points and four facets (2 for the wall, 2 for the
|
// circle, generate four points and four facets (2 for the wall, 2 for the
|
||||||
// top and bottom.
|
// top and bottom.
|
||||||
// Special case: Last line shares 2 vertices with the first line.
|
// Special case: Last line shares 2 vertices with the first line.
|
||||||
Vec2d p = Eigen::Rotation2Dd(0.) * Eigen::Vector2d(0, r);
|
Vec2f p = Eigen::Rotation2Df(0.f) * Eigen::Vector2f(0, r);
|
||||||
vertices.emplace_back(Vec3d(p(0), p(1), 0.));
|
vertices.emplace_back(Vec3f(p(0), p(1), 0.f));
|
||||||
vertices.emplace_back(Vec3d(p(0), p(1), h));
|
vertices.emplace_back(Vec3f(p(0), p(1), float(h)));
|
||||||
for (size_t i = 1; i < n_steps; ++i) {
|
for (size_t i = 1; i < n_steps; ++i) {
|
||||||
p = Eigen::Rotation2Dd(angle_step * i) * Eigen::Vector2d(0, r);
|
p = Eigen::Rotation2Df(angle_step * i) * Eigen::Vector2f(0, float(r));
|
||||||
vertices.emplace_back(Vec3d(p(0), p(1), 0.));
|
vertices.emplace_back(Vec3f(p(0), p(1), 0.f));
|
||||||
vertices.emplace_back(Vec3d(p(0), p(1), h));
|
vertices.emplace_back(Vec3f(p(0), p(1), float(h)));
|
||||||
int id = (int)vertices.size() - 1;
|
int id = (int)vertices.size() - 1;
|
||||||
facets.emplace_back( 0, id - 1, id - 3); // top
|
facets.emplace_back( 0, id - 1, id - 3); // top
|
||||||
facets.emplace_back(id, 1, id - 2); // bottom
|
facets.emplace_back(id, 1, id - 2); // bottom
|
||||||
@ -1027,8 +1030,14 @@ TriangleMesh make_cylinder(double r, double h, double fa)
|
|||||||
facets.emplace_back(id, 2, 3);
|
facets.emplace_back(id, 2, 3);
|
||||||
facets.emplace_back(id, id - 1, 2);
|
facets.emplace_back(id, id - 1, 2);
|
||||||
|
|
||||||
TriangleMesh mesh(std::move(vertices), std::move(facets));
|
return mesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
TriangleMesh make_cylinder(double r, double h, double fa)
|
||||||
|
{
|
||||||
|
TriangleMesh mesh{its_make_cylinder(r, h, fa)};
|
||||||
mesh.repair();
|
mesh.repair();
|
||||||
|
|
||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1063,14 +1072,15 @@ TriangleMesh make_cone(double r, double h, double fa)
|
|||||||
// to determine the granularity.
|
// to determine the granularity.
|
||||||
// Default angle is 1 degree.
|
// Default angle is 1 degree.
|
||||||
//FIXME better to discretize an Icosahedron recursively http://www.songho.ca/opengl/gl_sphere.html
|
//FIXME better to discretize an Icosahedron recursively http://www.songho.ca/opengl/gl_sphere.html
|
||||||
TriangleMesh make_sphere(double radius, double fa)
|
indexed_triangle_set its_make_sphere(double radius, double fa)
|
||||||
{
|
{
|
||||||
int sectorCount = int(ceil(2. * M_PI / fa));
|
int sectorCount = int(ceil(2. * M_PI / fa));
|
||||||
int stackCount = int(ceil(M_PI / fa));
|
int stackCount = int(ceil(M_PI / fa));
|
||||||
float sectorStep = float(2. * M_PI / sectorCount);
|
float sectorStep = float(2. * M_PI / sectorCount);
|
||||||
float stackStep = float(M_PI / stackCount);
|
float stackStep = float(M_PI / stackCount);
|
||||||
|
|
||||||
Pointf3s vertices;
|
indexed_triangle_set mesh;
|
||||||
|
auto& vertices = mesh.vertices;
|
||||||
vertices.reserve((stackCount - 1) * sectorCount + 2);
|
vertices.reserve((stackCount - 1) * sectorCount + 2);
|
||||||
for (int i = 0; i <= stackCount; ++ i) {
|
for (int i = 0; i <= stackCount; ++ i) {
|
||||||
// from pi/2 to -pi/2
|
// from pi/2 to -pi/2
|
||||||
@ -1078,16 +1088,16 @@ TriangleMesh make_sphere(double radius, double fa)
|
|||||||
double xy = radius * cos(stackAngle);
|
double xy = radius * cos(stackAngle);
|
||||||
double z = radius * sin(stackAngle);
|
double z = radius * sin(stackAngle);
|
||||||
if (i == 0 || i == stackCount)
|
if (i == 0 || i == stackCount)
|
||||||
vertices.emplace_back(Vec3d(xy, 0., z));
|
vertices.emplace_back(Vec3f(float(xy), 0.f, float(z)));
|
||||||
else
|
else
|
||||||
for (int j = 0; j < sectorCount; ++ j) {
|
for (int j = 0; j < sectorCount; ++ j) {
|
||||||
// from 0 to 2pi
|
// from 0 to 2pi
|
||||||
double sectorAngle = sectorStep * j;
|
double sectorAngle = sectorStep * j;
|
||||||
vertices.emplace_back(Vec3d(xy * cos(sectorAngle), xy * sin(sectorAngle), z));
|
vertices.emplace_back(Vec3d(xy * std::cos(sectorAngle), xy * std::sin(sectorAngle), z).cast<float>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Vec3i> facets;
|
auto& facets = mesh.indices;
|
||||||
facets.reserve(2 * (stackCount - 1) * sectorCount);
|
facets.reserve(2 * (stackCount - 1) * sectorCount);
|
||||||
for (int i = 0; i < stackCount; ++ i) {
|
for (int i = 0; i < stackCount; ++ i) {
|
||||||
// Beginning of current stack.
|
// Beginning of current stack.
|
||||||
@ -1112,8 +1122,15 @@ TriangleMesh make_sphere(double radius, double fa)
|
|||||||
k2 = k2_next;
|
k2 = k2_next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TriangleMesh mesh(std::move(vertices), std::move(facets));
|
|
||||||
|
return mesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
TriangleMesh make_sphere(double radius, double fa)
|
||||||
|
{
|
||||||
|
TriangleMesh mesh(its_make_sphere(radius, fa));
|
||||||
mesh.repair();
|
mesh.repair();
|
||||||
|
|
||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,8 +179,14 @@ void its_merge(indexed_triangle_set &A, const indexed_triangle_set &B);
|
|||||||
void its_merge(indexed_triangle_set &A, const std::vector<Vec3f> &triangles);
|
void its_merge(indexed_triangle_set &A, const std::vector<Vec3f> &triangles);
|
||||||
void its_merge(indexed_triangle_set &A, const Pointf3s &triangles);
|
void its_merge(indexed_triangle_set &A, const Pointf3s &triangles);
|
||||||
|
|
||||||
|
indexed_triangle_set its_make_cube(double x, double y, double z);
|
||||||
TriangleMesh make_cube(double x, double y, double z);
|
TriangleMesh make_cube(double x, double y, double z);
|
||||||
|
|
||||||
|
// Generate a TriangleMesh of a cylinder
|
||||||
|
indexed_triangle_set its_make_cylinder(double r, double h, double fa=(2*PI/360));
|
||||||
TriangleMesh make_cylinder(double r, double h, double fa=(2*PI/360));
|
TriangleMesh make_cylinder(double r, double h, double fa=(2*PI/360));
|
||||||
|
|
||||||
|
indexed_triangle_set its_make_sphere(double rho, double fa=(2*PI/360));
|
||||||
TriangleMesh make_cone(double r, double h, double fa=(2*PI/360));
|
TriangleMesh make_cone(double r, double h, double fa=(2*PI/360));
|
||||||
TriangleMesh make_sphere(double rho, double fa=(2*PI/360));
|
TriangleMesh make_sphere(double rho, double fa=(2*PI/360));
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user