Skip to content

Commit c3a59d8

Browse files
committed
Refactoring of pipeline interface
1 parent 4cc09b4 commit c3a59d8

3 files changed

Lines changed: 67 additions & 17 deletions

File tree

pysplashsurf/src/pipeline.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ fn reconstruction_pipeline_generic<I: Index, R: Real>(
105105
compute_normals,
106106
sph_normals,
107107
normals_smoothing_iters,
108-
interpolate_attributes: Vec::new(),
108+
interpolate_attributes: Some(attributes.iter().map(|a| a.name.clone()).collect()),
109109
mesh_smoothing_iters,
110110
mesh_smoothing_weights,
111111
mesh_smoothing_weights_normalization,
@@ -122,7 +122,7 @@ fn reconstruction_pipeline_generic<I: Index, R: Real>(
122122

123123
splashsurf::reconstruct::reconstruction_pipeline(
124124
particle_positions,
125-
attributes,
125+
&attributes,
126126
&params,
127127
&postprocessing_args,
128128
)

splashsurf/src/cli.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,13 +191,13 @@ mod cli_args_tests {
191191
#[test]
192192
fn verify_reconstruct_cli() {
193193
use clap::CommandFactory;
194-
crate::reconstruct::ReconstructSubcommandArgs::command().debug_assert()
194+
reconstruct::ReconstructSubcommandArgs::command().debug_assert()
195195
}
196196

197197
#[test]
198198
fn verify_convert_cli() {
199199
use clap::CommandFactory;
200-
crate::convert::ConvertSubcommandArgs::command().debug_assert()
200+
convert::ConvertSubcommandArgs::command().debug_assert()
201201
}
202202

203203
#[test]

splashsurf/src/reconstruct.rs

Lines changed: 63 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ pub struct ReconstructionPostprocessingParameters {
460460
/// Number of Laplacian smoothing iterations to apply to normals if normal interpolation is enabled
461461
pub normals_smoothing_iters: Option<usize>,
462462
/// Interpolate point attributes with the given names from the input attributes to the reconstructed surface
463-
pub interpolate_attributes: Vec<String>,
463+
pub interpolate_attributes: Option<Vec<String>>,
464464
/// Number of Laplacian smoothing iterations to apply t the reconstructed mesh
465465
pub mesh_smoothing_iters: Option<usize>,
466466
/// Enable feature weights for mesh smoothing if mesh smoothing enabled. Preserves isolated particles even under strong smoothing.
@@ -487,6 +487,38 @@ pub struct ReconstructionPostprocessingParameters {
487487
pub mesh_aabb_clamp_vertices: bool,
488488
}
489489

490+
impl ReconstructionPostprocessingParameters {
491+
/// Returns a new instance of the post-processing parameters with all postprocessing disabled
492+
pub fn new() -> Self {
493+
ReconstructionPostprocessingParameters {
494+
check_mesh_closed: false,
495+
check_mesh_manifold: false,
496+
check_mesh_orientation: false,
497+
check_mesh_debug: false,
498+
mesh_cleanup: false,
499+
mesh_cleanup_snap_dist: None,
500+
decimate_barnacles: false,
501+
keep_vertices: false,
502+
compute_normals: false,
503+
sph_normals: false,
504+
normals_smoothing_iters: None,
505+
interpolate_attributes: None,
506+
mesh_smoothing_iters: None,
507+
mesh_smoothing_weights: false,
508+
mesh_smoothing_weights_normalization: 0.0,
509+
generate_quads: false,
510+
quad_max_edge_diag_ratio: 0.0,
511+
quad_max_normal_angle: 0.0,
512+
quad_max_interior_angle: 0.0,
513+
output_mesh_smoothing_weights: false,
514+
output_raw_normals: false,
515+
output_raw_mesh: false,
516+
mesh_aabb: None,
517+
mesh_aabb_clamp_vertices: false,
518+
}
519+
}
520+
}
521+
490522
/// Conversion and validation of command line arguments
491523
pub(crate) mod arguments {
492524
use super::{ReconstructSubcommandArgs, ReconstructionPostprocessingParameters};
@@ -619,7 +651,7 @@ pub(crate) mod arguments {
619651
compute_normals: args.normals.into_bool(),
620652
sph_normals: args.sph_normals.into_bool(),
621653
normals_smoothing_iters: args.normals_smoothing_iters,
622-
interpolate_attributes: args.interpolate_attributes.clone(),
654+
interpolate_attributes: Some(args.interpolate_attributes.clone()),
623655
mesh_smoothing_iters: args.mesh_smoothing_iters,
624656
mesh_smoothing_weights: args.mesh_smoothing_weights.into_bool(),
625657
mesh_smoothing_weights_normalization: args.mesh_smoothing_weights_normalization,
@@ -959,11 +991,15 @@ pub(crate) fn reconstruction_pipeline_from_args(
959991
/// Inputs are the particle positions, a (possibly empty) list of attributes defined on the particles,
960992
/// [`Parameters`](splashsurf_lib::Parameters) for the surface reconstruction itself, and a set of parameters for optional
961993
/// post-processing steps.
962-
/// Please note that, unlike the CLI, the parameters for the surface reconstruction are not relative
963-
/// to the particle radius but absolute values.
994+
///
995+
/// * `params`: Please note that, unlike the CLI, any distance parameters for the surface reconstruction are not relative
996+
/// to the particle radius but are **absolute distance values** (see [`Parameters`](splashsurf_lib::Parameters)).
997+
/// * `attributes`: Note that the attributes are not required for the reconstruction itself but can be used for
998+
/// post-processing steps like attribute interpolation to the reconstructed surface. This has to be enabled explicitly
999+
/// in the post-processing parameters (see [`ReconstructionPostprocessingParameters`]).
9641000
pub fn reconstruction_pipeline<I: Index, R: Real>(
9651001
particle_positions: &[Vector3<R>],
966-
attributes: Vec<MeshAttribute<R>>,
1002+
attributes: &[MeshAttribute<R>],
9671003
params: &splashsurf_lib::Parameters<R>,
9681004
postprocessing: &ReconstructionPostprocessingParameters,
9691005
) -> Result<ReconstructionResult<I, R>, anyhow::Error> {
@@ -1018,7 +1054,12 @@ pub fn reconstruction_pipeline<I: Index, R: Real>(
10181054
// Initialize SPH interpolator if required later
10191055
let interpolator_required = postprocessing.mesh_smoothing_weights
10201056
|| postprocessing.sph_normals
1021-
|| !attributes.is_empty();
1057+
|| (!attributes.is_empty()
1058+
&& !postprocessing
1059+
.interpolate_attributes
1060+
.as_ref()
1061+
.map(Vec::is_empty)
1062+
.unwrap_or(true));
10221063
let interpolator = if interpolator_required {
10231064
profile!("initialize interpolator");
10241065
info!("Post-processing: Initializing interpolator...");
@@ -1235,23 +1276,28 @@ pub fn reconstruction_pipeline<I: Index, R: Real>(
12351276
}
12361277

12371278
// Interpolate attributes if requested
1238-
if !attributes.is_empty() {
1279+
if let Some(attribute_names) = &postprocessing.interpolate_attributes
1280+
&& !attributes.is_empty()
1281+
{
12391282
profile!("interpolate attributes");
12401283
info!("Post-processing: Interpolating attributes...");
12411284
let interpolator = interpolator.as_ref().expect("interpolator is required");
12421285

1243-
for attribute in attributes.into_iter() {
1286+
for attribute in attributes
1287+
.iter()
1288+
.filter(|a| attribute_names.contains(&a.name))
1289+
{
12441290
info!("Interpolating attribute \"{}\"...", attribute.name);
12451291

1246-
match attribute.data {
1292+
match &attribute.data {
12471293
AttributeData::ScalarReal(values) => {
12481294
let interpolated_values = interpolator.interpolate_scalar_quantity(
12491295
values.as_slice(),
12501296
mesh_with_data.vertices(),
12511297
true,
12521298
);
12531299
mesh_with_data.point_attributes.push(MeshAttribute::new(
1254-
attribute.name,
1300+
attribute.name.clone(),
12551301
AttributeData::ScalarReal(interpolated_values),
12561302
));
12571303
}
@@ -1262,7 +1308,7 @@ pub fn reconstruction_pipeline<I: Index, R: Real>(
12621308
true,
12631309
);
12641310
mesh_with_data.point_attributes.push(MeshAttribute::new(
1265-
attribute.name,
1311+
attribute.name.clone(),
12661312
AttributeData::Vector3Real(interpolated_values),
12671313
));
12681314
}
@@ -1458,7 +1504,11 @@ pub(crate) fn reconstruction_pipeline_from_path<I: Index, R: Real>(
14581504
// Load particle positions and attributes to interpolate
14591505
let (particle_positions, attributes) = io::read_particle_positions_with_attributes(
14601506
&paths.input_file,
1461-
&postprocessing.interpolate_attributes,
1507+
postprocessing
1508+
.interpolate_attributes
1509+
.as_ref()
1510+
.map(Vec::as_slice)
1511+
.unwrap_or(&[]),
14621512
&io_params.input,
14631513
)
14641514
.with_context(|| {
@@ -1472,7 +1522,7 @@ pub(crate) fn reconstruction_pipeline_from_path<I: Index, R: Real>(
14721522
tri_mesh,
14731523
tri_quad_mesh,
14741524
raw_reconstruction: reconstruction,
1475-
} = reconstruction_pipeline::<I, R>(&particle_positions, attributes, params, postprocessing)?;
1525+
} = reconstruction_pipeline::<I, R>(&particle_positions, &attributes, params, postprocessing)?;
14761526

14771527
if postprocessing.output_raw_mesh {
14781528
profile!("write surface mesh to file");

0 commit comments

Comments
 (0)