PeriDyno 1.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
PolygonSetToTriangleSet.cu
Go to the documentation of this file.
1#pragma once
2#include "PolygonSetToTriangleSet.h"
3#include "cuda_runtime.h"
4#include <thrust/sort.h>
5#include "GLSurfaceVisualModule.h"
6#include "GLWireframeVisualModule.h"
7#include "EarClipper.h"
8
9namespace dyno
10{
11 __global__ void extractPolyIndices(
12 DArray<uint> input,
13 DArray<uint> output,
14 int* arrayIndex
15 )
16 {
17 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
18 if (tId >= input.size()) return;
19
20 if (input[tId] == 1) {
21 int index = atomicAdd(arrayIndex, 1);
22 output[index] = tId;
23 }
24 }
25
26 __global__ void PolygonEdgeCounting(
27 DArray<uint> counter3,
28 DArray<uint> counter4,
29 DArray<uint> counter5,
30 DArrayList<uint> polygonIndices)
31 {
32 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
33 if (tId >= polygonIndices.size()) return;
34
35 counter3[tId] = polygonIndices[tId].size() == 3 ? 1 : 0;
36 counter4[tId] = polygonIndices[tId].size() == 4 ? 1 : 0;
37 counter5[tId] = polygonIndices[tId].size() >= 5 ? 1 : 0;
38 }
39
40 __global__ void PolygonSet_CountPoly2TriangleNumber(
41 DArray<uint> counter,
42 DArrayList<uint> polygonIndices)
43 {
44 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
45 if (tId >= counter.size()) return;
46
47 counter[tId] = polygonIndices[tId].size() - 2;
48 }
49
50 template<typename Triangle>
51 __global__ void Edge4_ExtractTriangleIndices(
52 DArray<Triangle> triangles,
53 DArrayList<uint> polygonIndices,
54 DArray<uint> radix)
55 {
56 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
57 if (tId >= radix.size()) return;
58
59 uint offset = radix[tId];
60
61 auto& index = polygonIndices[tId];
62
63 if (index.size() == 3)
64 {
65 uint v0 = index[0];
66 uint v1 = index[1];
67 uint v2 = index[2];
68 triangles[offset] = Triangle(v0, v1, v2);
69 }
70 }
71
72 template<typename Triangle>
73 __global__ void CopyTriangles(
74 DArray<Triangle> outTriangles,
75 DArrayList<uint> polygonIndices,
76 DArray<uint> triIndex,
77 DArrayList<uint> poly2tri
78 )
79 {
80 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
81 if (tId >= triIndex.size()) return;
82
83 auto& index = polygonIndices[tId];
84 if (index.size() == 3)
85 {
86 uint offset = triIndex[tId];
87 outTriangles[offset] = Triangle(index[0], index[1], index[2]);
88 poly2tri[tId][0] = offset;
89 }
90
91 }
92
93 template<typename Triangle>
94 __global__ void Quads2Triangles(
95 DArray<Triangle> outTriangles,
96 DArrayList<uint> polygonIndices,
97 DArray<Vec3f> pos,
98 DArray<uint> quadIndex,
99 DArrayList<uint> poly2tri,
100 int offset)
101 {
102 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
103 if (tId >= quadIndex.size()) return;
104
105 auto& index = polygonIndices[tId];
106 printf("poly list :%d\n",index.size());
107 if (index.size() == 4)
108 {
109 uint id = 2 * quadIndex[tId] + offset;
110
111 uint v0 = index[0];
112 uint v1 = index[1];
113 uint v2 = index[2];
114 uint v3 = index[3];
115 //�жϵ��Ƿ������
116
117 Vec3f A = pos[v0];
118 Vec3f B = pos[v1];
119 Vec3f C = pos[v2];
120 Vec3f P = pos[v3];
121
122 Vec3f AB = B - A;
123 Vec3f BC = C - B;
124 Vec3f CA = A - C;
125
126 Vec3f AP = P - A;
127 Vec3f BP = P - B;
128 Vec3f CP = P - C;
129
130 // ������
131 Vec3f cross1 = AB.cross(AP).normalize();
132 Vec3f cross2 = BC.cross(BP).normalize();
133 Vec3f cross3 = CA.cross(CP).normalize();
134
135 // �ж����в���ķ���
136 float dot1 = cross1.dot(cross2);
137 float dot2 = cross1.dot(cross3);
138 float dot3 = cross2.dot(cross3);
139
140 if ((dot1 >= 0 && dot2 >= 0 && dot3 >= 0) || (dot1 <= 0 && dot2 <= 0 && dot3 <= 0))
141 {
142 outTriangles[id] = Triangle(v0, v1, v3);
143 outTriangles[id + 1] = Triangle(v1, v2, v3);
144 }
145 else
146 {
147 outTriangles[id] = Triangle(v0, v1, v2);
148 outTriangles[id + 1] = Triangle(v0, v2, v3);
149 }
150
151 poly2tri[tId][0] = id;
152 poly2tri[tId][1] = id + 1;
153 }
154
155
156 }
157
158 template<typename Triangle>
159 __global__ void CopyTriangles2Triangles(
160 DArray<Triangle> outTriangles,
161 DArray<Triangle> inTriangles,
162 uint offset)
163 {
164 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
165 if (tId >= inTriangles.size()) return;
166
167 outTriangles[tId + offset] = inTriangles[tId];
168 }
169
170
171 __global__ void CounterLarger5Edges(
172 DArray<uint> counter
173 )
174 {
175 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
176 if (tId >= counter.size()) return;
177
178 if (counter[tId] <= 2)
179 counter[tId] = 0;
180 }
181
182
183 __global__ void updatepoly2triangleId_moreThan5Edge(
184 DArrayList<uint> poly2tri,
185 DArrayList<uint> polygonIndex,
186 DArray<uint> scanResult,
187 DArray<uint> edgeNum,
188 uint offset)
189 {
190 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
191 if (tId >= polygonIndex.size()) return;
192
193 uint count = edgeNum[tId];
194 uint start = scanResult[tId];
195
196 if (polygonIndex[tId].size() >= 5)
197 {
198 //printf("tId- d% start: %d i: %d count: %d\n", tId, start, i, count);
199
200 for (uint i = 0; i < count; i++)
201 {
202 auto& list = poly2tri[tId];
203 list[i] = offset + start + i;
204 printf("tId- %d , start: %d, i: %d, result: %d , listsize: %d\n",tId, start,i,poly2tri[tId][i], list.size());
205
206 }
207 }
208
209 }
210
211 template<typename TDataType>
212 void PolygonSetToTriangleSetModule<TDataType>:: convert(std::shared_ptr<PolygonSet<TDataType>> polygonset, std::shared_ptr<TriangleSet<TDataType>> triset,DArrayList<uint>& poly2tri)
213 {
214 triset->clear();
215
216 auto& polylist = polygonset->polygonIndices();
217
218 auto lists = polylist.lists();
219
220
221 DArray<uint> edge3(lists.size());
222 DArray<uint> edge4(lists.size());
223 DArray<uint> edge5(lists.size());
224
225 uint polyNum = polygonset->polygonIndices().size();
226
227 DArray<uint> poly2triCounter(polyNum);
228 cuExecute(polyNum,
229 PolygonSet_CountPoly2TriangleNumber,
230 poly2triCounter,
231 polygonset->polygonIndices());
232
233 poly2tri.resize(poly2triCounter);
234
235 int tNum = thrust::reduce(thrust::device, poly2triCounter.begin(), poly2triCounter.begin() + poly2triCounter.size());
236 if (tNum < 1)
237 return;
238
239 auto& triangles = triset->getTriangles();
240 triangles.resize(tNum);
241
242 cuExecute(polyNum,
243 PolygonEdgeCounting,
244 edge3,
245 edge4,
246 edge5,
247 polygonset->polygonIndices()
248 );
249
250 uint total_num3 = thrust::reduce(thrust::device, edge3.begin(), edge3.begin() + edge3.size());
251 thrust::exclusive_scan(thrust::device, edge3.begin(), edge3.begin() + edge3.size(), edge3.begin());
252
253 cuExecute(polyNum,
254 CopyTriangles,
255 triangles,
256 polygonset->polygonIndices(),
257 edge3,
258 poly2tri
259 );
260
261 uint total_num4 = thrust::reduce(thrust::device, edge4.begin(), edge4.begin() + edge4.size());
262 thrust::exclusive_scan(thrust::device, edge4.begin(), edge4.begin() + edge4.size(), edge4.begin());
263
264
265 //poly2triCounter
266
267 cuExecute(polyNum,
268 Quads2Triangles,
269 triangles,
270 polygonset->polygonIndices(),
271 polygonset->getPoints(),
272 edge4,
273 poly2tri,
274 total_num3
275 );
276
277 uint total_num5 = thrust::reduce(thrust::device, edge5.begin(), edge5.begin() + edge5.size());
278
279
280 CArray<uint> c_p2t;
281 c_p2t.assign(poly2triCounter);
282 for (size_t i = 0; i < c_p2t.size(); i++)
283 {
284 printf("poly2triCounter: %d\n", c_p2t[i]);
285 }
286
287 cuExecute(polyNum,
288 CounterLarger5Edges,
289 poly2triCounter
290 );
291 DArray<uint> startId;
292 startId.assign(poly2triCounter);
293
294 printf("************\n");
295 c_p2t.assign(poly2triCounter);
296 for (size_t i = 0; i < c_p2t.size(); i++)
297 {
298 printf("poly2triCounter: %d\n", c_p2t[i]);
299 }
300
301 thrust::exclusive_scan(thrust::device, startId.begin(), startId.begin() + startId.size(), startId.begin());
302
303 printf("*******SCAN*****\n");
304 c_p2t.assign(startId);
305 for (size_t i = 0; i < c_p2t.size(); i++)
306 {
307 printf("startId: %d\n", c_p2t[i]);
308 }
309
310 cuExecute(polyNum,
311 updatepoly2triangleId_moreThan5Edge,
312 poly2tri,
313 polygonset->polygonIndices(),
314 startId,
315 poly2triCounter,
316 total_num3 + total_num4
317 );
318
319
320
321 int* arrayIndex;
322 cudaMalloc((void**)&arrayIndex, sizeof(int));
323 cudaMemset(arrayIndex, 0, sizeof(int));
324
325 DArray<uint> d_v5_faceIds(total_num5);
326
327 cuExecute(edge5.size(),
328 extractPolyIndices,
329 edge5,
330 d_v5_faceIds,
331 arrayIndex
332 );
333
334 CArray<uint> c_v5_faceIds;
335 c_v5_faceIds.assign(d_v5_faceIds);
336
337 EarClipper<DataType3f> earClip;
338
339 CArrayList<uint> c_polygons;
340 c_polygons.assign(polylist);
341 CArray<Vec3f> c_points;
342 c_points.assign(polygonset->getPoints());
343
344 int poly2triOffset = 0;
345 for (size_t i = 0; i < c_v5_faceIds.size(); i++)
346 {
347
348 auto ptIndexList = c_polygons[c_v5_faceIds[i]];
349 std::vector<Vec3f> pts;
350 for (size_t j = 0; j < ptIndexList.size(); j++)
351 {
352 auto pt = ptIndexList[j];
353 pts.push_back(c_points[pt]);
354 }
355
356 std::vector<TopologyModule::Triangle> c_earTriangles;
357 earClip.polyClip(pts, c_earTriangles);//
358 if (c_earTriangles.size() != (pts.size() - 2))
359 {
360 printf("EarClip Error!!\n");
361 std::vector<TopologyModule::Triangle> c_earTest;
362 earClip.polyClip(pts, c_earTest);//
363 }
364
365 for (size_t k = 0; k < c_earTriangles.size(); k++)
366 {
367 c_earTriangles[k][0] = ptIndexList[c_earTriangles[k][0]];
368 c_earTriangles[k][1] = ptIndexList[c_earTriangles[k][1]];
369 c_earTriangles[k][2] = ptIndexList[c_earTriangles[k][2]];
370 }
371
372 int aa = 1;
373
374 DArray<TopologyModule::Triangle> d_earTriangles;
375 d_earTriangles.assign(c_earTriangles);
376
377 cuExecute(d_earTriangles.size(),
378 CopyTriangles2Triangles,
379 triangles,
380 d_earTriangles,
381 total_num3 + total_num4*2 + poly2triOffset
382 );
383 d_earTriangles.clear();
384
385 poly2triOffset += (ptIndexList.size() - 2);
386 }
387
388 triset->setPoints(polygonset->getPoints());
389 triset->update();
390
391 edge3.clear();
392 edge4.clear();
393 edge5.clear();
394 poly2triCounter.clear();
395
396 d_v5_faceIds.clear();
397
398 CArrayList<uint> c_poly2tri;
399 c_poly2tri.assign(poly2tri);
400 for (size_t i = 0; i < c_poly2tri.size(); i++)
401 {
402 printf("%d: ",i);
403 auto& list = c_poly2tri[i];
404 printf("size %d: ", list.size());
405
406 for (size_t j = 0; j < list.size(); j++)
407 {
408 printf("%d - ",list[j]);
409 }
410 printf("\n");
411 }
412
413 };
414 DEFINE_CLASS(PolygonSetToTriangleSetModule);
415
416 template<typename TDataType>
417 PolygonSetToTriangleSetNode<TDataType>::PolygonSetToTriangleSetNode()
418 {
419 mPolygonSetToTriangleSetMoudle = std::make_shared<PolygonSetToTriangleSetModule<DataType3f>>();
420 this->inPolygonSet()->connect(mPolygonSetToTriangleSetMoudle->inPolygonSet());
421
422 this->stateTriangleSet()->setDataPtr(std::make_shared<TriangleSet<DataType3f>>());
423
424 this->stateTriangleSet()->promoteOuput();
425
426 auto surfaceRender = std::make_shared<GLSurfaceVisualModule>();
427 auto wireRender = std::make_shared<GLWireframeVisualModule>();
428 this->stateTriangleSet()->connect(surfaceRender->inTriangleSet());
429 this->stateTriangleSet()->connect(wireRender->inEdgeSet());
430 this->graphicsPipeline()->pushModule(surfaceRender);
431 this->graphicsPipeline()->pushModule(wireRender);
432
433 };
434 DEFINE_CLASS(PolygonSetToTriangleSetNode);
435
436}