InteractiveComputerGraphics / splashsurf

Surface reconstruction library and CLI for particle data from SPH simulations, written in Rust.
https://splashsurf.physics-simulation.org/
MIT License
137 stars 20 forks source link

Python wrapper #100

Open Hassan-Bahrami opened 2 years ago

Hassan-Bahrami commented 2 years ago

Hi,

I'm wondering it there any python wrapper for this library? Also, do you have any reference regarding mathematical model you have used fot surface reconstruction? (specifically the function for finding surface level of particles).

w1th0utnam3 commented 2 years ago

Thank you for your interest. At the moment there is no Python wrapper. It shouldn't be too hard to build a wrapper with PyO3. Personally, I don't have much experience with, yet. So I'm not able to provide a wrapper in the very near future (we have other research priorities in our group at the moment) but it would certainly be a nice feature to have.

We don't have a publication to recommend at the moment, especially considering the exact formulation of the level-set function used in this implementation. Note that we don't specifically detect surface particles but just use an SPH based formulation of the indicator function (i.e, 1 inside of the fluid and 0 outside) to define a level-set function that is reconstructed using marching cubes. To summarize briefly: we use the level-set function

Phi(x) = - c + sum_{j in N(x)} of (V_j * W(x - x_j, h))

where c is the surface threshold, x is the position where we want to evaluate, sum_{j in N(x)} is the sum over all particles j in the neighborhood of point x, V_j is the volume of particle j, W is the SPH kernel function, x_j is the position of particle j and h is the kernel smoothing length.

EDIT: Removed part of the answer as I made a mistake.

Hassan-Bahrami commented 2 years ago

Thanks for the information

Hassan-Bahrami commented 2 years ago

Hi Fabian,

In SPH method, we must obtain the neighours of each particle to compute density, volume, etc. So, we only work with particles positions. But, when we are extracting the surface, we have position of each voxel corners. According to your formula, we need to find the nearest neighbours particle to each voxel point! Am I right?

Suppose I have N N N voxelized space. Then for computing following term:

sum_{j in N(x)}

Do I need to find nearest particles of each voxel's corner? In this case, it's tricky as we usually use an array to save voxels' coordinates and a Particle class to save all information of each particle such as their positions. If I mix voxels coordinates and particles poistion in one array to make Kdtree (or any other nearest neighbor algorithm), then I cannot identify which one is particle and which one is voxel's coordinate.

So, I'm wondering how do you find nearest particles to each voxel's corner?

w1th0utnam3 commented 2 years ago

According to your formula, we need to find the nearest neighbours particle to each voxel point! Am I right?

Yes, this is at least the most obvious way to do it.

Something similar is currently used to compute the surface normals in a post-processing step (build an R-star tree as acceleration structure of all the particles and then for each surface mesh vertex find all neighbor particles using the tree and compute the normal with them). But this is a bit hacky.

There is a more efficient way. We are not looping over the vertices of the marching cubes voxel grid to directly compute the value at each vertex. What we are usually doing in our group and also in this project is that we loop over all particles and then for each particle add-assign its contribution to every marching cubes vertex in the particle's compact support. Because the marching cubes grid is completely regular it's trivial for a particle to identify all vertices that it influences. The other way around is more difficult as you observed.

Hassan-Bahrami commented 2 years ago

Thank you!

I have implemented your proposed function in python and got this result: Capture

My purpose is to create two spheres that they are merging. Each sphere is created by some SPHs (saying 30 particles) and has visco-elastic property.

As you can see in the above picture, your method is kind of working. It's not smooth enough, maybe because we have only 30 particles for each sphere. But the problem is that two spheres are already connected, which is incorrect. They should be separate and, during the simulation, get merged.

So, I'm wondering how you separate different parts of fluids in your simulation? For example, if you want to show a blob that comes and joins to the water surface.

Thanks in advance!