3#include <thrust/sort.h>
7 template<typename TDataType>
8 PolygonSet<TDataType>::PolygonSet()
13 template<typename TDataType>
14 PolygonSet<TDataType>::~PolygonSet()
16 mPolygonIndex.clear();
19 template<typename TDataType>
20 void PolygonSet<TDataType>::setPolygons(const CArrayList<uint>& indices)
22 mPolygonIndex.assign(indices);
25 template<typename TDataType>
26 void PolygonSet<TDataType>::setPolygons(const DArrayList<uint>& indices)
28 mPolygonIndex.assign(indices);
31 template<typename TDataType>
32 void PolygonSet<TDataType>::copyFrom(PolygonSet<TDataType>& polygons)
34 PointSet<TDataType>::copyFrom(polygons);
36 mPolygonIndex.assign(polygons.mPolygonIndex);
39 template<typename TDataType>
40 bool PolygonSet<TDataType>::isEmpty()
43 empty |= mPolygonIndex.size() == 0;
48 __global__ void PolygonSet_CountPolygonNumber(
50 DArrayList<uint> polygonIndices)
52 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
53 if (tId >= polygonIndices.size()) return;
55 auto& index = polygonIndices[tId];
58 for (int i = 0; i < N; i++)
61 atomicAdd(&counter[v0], 1);
65 __global__ void PolygonSet_SetupVertex2Polygon(
66 DArrayList<uint> vert2Poly,
67 DArrayList<uint> polygonIndices)
69 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
70 if (tId >= polygonIndices.size()) return;
72 auto& index = polygonIndices[tId];
75 for (int i = 0; i < N; i++)
78 index.atomicInsert(v0);
82 template<typename TDataType>
83 void PolygonSet<TDataType>::updateTopology()
85 uint vNum = PointSet<TDataType>::mCoords.size();
87 //Update the vertex to polygon mapping
88 DArray<uint> counter(vNum);
92 PolygonSet_CountPolygonNumber,
96 mVer2Poly.resize(counter);
99 PolygonSet_SetupVertex2Polygon,
105 EdgeSet<TDataType>::updateTopology();
108 __global__ void PolygonSet_CountEdgeNumber(
109 DArray<uint> counter,
110 DArrayList<uint> polygonIndices)
112 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
113 if (tId >= counter.size()) return;
115 counter[tId] = polygonIndices[tId].size();
118 __global__ void PolygonSet_SetupEdgeKeys(
120 DArray<uint> polyIds,
121 DArrayList<uint> polygonIndices,
124 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
125 if (tId >= radix.size()) return;
127 uint offset = radix[tId];
129 auto& index = polygonIndices[tId];
131 int N = index.size();
132 for (int i = 0; i < N; i++)
135 uint v1 = index[(i + 1) % N];
136 keys[offset + i] = EKey(v0, v1);
137 polyIds[offset + i] = tId;
141 __global__ void PolygonSet_CountUniqueEdge(
142 DArray<uint> counter,
145 uint tId = threadIdx.x + (blockIdx.x * blockDim.x);
146 if (tId >= keys.size()) return;
148 if (tId == 0 || keys[tId] != keys[tId - 1])
154 template<typename Edge, typename Edg2Poly>
155 __global__ void PolygonSet_SetupEdgeIndices(
157 DArrayList<uint> poly2Edge,
158 DArray<Edg2Poly> edg2Poly,
159 DArray<EKey> edgeKeys,
160 DArray<uint> polyIds,
163 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
164 if (tId >= edgeKeys.size()) return;
166 uint edgeId = radix[tId];
167 uint polyId = polyIds[tId];
168 poly2Edge[polyId].atomicInsert(edgeId);
169 if (tId == 0 || edgeKeys[tId] != edgeKeys[tId - 1])
171 EKey key = edgeKeys[tId];
172 edges[edgeId] = Edge(key[0], key[1]);
174 Edg2Poly e2p(EMPTY, EMPTY);
175 e2p[0] = polyIds[tId];
177 if (tId + 1 < edgeKeys.size() && edgeKeys[tId + 1] == key)
178 e2p[1] = polyIds[tId + 1];
180 edg2Poly[edgeId] = e2p;
184 template<typename TDataType>
185 void PolygonSet<TDataType>::updateEdges()
187 uint polyNum = mPolygonIndex.size();
189 DArray<uint> radix(polyNum);
192 PolygonSet_CountEdgeNumber,
196 mPoly2Edg.resize(radix);
198 int eNum = thrust::reduce(thrust::device, radix.begin(), radix.begin() + radix.size());
199 thrust::exclusive_scan(thrust::device, radix.begin(), radix.begin() + radix.size(), radix.begin());
201 DArray<EKey> edgeKeys(eNum);
202 DArray<uint> polyIds(eNum);
205 PolygonSet_SetupEdgeKeys,
211 DArray<uint> uniqueEdgeCounter(eNum);
213 thrust::sort_by_key(thrust::device, edgeKeys.begin(), edgeKeys.begin() + edgeKeys.size(), polyIds.begin());
215 cuExecute(edgeKeys.size(),
216 PolygonSet_CountUniqueEdge,
220 int uniqueNum = thrust::reduce(thrust::device, uniqueEdgeCounter.begin(), uniqueEdgeCounter.begin() + uniqueEdgeCounter.size());
221 thrust::exclusive_scan(thrust::device, uniqueEdgeCounter.begin(), uniqueEdgeCounter.begin() + uniqueEdgeCounter.size(), uniqueEdgeCounter.begin());
223 EdgeSet<TDataType>::mEdges.resize(uniqueNum);
224 mEdg2Poly.resize(uniqueNum);
226 cuExecute(edgeKeys.size(),
227 PolygonSet_SetupEdgeIndices,
228 EdgeSet<TDataType>::mEdges,
238 uniqueEdgeCounter.clear();
241 template<typename TDataType>
242 void PolygonSet<TDataType>::extractEdgeSet(EdgeSet<TDataType>& es)
244 es.setPoints(PointSet<TDataType>::mCoords);
245 es.setEdges(EdgeSet<TDataType>::mEdges);
250 __global__ void PolygonSet_ExtractTriangleNumber(
251 DArray<uint> counter,
252 DArrayList<uint> polygonIndices)
254 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
255 if (tId >= counter.size()) return;
257 counter[tId] = polygonIndices[tId].size() == 3 ? 1 : 0;
260 template<typename Triangle>
261 __global__ void PolygonSet_ExtractTriangleIndices(
262 DArray<Triangle> triangles,
263 DArrayList<uint> polygonIndices,
266 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
267 if (tId >= radix.size()) return;
269 uint offset = radix[tId];
271 auto& index = polygonIndices[tId];
273 if (index.size() == 3)
278 triangles[offset] = Triangle(v0, v1, v2);
282 template<typename TDataType>
283 void PolygonSet<TDataType>::extractTriangleSet(TriangleSet<TDataType>& ts)
287 uint polyNum = mPolygonIndex.size();
289 DArray<uint> radix(polyNum);
292 PolygonSet_ExtractTriangleNumber,
296 int tNum = thrust::reduce(thrust::device, radix.begin(), radix.begin() + radix.size());
297 thrust::exclusive_scan(thrust::device, radix.begin(), radix.begin() + radix.size(), radix.begin());
299 DArray<Triangle> triangleIndices(tNum);
301 //TODO: remove duplicative vertices
303 PolygonSet_ExtractTriangleIndices,
308 ts.setPoints(PointSet<TDataType>::mCoords);
309 ts.setTriangles(triangleIndices);
313 triangleIndices.clear();
316 __global__ void PolygonSet_ExtractQuadNumber(
317 DArray<uint> counter,
318 DArrayList<uint> polygonIndices)
320 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
321 if (tId >= counter.size()) return;
323 counter[tId] = polygonIndices[tId].size() == 4 ? 1 : 0;
326 template<typename Quad>
327 __global__ void PolygonSet_ExtractQuadIndices(
329 DArrayList<uint> polygonIndices,
332 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
333 if (tId >= radix.size()) return;
335 uint offset = radix[tId];
337 auto& index = polygonIndices[tId];
339 if (index.size() == 4)
345 quads[offset] = Quad(v0, v1, v2, v3);
349 template<typename TDataType>
350 void PolygonSet<TDataType>::extractQuadSet(QuadSet<TDataType>& qs)
354 uint polyNum = mPolygonIndex.size();
356 DArray<uint> radix(polyNum);
359 PolygonSet_ExtractQuadNumber,
363 int tNum = thrust::reduce(thrust::device, radix.begin(), radix.begin() + radix.size());
364 thrust::exclusive_scan(thrust::device, radix.begin(), radix.begin() + radix.size(), radix.begin());
366 DArray<Quad> quadIndices(tNum);
368 //TODO: remove duplicative vertices
370 PolygonSet_ExtractQuadIndices,
375 qs.setPoints(PointSet<TDataType>::mCoords);
376 qs.setQuads(quadIndices);
383 __global__ void PolygonSet_CountTriangleNumber(
384 DArray<uint> counter,
385 DArrayList<uint> polygonIndices)
387 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
388 if (tId >= counter.size()) return;
390 counter[tId] = polygonIndices[tId].size() - 2;
393 template<typename Triangle>
394 __global__ void PolygonSet_SetupTriangleIndices(
395 DArray<Triangle> triangles,
396 DArrayList<uint> polygonIndices,
399 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
400 if (tId >= radix.size()) return;
402 uint offset = radix[tId];
404 auto& index = polygonIndices[tId];
406 int N = index.size();
407 for (int i = 0; i < N - 2; i++)
410 uint v1 = index[i + 1];
411 uint v2 = index[i + 2];
412 triangles[offset + i] = Triangle(v0, v1, v2);
416 template<typename TDataType>
417 void PolygonSet<TDataType>::turnIntoTriangleSet(TriangleSet<TDataType>& ts)
421 uint polyNum = mPolygonIndex.size();
423 DArray<uint> radix(polyNum);
426 PolygonSet_CountTriangleNumber,
430 int tNum = thrust::reduce(thrust::device, radix.begin(), radix.begin() + radix.size());
431 thrust::exclusive_scan(thrust::device, radix.begin(), radix.begin() + radix.size(), radix.begin());
433 DArray<Triangle> triangleIndex(tNum);
436 PolygonSet_SetupTriangleIndices,
441 ts.setPoints(PointSet<TDataType>::mCoords);
442 ts.setTriangles(triangleIndex);
446 triangleIndex.clear();
449 template<typename TDataType>
450 void PolygonSet<TDataType>::triangleSetToPolygonSet(TriangleSet<TDataType>& ts)
452 this->setPoints(ts.getPoints());
454 this->mPolygonIndex.resize(ts.getTriangles().size(),3);
456 cuExecute(ts.getTriangles().size(),
467 template<typename Triangle>
468 __global__ void triSet2PolygonSet(
469 DArray<Triangle> triangles,
470 DArrayList<uint> polygons
473 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
474 if (tId >= triangles.size()) return;
476 auto& index = polygons[tId];
477 for (int i = 0; i < 3; i++)
478 index.insert(triangles[tId][i]);
482 DEFINE_CLASS(PolygonSet);