Skip to content

Commit 181f816

Browse files
committed
Add benchmark for libigl
1 parent 9988e3b commit 181f816

File tree

7 files changed

+145
-8
lines changed

7 files changed

+145
-8
lines changed

CMakeLists.txt

+3-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ option(KIGUMI_BUILD_CLI "Build the command-line interface" ON)
55
option(KIGUMI_BUILD_TESTS "Build the unit tests" ON)
66

77
if(KIGUMI_BUILD_BENCHES)
8-
list(APPEND VCPKG_MANIFEST_FEATURES "bench-geogram" "bench-manifold" "bench-mcut")
8+
list(APPEND VCPKG_MANIFEST_FEATURES "bench-geogram" "bench-libigl" "bench-manifold" "bench-mcut")
99
endif()
1010

1111
project(kigumi CXX)
@@ -46,6 +46,8 @@ target_link_libraries(${TARGET} INTERFACE
4646
)
4747

4848
if(KIGUMI_BUILD_BENCHES)
49+
find_package(Eigen3 CONFIG REQUIRED)
50+
find_package(libigl CONFIG REQUIRED)
4951
find_package(PkgConfig REQUIRED)
5052
pkg_check_modules(Clipper2 REQUIRED IMPORTED_TARGET Clipper2)
5153

README.md

+10-7
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,15 @@ and [Boolean_region_builder.h](include/kigumi/Boolean_region_builder.h).
2121

2222
Here are the timings (in seconds) for computing the Boolean intersection between meshes, excluding I/O time:
2323

24-
| Test case | [coref.][coref] (seq.) | [geogram][geogram] (par.) | kigumi (seq.)¹ | kigumi (par.) | [manif.][manif] (seq.) | manif. (par.)² | [MCUT][mcut] (par.) |
25-
|-------------------|-----------------------:|--------------------------:|---------------:|--------------:|-----------------------:|---------------:|--------------------:|
26-
| **Open** | 4.6 | FAILED | 2.4 | 1.3 | FAILED | FAILED | FAILED |
27-
| **Open & closed** | FAILED | 70.5 | 1.6 | 0.9 | FAILED | FAILED | FAILED |
28-
| **Closed** | 57.4 | FAILED | 5.3 | 2.7 | 8.9 | 1.7 | 24.5 |
29-
| **Non-manifold** | FAILED | FAILED | 0.5 | 0.3 | FAILED | FAILED | FAILED |
24+
| Test case | [coref.][coref] (seq.) | [geogram][geogram] (par.) | kigumi (seq.)¹ | kigumi (par.) | [libigl][libigl] (seq.)² | [manif.][manif] (seq.) | manif. (par.)³ | [MCUT][mcut] (par.) |
25+
|-------------------|-----------------------:|--------------------------:|---------------:|--------------:|-------------------------:|-----------------------:|---------------:|--------------------:|
26+
| **Open** | 4.6 | FAILED | 2.4 | 1.3 | FAILED | FAILED | FAILED | FAILED |
27+
| **Open & closed** | FAILED | 70.5 | 1.6 | 0.9 | FAILED | FAILED | FAILED | FAILED |
28+
| **Closed** | 57.4 | FAILED | 5.3 | 2.7 | 61.0 | 8.9 | 1.7 | 24.5 |
29+
| **Non-manifold** | FAILED | FAILED | 0.5 | 0.3 | FAILED | FAILED | FAILED | FAILED |
3030

31-
¹ Ran with `KIGUMI_NUM_THREADS=1`. ² Configured with `-DMANIFOLD_PAR=TBB`.
31+
¹ Ran with `KIGUMI_NUM_THREADS=1`. ² `igl::copyleft::cgal::mesh_boolean` with `CGAL::Lazy_exact_nt<mpq_class>` as the
32+
number type was used. ³ Configured with `-DMANIFOLD_PAR=TBB`.
3233

3334
Benchmarks were performed on a MacBook Pro 13" (M1, 2020). Programs were built with Homebrew Clang 18.1.8. The following
3435
commands were used:
@@ -100,6 +101,8 @@ An enhanced version of the algorithm described in [[1]](#1) is used.
100101

101102
[geogram]: https://github.com/BrunoLevy/geogram
102103

104+
[libigl]: https://github.com/libigl/libigl
105+
103106
[manif]: https://github.com/elalish/manifold
104107

105108
[mcut]: https://github.com/cutdigital/mcut

benches/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
add_subdirectory(corefinement)
22
add_subdirectory(geogram)
33
add_subdirectory(kigumi)
4+
add_subdirectory(libigl)
45
add_subdirectory(manifold)
56
add_subdirectory(mcut)

benches/libigl/CMakeLists.txt

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
set(TARGET kigumi_bench_libigl)
2+
3+
add_executable(${TARGET}
4+
main.cc
5+
)
6+
7+
set_target_properties(${TARGET} PROPERTIES
8+
OUTPUT_NAME libigl
9+
)
10+
11+
if(UNIX)
12+
target_compile_options(${TARGET} PRIVATE -Wall -Wextra -Werror)
13+
elseif(MSVC)
14+
target_compile_options(${TARGET} PRIVATE /W4 /WX /wd4702)
15+
endif()
16+
17+
target_link_libraries(${TARGET} PRIVATE
18+
CGAL::CGAL
19+
Eigen3::Eigen
20+
igl::igl_core
21+
igl_copyleft::igl_copyleft_cgal
22+
igl_copyleft::igl_copyleft_core
23+
kigumi
24+
)

benches/libigl/main.cc

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
2+
#include <igl/copyleft/cgal/mesh_boolean.h>
3+
#include <kigumi/Triangle_soup.h>
4+
#include <kigumi/Triangle_soup_io.h>
5+
6+
#include <Eigen/Core>
7+
#include <chrono>
8+
#include <exception>
9+
#include <iostream>
10+
#include <string>
11+
#include <vector>
12+
13+
using K = CGAL::Exact_predicates_exact_constructions_kernel;
14+
using Triangle_soup = kigumi::Triangle_soup<K>;
15+
using Faces = Eigen::Matrix<int, Eigen::Dynamic, 3>;
16+
using Vertices = Eigen::Matrix<typename K::FT, Eigen::Dynamic, 3>;
17+
using kigumi::read_triangle_soup;
18+
using kigumi::Vertex_index;
19+
using kigumi::write_triangle_soup;
20+
21+
namespace {
22+
23+
struct Mesh {
24+
Vertices vertices;
25+
Faces faces;
26+
};
27+
28+
bool read_mesh(const std::string& filename, Mesh& mesh) {
29+
Triangle_soup soup;
30+
if (!read_triangle_soup(filename, soup)) {
31+
return false;
32+
}
33+
34+
mesh.vertices.resize(soup.vertices().size(), 3);
35+
for (auto vi : soup.vertices()) {
36+
const auto& p = soup.point(vi);
37+
auto row = mesh.vertices.row(vi.idx());
38+
row << p.x(), p.y(), p.z();
39+
}
40+
mesh.faces.resize(soup.faces().size(), 3);
41+
for (auto fi : soup.faces()) {
42+
const auto& f = soup.face(fi);
43+
auto row = mesh.faces.row(fi.idx());
44+
row << f[0].idx(), f[1].idx(), f[2].idx();
45+
}
46+
47+
return true;
48+
}
49+
50+
bool write_mesh(const std::string& filename, const Mesh& mesh) {
51+
Triangle_soup soup;
52+
for (auto row : mesh.vertices.rowwise()) {
53+
soup.add_vertex({row(0), row(1), row(2)});
54+
}
55+
for (auto row : mesh.faces.rowwise()) {
56+
soup.add_face({Vertex_index{static_cast<std::size_t>(row(0))},
57+
Vertex_index{static_cast<std::size_t>(row(1))},
58+
Vertex_index{static_cast<std::size_t>(row(2))}});
59+
}
60+
61+
return write_triangle_soup(filename, soup);
62+
}
63+
64+
} // namespace
65+
66+
int main(int argc, char* argv[]) {
67+
try {
68+
std::vector<std::string> args(argv + 1, argv + argc);
69+
70+
Mesh first;
71+
Mesh second;
72+
Mesh result;
73+
74+
read_mesh(args.at(0), first);
75+
read_mesh(args.at(1), second);
76+
77+
auto start = std::chrono::high_resolution_clock::now();
78+
igl::copyleft::cgal::mesh_boolean(first.vertices, first.faces, second.vertices, second.faces,
79+
igl::MESH_BOOLEAN_TYPE_INTERSECT, result.vertices,
80+
result.faces);
81+
auto end = std::chrono::high_resolution_clock::now();
82+
std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(end - start) << std::endl;
83+
84+
write_mesh(args.at(2), result);
85+
86+
return 0;
87+
} catch (const std::exception& e) {
88+
std::cerr << "error: " << e.what() << std::endl;
89+
return 1;
90+
} catch (...) {
91+
std::cerr << "unknown error" << std::endl;
92+
return 1;
93+
}
94+
}

tools/bench_methods.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
corefinement
22
geogram
33
kigumi
4+
libigl
45
manifold
56
mcut

vcpkg.json

+12
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,18 @@
1717
"bench-geogram": {
1818
"description": "Build the benchmark for geogram"
1919
},
20+
"bench-libigl": {
21+
"description": "Build the benchmark for libigl",
22+
"dependencies": [
23+
"eigen3",
24+
{
25+
"name": "libigl",
26+
"features": [
27+
"cgal"
28+
]
29+
}
30+
]
31+
},
2032
"bench-manifold": {
2133
"description": "Build the benchmark for manifold",
2234
"dependencies": [

0 commit comments

Comments
 (0)