orzzzjq / gCentroidal-Voronoi-Tessellation

Compute centroidal Voronoi tessellations in 2D and 3D using the GPU.
https://www.comp.nus.edu.sg/~tants/cvt.html
MIT License
35 stars 10 forks source link

Density bahves unexpectedly #2

Closed lvasa closed 3 years ago

lvasa commented 3 years ago

Hi, I am testing the project by setting different densities, but it seems that the only thing that matters is where zeros are placed. Apart from that, no matter what density distribution I prescribe (in the 3D case), I always get the non-zero area uniformly covered with voronoi cells.

orzzzjq commented 3 years ago

Hi, I don't know what are the 'zeros' you mean. Generally speaking, the density distribution should be positive. I tested with different density distributions and did some visualizations, but I never see the issue you mentioned...

orzzzjq commented 3 years ago

Maybe your density distribution is too smooth, you can try something more aggressive.

lvasa commented 3 years ago

Hi, thanks for answering! I have tried density computed as i i+j j+k * k, but I got uniformly distributed cells/centers. Only when I set density to zero in some voxels, the centers do not appear there.

lvasa commented 3 years ago

I have now tried inputDensity[TOID(i, j, k, fboSize)] = i i+j j+k * k + 1 to make sure that all densities are positive, but I am still getting a uniform distribution in the result.

orzzzjq commented 3 years ago

Hi, thanks for answering! I have tried density computed as i i+j j+k * k, but I got uniformly distributed cells/centers. Only when I set density to zero in some voxels, the centers do not appear there.

I also tested with this function, and the visualization shows that it's not uniform...

lvasa commented 3 years ago

Great, I am obviously doing something wrong :) Could you maybe send me a complete MSVS solution, so that I can check whether it works on my machine, and perhaps find out what went wrong? Or alternatively I could send you mine and you can check. For visualisation, I simply iterate through all the outputVoronoi voxels and store each voxel value as v line to an .obj file - the Voronoi centers are then duplicated several times, but when viewing in MeshLab, this should show me the centers, is that a correct approach?

orzzzjq commented 3 years ago

I didn't visualize all the voxels as it's too large. I only output the centers and using Potree to do the visualization. But the distribution is not obvious in the visualization when you use i i+j j+k k and only visualize the centers. You can try something more aggressive (like exponential functions) or try to output the surface of the cube and visualize the regions with different colors. A density function I used: `expf(-20. (xx+yy+zz)) + 0.05 sin(pix)sin(pix) sin(piy)sin(piy) sin(piz)sin(pi*z)` where the cube is rescaled to [-1,1]^3.

orzzzjq commented 3 years ago

A sample result I get:

drawing
lvasa commented 3 years ago

No, still getting a uniform distribution like this image Could the problem be caused by me changing the fboSize to 256?

lvasa commented 3 years ago

Btw is there a simple way to obtain only the centers, other than iterating through the voxels and finding unique values?

orzzzjq commented 3 years ago

No, still getting a uniform distribution like this [image] Could the problem be caused by me changing the fboSize to 256?

Oh, I don't know what happened then... For 3D, you need to use DECODE(p, x, y, z) to get the coordinates as they are encoded into a single integer p (the value of outputVoronoi[]).

Btw is there a simple way to obtain only the centers, other than iterating through the voxels and finding unique values?

Yes, there is a simpler way, but you may need to modify the CUDA code. If you only need the position of the points, you don't need to construct the resulted Voronoi diagram after you get the final position of the points (this line): https://github.com/orzzzjq/gCentroidal-Voronoi-Tessellation/blob/44dea467aa8172a1d2f4c10f11881fbd236495c0/gCVT-3D/gCVT/gCVTHost.cu#L336 And then collect the points from cvtVoronoi[] using parallel prefix similar to thrust::remove_if().

lvasa commented 3 years ago

I'm sorry to bother you with this, but I must be doing something stupid. I have packed my whole solution, including the densitiy initialization - could you please have a quick look at what it is I have done wrong? If I redirect the output into an .obj file, I expect to get a non-uniform point cloud, but I keep getting a (nice) sampling of a cube. My solution is here: http://meshcompression.org/CudaTest.zip, I am running the code on an MSI RTX 2070.

orzzzjq commented 3 years ago

I'm sorry to bother you with this, but I must be doing something stupid. I have packed my whole solution, including the densitiy initialization - could you please have a quick look at what it is I have done wrong? If I redirect the output into an .obj file, I expect to get a non-uniform point cloud, but I keep getting a (nice) sampling of a cube. My solution is here: http://meshcompression.org/CudaTest.zip, I am running the code on an MSI RTX 2070.

I think there might be something wrong when you are doing the rescaling. I just modified it from

float x = (i - halfSize) / (2 * fboSize);
float y = (j - halfSize) / (2 * fboSize);
float z = (k - halfSize) / (2 * fboSize);

to

float x = (i - halfSize) / halfSize;
float y = (j - halfSize) / halfSize;
float z = (k - halfSize) / halfSize;

Try it again. :)

lvasa commented 3 years ago

Sorry, my bad indeed, I have not realized that if the density doubles, then the cell diameter only grows by ~25%. The software works correctly indeed. Thanks so much for your patience :)