@@ -20,8 +20,16 @@ use structopt::StructOpt;
2020#[ derive( Clone , Debug , StructOpt ) ]
2121pub struct ReconstructSubcommandArgs {
2222 /// Path to the input file where the particle positions are stored (supported formats: VTK, binary f32 XYZ, PLY, BGEO)
23- #[ structopt( short = "-i" , parse( from_os_str) ) ]
24- input_file : PathBuf ,
23+ #[ structopt( short = "-i" , long, parse( from_os_str) ) ]
24+ input_file : Option < PathBuf > ,
25+ /// Path to a sequence of particle files that should be processed, use `{}` in the filename to indicated a placeholder
26+ #[ structopt(
27+ name = "input_sequence_pattern" ,
28+ short = "-s" ,
29+ long,
30+ parse( from_os_str)
31+ ) ]
32+ input_sequence : Option < PathBuf > ,
2533 /// Filename for writing the reconstructed surface to disk (default: "{original_filename}_surface.vtk")
2634 #[ structopt( short = "-o" , parse( from_os_str) ) ]
2735 output_file : Option < PathBuf > ,
@@ -158,7 +166,7 @@ mod arguments {
158166 use super :: ReconstructSubcommandArgs ;
159167 use crate :: io;
160168 use anyhow:: { anyhow, Context } ;
161- use log:: { info, warn } ;
169+ use log:: info;
162170 use splashsurf_lib:: nalgebra:: Vector3 ;
163171 use splashsurf_lib:: AxisAlignedBoundingBox3d ;
164172 use std:: convert:: TryFrom ;
@@ -374,55 +382,58 @@ mod arguments {
374382 fn try_from ( args : & ReconstructSubcommandArgs ) -> Result < Self , Self :: Error > {
375383 let output_suffix = "surface" ;
376384
377- // If the input file exists, a single input file should be processed
378- if args. input_file . is_file ( ) {
379- // Use the user defined output file name if provided...
380- let output_file = if let Some ( output_file) = & args. output_file {
381- output_file. clone ( )
382- // ...otherwise, generate one based on the input filename
383- } else {
384- let input_stem = args. input_file . file_stem ( ) . unwrap ( ) . to_string_lossy ( ) ;
385- format ! ( "{}_{}.vtk" , input_stem, output_suffix) . into ( )
386- } ;
387-
388- Self :: try_new (
389- false ,
390- args. input_file . clone ( ) ,
391- args. output_dir . clone ( ) ,
392- output_file,
393- args. output_dm_points . clone ( ) ,
394- args. output_dm_grid . clone ( ) ,
395- args. output_octree . clone ( ) ,
396- )
397- // If the input file does not exist, its possible that a sequence of files should be processed
398- } else {
399- warn ! ( "The input file '{}' does not exist. Assuming this is a pattern for a sequence of files." , args. input_file. display( ) ) ;
385+ if let Some ( input_file) = & args. input_file {
386+ if input_file. is_file ( ) {
387+ // Use the user defined output file name if provided...
388+ let output_file = if let Some ( output_file) = & args. output_file {
389+ output_file. clone ( )
390+ // ...otherwise, generate one based on the input filename
391+ } else {
392+ let input_stem = input_file. file_stem ( ) . unwrap ( ) . to_string_lossy ( ) ;
393+ format ! ( "{}_{}.vtk" , input_stem, output_suffix) . into ( )
394+ } ;
400395
401- // Make sure that the supposed sequence pattern ends with a filename (and not with a path separator)
402- let input_filename = match args. input_file . file_name ( ) {
396+ Self :: try_new (
397+ false ,
398+ input_file. clone ( ) ,
399+ args. output_dir . clone ( ) ,
400+ output_file,
401+ args. output_dm_points . clone ( ) ,
402+ args. output_dm_grid . clone ( ) ,
403+ args. output_octree . clone ( ) ,
404+ )
405+ } else {
406+ return Err ( anyhow ! (
407+ "Input file does not exist: \" {}\" " ,
408+ input_file. display( )
409+ ) ) ;
410+ }
411+ } else if let Some ( input_pattern) = & args. input_sequence {
412+ // Make sure that the sequence pattern ends with a filename (and not with a path separator)
413+ let input_filename = match input_pattern. file_name ( ) {
403414 Some ( input_filename) => input_filename. to_string_lossy ( ) ,
404415 None => {
405416 return Err ( anyhow ! (
406417 "The input file path '{}' does not end with a filename" ,
407- args . input_file . display( )
418+ input_pattern . display( )
408419 ) )
409420 }
410421 } ;
411422
412423 // Make sure that the parent directory of the sequence pattern exists
413- if let Some ( input_dir) = args . input_file . parent ( ) {
424+ if let Some ( input_dir) = input_pattern . parent ( ) {
414425 if !input_dir. is_dir ( ) && input_dir != Path :: new ( "" ) {
415426 return Err ( anyhow ! (
416427 "The parent directory '{}' of the input file path '{}' does not exist" ,
417428 input_dir. display( ) ,
418- args . input_file . display( )
429+ input_pattern . display( )
419430 ) ) ;
420431 }
421432 }
422433
423434 // Make sure that we have a placeholder '{}' in the filename part of the sequence pattern
424435 if input_filename. contains ( "{}" ) {
425- let input_stem = args . input_file . file_stem ( ) . unwrap ( ) . to_string_lossy ( ) ;
436+ let input_stem = input_pattern . file_stem ( ) . unwrap ( ) . to_string_lossy ( ) ;
426437 // Currently, only VTK files are supported for output
427438 let output_filename = format ! (
428439 "{}.vtk" ,
@@ -431,7 +442,7 @@ mod arguments {
431442
432443 Self :: try_new (
433444 true ,
434- args . input_file . clone ( ) ,
445+ input_pattern . clone ( ) ,
435446 args. output_dir . clone ( ) ,
436447 output_filename. into ( ) ,
437448 args. output_dm_points . clone ( ) ,
@@ -440,10 +451,13 @@ mod arguments {
440451 )
441452 } else {
442453 return Err ( anyhow ! (
443- "Input file does not exist or invalid file sequence pattern in input file path '{}'" ,
444- args. input_file. display( )
445- ) ) ;
454+ "The input sequence pattern \" {}\" does not contain a place holder \" {{}}\" " , input_pattern. display( )
455+ ) ) ;
446456 }
457+ } else {
458+ return Err ( anyhow ! (
459+ "Neither an input file path or input sequence pattern was provided"
460+ ) ) ;
447461 }
448462 }
449463 }
0 commit comments