@@ -523,11 +523,15 @@ def convert_tris_to_quads(
523523def reconstruction_pipeline (
524524 particles , * , attributes_to_interpolate = {}, particle_radius ,
525525 rest_density = 1000.0 , smoothing_length = 2.0 , cube_size ,
526- iso_surface_threshold = 0.6 , enable_multi_threading = True , mesh_smoothing_weights = False , sph_normals = False ,
526+ iso_surface_threshold = 0.6 , enable_multi_threading = True ,
527+ check_mesh_closed = False , check_mesh_manifold = False ,
528+ check_mesh_orientation = False , check_mesh_debug = False ,
529+ mesh_smoothing_weights = False , sph_normals = False ,
527530 mesh_smoothing_weights_normalization = 13.0 , mesh_smoothing_iters = None , normals_smoothing_iters = None ,
528- mesh_cleanup = False , decimate_barnacles = False , keep_vertices = False ,
529- compute_normals = False , output_raw_normals = False , output_mesh_smoothing_weights = False , mesh_aabb_clamp_vertices = False ,
530- subdomain_grid = True , subdomain_num_cubes_per_dim = 64 , aabb_min = None , aabb_max = None , mesh_aabb_min = None , mesh_aabb_max = None
531+ mesh_cleanup = False , mesh_cleanup_snap_dist = None , decimate_barnacles = False , keep_vertices = False ,
532+ compute_normals = False , output_raw_normals = False , output_raw_mesh = False , output_mesh_smoothing_weights = False , mesh_aabb_clamp_vertices = False ,
533+ subdomain_grid = True , subdomain_num_cubes_per_dim = 64 , aabb_min = None , aabb_max = None , mesh_aabb_min = None , mesh_aabb_max = None ,
534+ generate_quads = False , quad_max_edge_diag_ratio = 1.75 , quad_max_normal_angle = 10.0 , quad_max_interior_angle = 135.0
531535):
532536 """Surface reconstruction based on particle positions with subsequent post-processing
533537
@@ -558,6 +562,18 @@ def reconstruction_pipeline(
558562
559563 enable_multi_threading: bool
560564 Multi-threading flag
565+
566+ check_mesh_closed: bool
567+ Enable checking the final mesh for holes
568+
569+ check_mesh_manifold: bool
570+ Enable checking the final mesh for non-manifold edges and vertices
571+
572+ check_mesh_orientation: bool
573+ Enable checking the final mesh for inverted triangles (compares angle between vertex normals and adjacent face normals)
574+
575+ check_mesh_debug: bool
576+ Enable additional debug output for the check-mesh operations (has no effect if no other check-mesh option is enabled)
561577
562578 sph_normals: bool
563579 Flag to compute normals using SPH interpolation instead of geometry-based normals.
@@ -578,6 +594,9 @@ def reconstruction_pipeline(
578594 mesh_cleanup: bool
579595 Flag to perform mesh cleanup\n
580596 This implements the method from “Compact isocontours from sampled data” (Moore, Warren; 1992)
597+
598+ mesh_cleanup_snap_dist: float
599+ If MC mesh cleanup is enabled, vertex snapping can be limited to this distance relative to the MC edge length (should be in range of [0.0,0.5])
581600
582601 decimate_barnacles: bool
583602 Flag to perform barnacle decimation\n
@@ -590,11 +609,14 @@ def reconstruction_pipeline(
590609 Flag to compute normals\n
591610 If set to True, the normals will be computed and stored in the mesh.
592611
612+ output_mesh_smoothing_weights: bool
613+ Flag to store the mesh smoothing weights if smoothing weights are computed.
614+
593615 output_raw_normals: bool
594616 Flag to output the raw normals in addition to smoothed normals if smoothing of normals is enabled
595617
596- output_mesh_smoothing_weights : bool
597- Flag to store the mesh smoothing weights if smoothing weights are computed.
618+ output_raw_mesh : bool
619+ When true, also return the SurfaceReconstruction object with no post-processing applied
598620
599621 mesh_aabb_clamp_vertices: bool
600622 Flag to clamp the vertices of the mesh to the AABB
@@ -616,29 +638,58 @@ def reconstruction_pipeline(
616638
617639 mesh_aabb_max: np.ndarray
618640 Largest corner of the axis-aligned bounding box for the mesh
641+
642+ generate_quads: bool
643+ Enable trying to convert triangles to quads if they meet quality criteria
644+
645+ quad_max_edge_diag_ratio: float
646+ Maximum allowed ratio of quad edge lengths to its diagonals to merge two triangles to a quad (inverse is used for minimum)
647+
648+ quad_max_normal_angle: float
649+ Maximum allowed angle (in degrees) between triangle normals to merge them to a quad
650+
651+ quad_max_interior_angle: float
652+ Maximum allowed vertex interior angle (in degrees) inside a quad to merge two triangles to a quad
619653
620654 Returns
621655 -------
622- tuple[TriMeshWithDataF32 | TriMeshWithDataF64, SurfaceReconstructionF32 | SurfaceReconstructionF64]
656+ tuple[TriMeshWithDataF32 | TriMeshWithDataF64 | MixedTriQuadMeshWithDataF32 | MixedTriQuadMeshWithDataF64, Optional[ SurfaceReconstructionF32] | Optional[ SurfaceReconstructionF64] ]
623657 Mesh with data object and SurfaceReconstruction object containing the reconstructed mesh and used grid
624658 """
625659 if particles .dtype == 'float32' :
626- return reconstruction_pipeline_f32 (particles , attributes_to_interpolate = attributes_to_interpolate , particle_radius = particle_radius , rest_density = rest_density ,
627- smoothing_length = smoothing_length , cube_size = cube_size , iso_surface_threshold = iso_surface_threshold ,
628- aabb_min = aabb_min , aabb_max = aabb_max , enable_multi_threading = enable_multi_threading ,
629- use_custom_grid_decomposition = subdomain_grid , subdomain_num_cubes_per_dim = subdomain_num_cubes_per_dim ,
630- global_neighborhood_list = False , mesh_cleanup = mesh_cleanup , decimate_barnacles = decimate_barnacles ,
631- keep_vertices = keep_vertices , compute_normals = compute_normals , sph_normals = sph_normals , normals_smoothing_iters = normals_smoothing_iters ,
632- mesh_smoothing_iters = mesh_smoothing_iters , mesh_smoothing_weights = mesh_smoothing_weights , mesh_smoothing_weights_normalization = mesh_smoothing_weights_normalization ,
633- output_mesh_smoothing_weights = output_mesh_smoothing_weights , output_raw_normals = output_raw_normals , mesh_aabb_min = mesh_aabb_min , mesh_aabb_max = mesh_aabb_max , mesh_aabb_clamp_vertices = mesh_aabb_clamp_vertices )
660+ tri_mesh , tri_quad_mesh , reconstruction = reconstruction_pipeline_f32 (particles , attributes_to_interpolate = attributes_to_interpolate , particle_radius = particle_radius , rest_density = rest_density ,
661+ smoothing_length = smoothing_length , cube_size = cube_size , iso_surface_threshold = iso_surface_threshold ,
662+ aabb_min = aabb_min , aabb_max = aabb_max , enable_multi_threading = enable_multi_threading ,
663+ use_custom_grid_decomposition = subdomain_grid , subdomain_num_cubes_per_dim = subdomain_num_cubes_per_dim ,
664+ check_mesh_closed = check_mesh_closed , check_mesh_manifold = check_mesh_manifold , check_mesh_orientation = check_mesh_orientation , check_mesh_debug = check_mesh_debug ,
665+ mesh_cleanup = mesh_cleanup , max_rel_snap_dist = mesh_cleanup_snap_dist , decimate_barnacles = decimate_barnacles ,
666+ keep_vertices = keep_vertices , compute_normals = compute_normals , sph_normals = sph_normals , normals_smoothing_iters = normals_smoothing_iters ,
667+ mesh_smoothing_iters = mesh_smoothing_iters , mesh_smoothing_weights = mesh_smoothing_weights , mesh_smoothing_weights_normalization = mesh_smoothing_weights_normalization ,
668+ output_mesh_smoothing_weights = output_mesh_smoothing_weights , output_raw_normals = output_raw_normals , output_raw_mesh = output_raw_mesh ,
669+ mesh_aabb_min = mesh_aabb_min , mesh_aabb_max = mesh_aabb_max , mesh_aabb_clamp_vertices = mesh_aabb_clamp_vertices ,
670+ generate_quads = generate_quads , quad_max_edge_diag_ratio = quad_max_edge_diag_ratio , quad_max_normal_angle = quad_max_normal_angle , quad_max_interior_angle = quad_max_interior_angle )
671+
672+ if tri_mesh == None :
673+ return (tri_quad_mesh , reconstruction )
674+ else :
675+ return (tri_mesh , reconstruction )
676+
634677 elif particles .dtype == 'float64' :
635- return reconstruction_pipeline_f64 (particles , attributes_to_interpolate = attributes_to_interpolate , particle_radius = particle_radius , rest_density = rest_density ,
636- smoothing_length = smoothing_length , cube_size = cube_size , iso_surface_threshold = iso_surface_threshold ,
637- aabb_min = aabb_min , aabb_max = aabb_max , enable_multi_threading = enable_multi_threading ,
638- use_custom_grid_decomposition = subdomain_grid , subdomain_num_cubes_per_dim = subdomain_num_cubes_per_dim ,
639- global_neighborhood_list = False , mesh_cleanup = mesh_cleanup , decimate_barnacles = decimate_barnacles ,
640- keep_vertices = keep_vertices , compute_normals = compute_normals , sph_normals = sph_normals , normals_smoothing_iters = normals_smoothing_iters ,
641- mesh_smoothing_iters = mesh_smoothing_iters , mesh_smoothing_weights = mesh_smoothing_weights , mesh_smoothing_weights_normalization = mesh_smoothing_weights_normalization ,
642- output_mesh_smoothing_weights = output_mesh_smoothing_weights , output_raw_normals = output_raw_normals , mesh_aabb_min = mesh_aabb_min , mesh_aabb_max = mesh_aabb_max , mesh_aabb_clamp_vertices = mesh_aabb_clamp_vertices )
678+ tri_mesh , tri_quad_mesh , reconstruction = reconstruction_pipeline_f64 (particles , attributes_to_interpolate = attributes_to_interpolate , particle_radius = particle_radius , rest_density = rest_density ,
679+ smoothing_length = smoothing_length , cube_size = cube_size , iso_surface_threshold = iso_surface_threshold ,
680+ aabb_min = aabb_min , aabb_max = aabb_max , enable_multi_threading = enable_multi_threading ,
681+ use_custom_grid_decomposition = subdomain_grid , subdomain_num_cubes_per_dim = subdomain_num_cubes_per_dim ,
682+ check_mesh_closed = check_mesh_closed , check_mesh_manifold = check_mesh_manifold , check_mesh_orientation = check_mesh_orientation , check_mesh_debug = check_mesh_debug ,
683+ mesh_cleanup = mesh_cleanup , max_rel_snap_dist = mesh_cleanup_snap_dist , decimate_barnacles = decimate_barnacles ,
684+ keep_vertices = keep_vertices , compute_normals = compute_normals , sph_normals = sph_normals , normals_smoothing_iters = normals_smoothing_iters ,
685+ mesh_smoothing_iters = mesh_smoothing_iters , mesh_smoothing_weights = mesh_smoothing_weights , mesh_smoothing_weights_normalization = mesh_smoothing_weights_normalization ,
686+ output_mesh_smoothing_weights = output_mesh_smoothing_weights , output_raw_normals = output_raw_normals , output_raw_mesh = output_raw_mesh ,
687+ mesh_aabb_min = mesh_aabb_min , mesh_aabb_max = mesh_aabb_max , mesh_aabb_clamp_vertices = mesh_aabb_clamp_vertices ,
688+ generate_quads = generate_quads , quad_max_edge_diag_ratio = quad_max_edge_diag_ratio , quad_max_normal_angle = quad_max_normal_angle , quad_max_interior_angle = quad_max_interior_angle )
689+
690+ if tri_mesh == None :
691+ return (tri_quad_mesh , reconstruction )
692+ else :
693+ return (tri_mesh , reconstruction )
643694 else :
644695 raise ValueError ("Invalid data type (only float32 and float64 are supported, consider explicitly specifying the dtype for particles)" )
0 commit comments