Skip to content

Commit 9b9fb4a

Browse files
committed
Add tests for CLI pipeline functionality
1 parent d582e94 commit 9b9fb4a

File tree

4 files changed

+363
-1
lines changed

4 files changed

+363
-1
lines changed

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

splashsurf/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,6 @@ lexical-sort = "0.3"
2727
indicatif = "0.18"
2828
parking_lot = "0.12"
2929
once_cell = "1.18"
30+
31+
[dev-dependencies]
32+
all_asserts = "2.3.3"

splashsurf/tests/test_pipeline.rs

Lines changed: 352 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,352 @@
1+
use splashsurf_lib::io::vtk_format;
2+
use splashsurf_lib::nalgebra::Vector3;
3+
use splashsurf_lib::{Aabb3d, GridDecompositionParameters, SpatialDecomposition};
4+
5+
use all_asserts::assert_range;
6+
7+
#[test]
8+
fn test_basic_pipeline() -> Result<(), Box<dyn std::error::Error>> {
9+
let particles =
10+
splashsurf_lib::io::particles_from_file("../data/bunny_frame_14_7705_particles.vtk")?;
11+
12+
let particle_radius = 0.025;
13+
let mut params = splashsurf_lib::Parameters::new_relative(particle_radius, 4.0, 1.0);
14+
params.spatial_decomposition = SpatialDecomposition::None;
15+
16+
let mut postprocessing = splashsurf::reconstruct::ReconstructionPostprocessingParameters::new();
17+
postprocessing.output_raw_mesh = true;
18+
19+
let reconstruction = splashsurf::reconstruct::reconstruction_pipeline::<i64, _>(
20+
&particles,
21+
&[],
22+
&params,
23+
&postprocessing,
24+
)?;
25+
let mesh = &reconstruction
26+
.tri_mesh
27+
.as_ref()
28+
.expect("reconstruction should produce a triangle mesh")
29+
.mesh;
30+
let raw_mesh = reconstruction
31+
.raw_reconstruction
32+
.as_ref()
33+
.expect("raw surface should be present")
34+
.mesh();
35+
vtk_format::write_vtk(mesh, "../out/bunny_test_basic_pipeline.vtk", "mesh")?;
36+
37+
// Compare raw and final mesh
38+
assert_eq!(
39+
mesh.triangles.len(),
40+
raw_mesh.triangles.len(),
41+
"Number of triangles should match between raw and final mesh"
42+
);
43+
assert_eq!(
44+
mesh.vertices.len(),
45+
raw_mesh.vertices.len(),
46+
"Number of vertices should match between raw and final mesh"
47+
);
48+
assert_eq!(
49+
mesh.triangles, raw_mesh.triangles,
50+
"Triangle indices should match between raw and final mesh"
51+
);
52+
// Check number of triangles and vertices
53+
assert_range!(
54+
(35000..40000),
55+
raw_mesh.triangles.len(),
56+
"Number of triangles should be in expected range"
57+
);
58+
assert_range!(
59+
(15000..20000),
60+
raw_mesh.vertices.len(),
61+
"Number of vertices should be in expected range"
62+
);
63+
// Check manifoldness
64+
let mesh_manifold_information = mesh.compute_manifold_information();
65+
assert!(
66+
mesh_manifold_information.is_closed(),
67+
"Mesh should be closed"
68+
);
69+
assert!(
70+
mesh_manifold_information.is_manifold(),
71+
"Mesh should be manifold"
72+
);
73+
74+
Ok(())
75+
}
76+
77+
#[test]
78+
#[cfg_attr(debug_assertions, ignore)]
79+
fn test_basic_pipeline_fine() -> Result<(), Box<dyn std::error::Error>> {
80+
let particles =
81+
splashsurf_lib::io::particles_from_file("../data/bunny_frame_14_7705_particles.vtk")?;
82+
83+
let particle_radius = 0.025;
84+
let mut params = splashsurf_lib::Parameters::new_relative(particle_radius, 4.0, 0.2);
85+
params.spatial_decomposition = SpatialDecomposition::UniformGrid(GridDecompositionParameters {
86+
subdomain_num_cubes_per_dim: 48,
87+
auto_disable: false,
88+
});
89+
90+
let postprocessing = splashsurf::reconstruct::ReconstructionPostprocessingParameters::new();
91+
92+
let reconstruction = splashsurf::reconstruct::reconstruction_pipeline::<i64, _>(
93+
&particles,
94+
&[],
95+
&params,
96+
&postprocessing,
97+
)?;
98+
let mesh = &reconstruction
99+
.tri_mesh
100+
.as_ref()
101+
.expect("reconstruction should produce a triangle mesh")
102+
.mesh;
103+
vtk_format::write_vtk(mesh, "../out/bunny_test_basic_pipeline_fine.vtk", "mesh")?;
104+
105+
assert_range!(
106+
(920000..930000),
107+
mesh.triangles.len(),
108+
"Number of triangles should be in expected range"
109+
);
110+
assert_range!(
111+
(455000..465000),
112+
mesh.vertices.len(),
113+
"Number of vertices should be in expected range"
114+
);
115+
116+
let mesh_manifold_information = mesh.compute_manifold_information();
117+
assert!(
118+
mesh_manifold_information.is_closed(),
119+
"Mesh should be closed"
120+
);
121+
assert!(
122+
mesh_manifold_information.is_manifold(),
123+
"Mesh should be manifold"
124+
);
125+
126+
Ok(())
127+
}
128+
129+
#[test]
130+
fn test_basic_pipeline_particle_aabb() -> Result<(), Box<dyn std::error::Error>> {
131+
let particles =
132+
splashsurf_lib::io::particles_from_file("../data/bunny_frame_14_7705_particles.vtk")?;
133+
let particle_radius = 0.025;
134+
135+
let mut params = splashsurf_lib::Parameters::new_relative(particle_radius, 4.0, 1.0);
136+
params.particle_aabb = Some(Aabb3d::new(
137+
Vector3::new(-0.7, 0.6, -0.2),
138+
Vector3::new(0.8, 2.1, 0.7),
139+
));
140+
141+
let postprocessing = splashsurf::reconstruct::ReconstructionPostprocessingParameters::new();
142+
143+
let reconstruction = splashsurf::reconstruct::reconstruction_pipeline::<i64, _>(
144+
&particles,
145+
&[],
146+
&params,
147+
&postprocessing,
148+
)?;
149+
let mesh = &reconstruction
150+
.tri_mesh
151+
.as_ref()
152+
.expect("reconstruction should produce a triangle mesh")
153+
.mesh;
154+
vtk_format::write_vtk(
155+
mesh,
156+
"../out/bunny_test_basic_pipeline_particle_aabb.vtk",
157+
"mesh",
158+
)?;
159+
160+
assert_range!(
161+
(19000..23000),
162+
mesh.triangles.len(),
163+
"Number of triangles should be in expected range"
164+
);
165+
assert_range!(
166+
(9500..11500),
167+
mesh.vertices.len(),
168+
"Number of vertices should be in expected range"
169+
);
170+
171+
let mesh_manifold_information = mesh.compute_manifold_information();
172+
assert!(
173+
mesh_manifold_information.is_closed(),
174+
"Mesh should be closed"
175+
);
176+
assert!(
177+
mesh_manifold_information.is_manifold(),
178+
"Mesh should be manifold"
179+
);
180+
181+
Ok(())
182+
}
183+
184+
#[test]
185+
fn test_basic_pipeline_postprocessing() -> Result<(), Box<dyn std::error::Error>> {
186+
let particles =
187+
splashsurf_lib::io::particles_from_file("../data/bunny_frame_14_7705_particles.vtk")?;
188+
let particle_radius = 0.025;
189+
190+
let params = splashsurf_lib::Parameters::new_relative(particle_radius, 4.0, 1.0);
191+
192+
let mut postprocessing = splashsurf::reconstruct::ReconstructionPostprocessingParameters::new();
193+
postprocessing.mesh_cleanup = true;
194+
postprocessing.mesh_smoothing_weights = true;
195+
postprocessing.mesh_smoothing_iters = Some(5);
196+
postprocessing.output_mesh_smoothing_weights = true;
197+
postprocessing.output_raw_mesh = true;
198+
199+
let reconstruction = splashsurf::reconstruct::reconstruction_pipeline::<i64, _>(
200+
&particles,
201+
&[],
202+
&params,
203+
&postprocessing,
204+
)?;
205+
let mesh = &reconstruction
206+
.tri_mesh
207+
.as_ref()
208+
.expect("reconstruction should produce a triangle mesh")
209+
.mesh;
210+
let raw_mesh = reconstruction
211+
.raw_reconstruction
212+
.as_ref()
213+
.expect("raw surface should be present")
214+
.mesh();
215+
vtk_format::write_vtk(
216+
mesh,
217+
"../out/bunny_test_basic_pipeline_postprocessing.vtk",
218+
"mesh",
219+
)?;
220+
221+
assert_ne!(
222+
mesh.triangles.len(),
223+
raw_mesh.triangles.len(),
224+
"Number of triangles should differ between raw and postprocessed mesh"
225+
);
226+
assert_ne!(
227+
mesh.vertices.len(),
228+
raw_mesh.vertices.len(),
229+
"Number of vertices should differ between raw and postprocessed mesh"
230+
);
231+
232+
assert_eq!(
233+
reconstruction
234+
.tri_mesh
235+
.as_ref()
236+
.unwrap()
237+
.point_attributes
238+
.len(),
239+
2,
240+
"There should be two point attributes (number of neighbors and smoothing weights)"
241+
);
242+
243+
assert_range!(
244+
(18000..22000),
245+
mesh.triangles.len(),
246+
"Number of triangles should be in expected range"
247+
);
248+
assert_range!(
249+
(8000..12000),
250+
mesh.vertices.len(),
251+
"Number of vertices should be in expected range"
252+
);
253+
254+
let mesh_manifold_information = mesh.compute_manifold_information();
255+
assert!(
256+
mesh_manifold_information.is_closed(),
257+
"Mesh should be closed"
258+
);
259+
assert!(
260+
mesh_manifold_information.is_manifold(),
261+
"Mesh should be manifold"
262+
);
263+
264+
Ok(())
265+
}
266+
267+
#[test]
268+
fn test_basic_pipeline_postprocessing_with_aabb() -> Result<(), Box<dyn std::error::Error>> {
269+
let particles =
270+
splashsurf_lib::io::particles_from_file("../data/bunny_frame_14_7705_particles.vtk")?;
271+
let particle_radius = 0.025;
272+
273+
let mut params = splashsurf_lib::Parameters::new_relative(particle_radius, 4.0, 1.0);
274+
params.particle_aabb = Some(Aabb3d::new(
275+
Vector3::new(-0.7, 0.6, -0.2),
276+
Vector3::new(0.8, 2.1, 0.7),
277+
));
278+
279+
let mut postprocessing = splashsurf::reconstruct::ReconstructionPostprocessingParameters::new();
280+
postprocessing.mesh_cleanup = true;
281+
postprocessing.mesh_smoothing_weights = true;
282+
postprocessing.mesh_smoothing_iters = Some(5);
283+
postprocessing.output_mesh_smoothing_weights = true;
284+
postprocessing.output_raw_mesh = true;
285+
286+
let reconstruction = splashsurf::reconstruct::reconstruction_pipeline::<i64, _>(
287+
&particles,
288+
&[],
289+
&params,
290+
&postprocessing,
291+
)?;
292+
let mesh = &reconstruction
293+
.tri_mesh
294+
.as_ref()
295+
.expect("reconstruction should produce a triangle mesh")
296+
.mesh;
297+
let raw_mesh = reconstruction
298+
.raw_reconstruction
299+
.as_ref()
300+
.expect("raw surface should be present")
301+
.mesh();
302+
vtk_format::write_vtk(
303+
mesh,
304+
"../out/bunny_test_basic_pipeline_postprocessing_aabb.vtk",
305+
"mesh",
306+
)?;
307+
308+
assert_ne!(
309+
mesh.triangles.len(),
310+
raw_mesh.triangles.len(),
311+
"Number of triangles should differ between raw and postprocessed mesh"
312+
);
313+
assert_ne!(
314+
mesh.vertices.len(),
315+
raw_mesh.vertices.len(),
316+
"Number of vertices should differ between raw and postprocessed mesh"
317+
);
318+
319+
assert_eq!(
320+
reconstruction
321+
.tri_mesh
322+
.as_ref()
323+
.unwrap()
324+
.point_attributes
325+
.len(),
326+
2,
327+
"There should be two point attributes (number of neighbors and smoothing weights)"
328+
);
329+
330+
assert_range!(
331+
(11000..13000),
332+
mesh.triangles.len(),
333+
"Number of triangles should be in expected range"
334+
);
335+
assert_range!(
336+
(5000..7000),
337+
mesh.vertices.len(),
338+
"Number of vertices should be in expected range"
339+
);
340+
341+
let mesh_manifold_information = mesh.compute_manifold_information();
342+
assert!(
343+
mesh_manifold_information.is_closed(),
344+
"Mesh should be closed"
345+
);
346+
assert!(
347+
mesh_manifold_information.is_manifold(),
348+
"Mesh should be manifold"
349+
);
350+
351+
Ok(())
352+
}

splashsurf_lib/src/marching_cubes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ pub fn check_mesh_consistency<I: Index, R: Real>(
190190
}
191191

192192
if check_manifold && !non_manifold_edges.is_empty() {
193-
error_strings.push(format!("Mesh is not manifold. It has {} non-manifold edges (edges that are connected to more than twi triangles).", non_manifold_edges.len()));
193+
error_strings.push(format!("Mesh is not manifold. It has {} non-manifold edges (edges that are connected to more than two triangles).", non_manifold_edges.len()));
194194
if debug {
195195
for e in non_manifold_edges {
196196
add_edge_errors(&mut error_strings, e);

0 commit comments

Comments
 (0)