i’m using stoke to produce nice clouds of points, it rocks!! but with the fluid motion in some moments i get isolated points that are undesired
so my question is:
how to select points by loneliness?!?
in ICE i did this checking for the nearest particle then using a counter for the number of particles found, selecting the particles that has less than “n” neighbors and delete them
how to check inside the same point cloud for the nearest particle?
is this correct?
i get an error message Magma Channel “NeighborCount” Not Available in this PRT Object
The Channel NeighborCount is on the list because it is native to some source files, for example coming from RealFlow via BIN, RPC or PRT files.
It is not native to any Krakatoa object.
Also, the current version of the Krakatoa Magma modifier (other than the Genome version for meshes) does not have an option to input the data of the current stream it is operating on. (It is on our Wish List though).
So as a workaround you are required to use a copy of the PRT Loader for the filtering - you can hide it so it does not render, but you can pick it in the Magma as the reference particle system. Then you can use a ParticleSumRadius operator with a radius set to the distance within which you want to explore the neighborhood of each particle, and use the NumParticles output socket in the Logic > Less operator before outputting to the Selection channel as you did. When there are no neighbors in the given radius, the result will be 1 and not 0 because the particle will find its own clone in the other system, withing a distance of 0.0 units.
Remember that this is history-independent, so some particles might disappear and appear as the number of neighbor particles changes over time.
You can bake the results to a new PRT sequence, so you have to run it only once. Of course, if you resimulate the particles in the original Stoke, you will have to redo the filtering and re-save the cache each time.
Also, you should make sure the radius is as small as possible (but still larger than the distance between two particles), as the larger the search radius, the slower the search will get.
In the future, we might switch particle storage in Krakatoa to what Sequoia uses (SPRT instead of PRT), which should make searching for neighbors much faster.
Other than that, you can try using a Stoke Field Magma to cache the count data between the PRT Loader being sampled, and the PRT Loader or Stoke being culled:
Add a Magma modifier to the PRT Loader copy being sampled, and add a new custom channel called “Counter” or something like that (name is arbitrary).Set it to Float16 Arity 1, and InputValue 1.0.
Create a Stoke Field Magma around the PRT Loader on a frame that has its bounding box the largest, or set the bounding box manually to enclose any space the particles might occupy.
Set the spacing of the grid to about 2x the value of your previous search radius - we will store the result of a ParticleSumRadius into these voxels, and use them to access the result faster.
Set a Magma flow in the Stoke Field Magma which uses the same ParticleSumRadius, but collects the “Counter” value of the particles and outputs it as a new Field - you could reuse the Density channel, or create a new “Count” channel of type Float to store the results.
In the Krakatoa Magma modifier on your particle system to be culled, use an InputField operator to read the field of the Stoke Field Magma, and compare it to your neighbors threshold value (should be a Float, too) using a Less logical operator, and set a Selection based on that.
Delete the particles accordingly.
Obviously, this is not going to be as precise as using an uncached ParticleSumRadius - we are checking the number of particles only in the center of each voxel, and any particles inside this voxel will get deleted if the number of particles inside the voxel is below the threshold. In contrast, the original approach you proposed uses the exact particle position to find its neighbors within a certain radius, so it would be a bit more precise.
On the positive side, the number of ParticleSumRadius calls will be equal to the number of voxels in the grid, so if you have 100 million particles, but only 1 million voxels, it should run about 100x faster.