1#include "ComputeSurfaceLevelSet.h"
5 template<typename TDataType>
6 ComputeSurfaceLevelset<TDataType>::ComputeSurfaceLevelset()
13 template<typename TDataType>
14 ComputeSurfaceLevelset<TDataType>::~ComputeSurfaceLevelset()
19 //template <typename Real, typename Coord>
20 //__device__ Real ComputeSurface_density(Coord cell, Coord points, Real mass, SpikyKernel<Real> )
26 template < typename Coord>
27 __device__ Coord CSur_getCellPosition(int3 index, Coord origin, Real h)
30 index.x * h + origin[0],
31 index.y * h + origin[1],
32 index.z * h + origin[2]
36 template < typename Coord>
37 __device__ int3 CSur_getCellIndex(Coord pos, Coord origin, Real h)
41 * 2.5 h : 2.0 h + 0.5 h;
42 * 2.0 h : the expanded cells;
43 * 0.5 h : the offset of cell position.
45 //index.x = (int)((pos - origin + 0.5 * h[0])[0] / h[0]);
46 //index.y = (int)((pos - origin + 0.5 * h[0])[1] / h[1]);
47 //index.z = (int)((pos - origin + 0.5 * h[0])[2] / h[2]);
48 index.x = (int)((pos - origin )[0] / h);
49 index.y = (int)((pos - origin )[1] / h);
50 index.z = (int)((pos - origin )[2] / h);
55 template < typename Real>
56 __device__ Real CSur_PhiByDensity(Real V, Real weight)
63 template <typename Real, typename Coord>
64 __global__ void ComputeSurface_PointToLevelset(
65 DArray3D<Real> distance,
69 SpikyKernel<Real> kern,
75 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
76 if (pId >= point.size()) return;
78 Coord& pos_i = point[pId];
80 int3 index = CSur_getCellIndex(pos_i, origin, cell_dx);
81 //Coord cellpos = CSur_getCellPosition(index, origin, h);
89 for(int i = -neiborGridNum.x; i <= neiborGridNum.x; i ++)
90 for (int j = -neiborGridNum.y; j <= neiborGridNum.y; j++)
91 for (int k = -neiborGridNum.z; k <= neiborGridNum.z; k++)
94 index_offset.x = index.x + i;
95 index_offset.y = index.y + j;
96 index_offset.z = index.z + k;
98 cellpos = CSur_getCellPosition(index_offset, origin, cell_dx);
99 Real r = (cellpos - pos_i).norm();
100 Real w = kern.Weight(r, smoothingLength);
102 atomicAdd(&distance(index_offset.x, index_offset.y, index_offset.z),
103 CSur_PhiByDensity(1.0f, w));
109 //Real value = distance(index.x, index.y, index.z);
110 //if (value < -10000.0f)
112 // printf(" %f \r\n", value);
117 template <typename Real, typename Coord>
118 __global__ void ComputeSurface_Smoothing(
119 DArray3D<Real> distance,
123 Real smoothingLength,
124 SpikyKernel<Real> kern
127 int i = threadIdx.x + (blockIdx.x * blockDim.x);
128 int j = threadIdx.y + (blockIdx.y * blockDim.y);
129 int k = threadIdx.z + (blockIdx.z * blockDim.z);
131 Real grid_ijk = distance(i, j, k) ;
132 Real grid_neighbor = 0.0f;
138 template <typename Real>
139 __global__ void ComputeSurface_LevelsetInitial(
140 DArray3D<Real> distance,
143 int dId = threadIdx.x + (blockIdx.x * blockDim.x);
144 if (dId >= distance.nx() * distance.ny() * distance.nz()) return;
147 /* if (distance[dId]> 10* EPSILON)
148 printf("distance %f \r\n",distance[dId]);*/
150 distance[dId] = value;
151 for (int i = -1; i < 2; i++)
152 for (int j = -1; j < 2; j++)
153 for (int k = -1; k < 2; k++)
156 //index_offset.x = index.x + i;
157 //index_offset.y = index.y + j;
158 //index_offset.z = index.z + k;
160 //cellpos = CSur_getCellPosition(index, origin, cell_dx);
161 //Real r = (cellpos - pos_i).norm();
162 //Real w = kern.Weight(r, smoothingLength);
166 template <typename Real>
167 __global__ void ComputeSurface_LevelsetTest(
168 DArray3D<Real> distance,
171 int dId = threadIdx.x + (blockIdx.x * blockDim.x);
172 if (dId >= distance.nx() * distance.ny() * distance.nz()) return;
175 //if (distance[dId] < -100* EPSILON)
176 // printf("%f \r\n",distance[dId]);
179 template<typename TDataType>
180 void ComputeSurfaceLevelset<TDataType>::constrain()
182 std::cout << "ComputeSurfaceLevelset: " << this->inPoints()->size() <<std::endl;
184 int num = this->inPoints()->size();
185 auto& sdf = this->inLevelSet()->getDataPtr()->getSDF();
187 auto& distances = this->inLevelSet()->getDataPtr()->getSDF().distances();
188 Real cell_dx = this->inLevelSet()->getDataPtr()->getSDF().getGridSpacing();
189 Coord origin = this->inLevelSet()->getDataPtr()->getSDF().lowerBound();
193 Real smoothingLength = (Real)(2.5f * cell_dx);
195 int3 neiborGridNumber = make_int3(
196 (int)(smoothingLength / cell_dx),
197 (int)(smoothingLength / cell_dx),
198 (int)(smoothingLength / cell_dx)
200 std::cout << neiborGridNumber.x << ", " << neiborGridNumber.y << ", " << neiborGridNumber.z << ", " << std::endl;
202 cuExecute(num, ComputeSurface_PointToLevelset,
204 this->inPoints()->getData(),
213 DEFINE_CLASS(ComputeSurfaceLevelset);