splashsurf Surface Reconstruction

repository·main·Indexed 43 days ago

https://github.com/interactivecomputergraphics/splashsurf

A high-performance tool and library for reconstructing smooth surfaces from particle-based fluid simulations, such as SPlisHSPlasH. It utilizes a fast marching cubes-based method with weighted Laplacian smoothing to produce high-quality meshes without volume loss. Available as a Rust CLI, a Rust library (splashsurf_lib), Python bindings (pysplashsurf v0.14.1), and a Blender add-on (splashsurf_studio).

Tokens
41.3K
Snippets
116
Records
174
Agent score
52%

What's inside splashsurf

  1. Overview of splashsurf components

    main

    splashsurf is a surface reconstruction library and CLI for particle data from SPH (Smoothed Particle Hydrodynamics) simulations. It provides several ways to use the technology:

    • splashsurf (CLI): A binary crate for running surface reconstructions from the terminal.
    • splashsurf_lib (Rust Library): A Rust library for integrating reconstruction directly into other Rust applications or building custom pipelines.
    • pysplashsurf (Python Bindings): Python bindings for both the CLI and the library.
    • splashsurf_studio (Blender Add-on): A Blender add-on built on the Python bindings for on-the-fly surface reconstruction.
  2. How subdomain grid-based decomposition works

    main

    To avoid the memory and performance issues of a naive dense marching cubes reconstruction on large domains, splashsurf uses a subdomain grid approach (enabled by default via --subdomain-grid=on).

    How it works:

    1. Division: The fluid domain is divided into subdomains, each containing a fixed number of marching cubes cells (default is 64x64x64).
    2. Allocation: Only subdomains containing fluid particles are allocated. For subdomains with very few particles (less than 5% of the largest subdomain), a hashmap is used to save memory. For most dense domains, a dense 3D array is used to maximize cache locality.
    3. Parallelization: Triangulation per subdomain is performed in parallel.
    4. Stitching: To ensure a seamless mesh, floating-point operations at subdomain boundaries are performed in a consistent order. This ensures identical field values on both sides of a boundary, making the resulting meshes topologically compatible for parallel merging.

    When to use/disable:

    • Large simulations: The subdomain grid approach is significantly faster due to better cache locality and parallelization.
    • Small simulations (< low thousands of particles): The overhead of domain decomposition and stitching might make it slower. In these cases, you can disable it to use a global approach with thread-local hashmaps.
    # Example flag to toggle decomposition (though it is ON by default)
    --subdomain-grid=off
  3. Reconstruct surfaces from SPH particle data

    main

    splashsurf uses a fast marching cubes-based method to reconstruct a (closed) triangle mesh from SPH fluid simulation particles.

    Key Features:

    • Normals: Computes surface normals using SPH gradients.
    • Attribute Interpolation: Interpolates scalar and vector attributes defined on particles onto the surface.
    • Smoothing: Supports a weighted Laplacian smoothing approach to remove typical SPH simulation bumps.

    Required Parameters:

    To perform a reconstruction, you must provide:

    • Kernel radius: The compact support of the SPH kernel.
    • Particle radius: Used to compute the volume of particles.
    • Marching cubes resolution: The resolution of the reconstruction (an iso-surface threshold is pre-configured by default).
  4. Data type requirements for pysplashsurf

    main

    When calling pysplashsurf functions, adhere to the following data type constraints to ensure compatibility:

    • Scalar parameters: Use standard Python float.
    • Array inputs (e.g., particle positions): Use Numpy arrays with data-type np.float32 or np.float64.
    • Precision: Output arrays will match the float precision of the input arrays.
    • Memory Layout: Array-like inputs must be contiguous (C-order) in memory.
    • Consistency: All array-like and object-type inputs (such as Aabb3d) passed to a single function call must use the same float data-type (either all float32 or all float64).
  5. Work with different mesh types in pysplashsurf

    main

    The library provides several mesh representations depending on your geometry needs:

    • TriMesh3d: A standard 3D triangular mesh.
    • MixedTriQuadMesh3d: A 3D mesh containing a mixture of triangles and quadrilaterals.
    • MeshWithData: A mesh structure that carries additional associated data.

    Detailed specifications for these types are available in the splashsurf_lib Rust documentation.

  6. Limitations and Workarounds for Geometry Nodes

    main

    Geometry Nodes Input Limitation

    Due to Blender's execution order, Splashsurf Studio cannot use geometry generated by Geometry Nodes as input for reconstruction. It only supports base geometry or geometry loaded via external tools (like Sequence Loader).

    Workaround for rendering both particles and surfaces: If you need to render both the particles (via Geometry Nodes) and the reconstructed surface in the same scene:

    1. Create a separate object with a placeholder mesh (e.g., a cube).
    2. Apply your Geometry Nodes to this placeholder object.
    3. Inside the Geometry Nodes setup, refer to the original particle data object and ignore the placeholder geometry.

    Geometry Nodes Output

    The reconstructed surface produced by Splashsurf Studio can be used as input for Geometry Nodes.

  7. Parallelization limitations and notes

    main

    While the tool supports multi-threading, certain features are hard-coded to parallelize over particles or the mesh/domain and cannot be switched to sequential mode using --mt-particles=off.

    Affected features include:

    • The "subdomain-grid" domain decomposition approach.
    • Post-processing (interpolation of smoothing weights, normals, and other fluid attributes).

    Recommendation: If you are using the "subdomain-grid" decomposition or these post-processing features, it is recommended not to parallelize over multiple files (keep --mt-files=off).

  8. How the surface reconstruction procedure works

    main

    The library uses a spatial hashing strategy to evaluate fluid density onto a sparse grid. This approach is memory-efficient because it only allocates memory in areas where fluid density is non-zero, rather than allocating a full background grid for the entire domain.

    The Reconstruction Workflow

    1. Virtual Background Grid Construction: A virtual grid is defined with the desired marching cubes resolution. No memory is allocated for the grid itself; only its topology is used implicitly.
    2. Density Computation: The library performs a neighborhood search for each fluid particle and evaluates an SPH sum (based on kernel radius and particle rest mass) to compute density.
    3. Splash Detection (Optional): If a "splash detection radius" is provided, single particles can be masked as inactive using an additional neighborhood search.
    4. Sparse Density Map Generation: A map is created that associates virtual background grid vertex indices with their corresponding fluid density values. This map only contains entries for vertices with non-zero density.
    5. Surface Edge Interpolation: The library identifies edges that cross the fluid surface threshold. It iterates through vertices in the sparse density map, skipping those clearly inside the fluid, and uses linear interpolation to find the exact crossing point on edges between a 'threshold-crossing' vertex and its neighbors.
    6. Marching Cubes Triangulation: Finally, the library iterates through the cells containing surface crossing points, uses a marching cubes lookup table (LUT) to determine the triangulation, and emits the resulting triangles into the final mesh.
  9. Basic Workflow for Surface Reconstruction in Splashsurf Studio

    main

    Splashsurf Studio performs on-the-fly surface reconstruction from Blender object vertices. Follow these steps to set up a reconstruction:

    1. Import Particle Data: Load your particle data (e.g., via the Sequence Loader add-on).
    2. Select Input: Select the particle data object in the Outliner. In the Splashsurf Studio panel (found in the 3D Viewport toolbar via the N key), click the "+" button in the "Select Input" panel to register the object's vertices.
    3. Configure Settings:
      • Viewport Settings: Adjust these for real-time updates in the 3D Viewport (typically lower resolution for performance).
      • Render Settings: Adjust these for high-quality reconstructions during rendering.
    4. Activate: Click the activation button in the "Select Input" panel to start the automatic reconstruction process.

    The surface will automatically update whenever the frame changes (e.g., when the Sequence Loader updates the input file).

  10. Process a sequence of files

    main

    The tool can automatically process multiple files by using a {} placeholder in the filename. The placeholder is treated as a (\d+) regex (matching one or more digits), supporting zero-padding and non-zero padded indices.

    Key features for sequences:

    • Sorting: Files are processed in natural sort order. Missing files in a sequence are silently skipped.
    • Range Control: Use -s / --start-index and -e / --end-index to specify the range of files to process.
    • Parallelism:
      • --mt-files=on: Enables processing multiple files in parallel.
      • Important: If --mt-files=on is enabled, you should set --mt-particles=off to avoid performance degradation. This is ideal for many files with few particles.
    • Thread Control: Use -n / --num-threads or the RAYON_NUM_THREADS environment variable to set the thread count.
    # Example pattern for a sequence of files
    splashsurf reconstruct particles_{}.vtk -r=0.011 -c=1.5 -l=2.0 -t=0.6