1#include "PointsBehindMesh.h"
3#include "GLPointVisualModule.h"
4#include "GLSurfaceVisualModule.h"
5#include "GLWireframeVisualModule.h"
7#include <thrust/sort.h>
10 template<typename TDataType>
11 PointsBehindMesh<TDataType>::PointsBehindMesh()
12 : Sampler<TDataType>()
14 this->statePointSet()->setDataPtr(std::make_shared<PointSet<TDataType>>());
15 this->statePointSet()->promoteOuput();
17 this->statePlane()->setDataPtr(std::make_shared<TriangleSet<TDataType>>());
19 this->statePosition()->allocate();
20 this->statePosition()->promoteOuput();
22 this->statePointNormal()->allocate();
23 this->statePointNormal()->promoteOuput();
25 this->statePointBelongTriangleIndex()->allocate();
28 //auto tsRender = std::make_shared<GLSurfaceVisualModule>();
29 //tsRender->setColor(Color(0.1f, 0.12f, 0.25f));
30 //tsRender->varAlpha()->setValue(0.5);
31 //tsRender->setVisible(true);
32 //this->statePlane()->connect(tsRender->inTriangleSet());
33 //this->graphicsPipeline()->pushModule(tsRender);
35 auto esRender = std::make_shared<GLWireframeVisualModule>();
36 esRender->varBaseColor()->setValue(Color(0, 0, 0));
37 this->statePlane()->connect(esRender->inEdgeSet());
38 this->graphicsPipeline()->pushModule(esRender);
40 auto ptRender = std::make_shared<GLPointVisualModule>();
41 ptRender->setColor(Color(0, 0.5, 1));
42 ptRender->varPointSize()->setValue(0.005f);
43 ptRender->setColorMapMode(GLPointVisualModule::PER_VERTEX_SHADER);
44 this->statePointSet()->connect(ptRender->inPointSet());
45 this->graphicsPipeline()->pushModule(ptRender);
47 m_NeighborPointQuery = std::make_shared<NeighborPointQuery<TDataType>>();
48 this->statePosition()->connect(m_NeighborPointQuery->inPosition());
52 template<typename Coord>
53 __device__ Real WhetherPointInsideTriangle(Coord t_a, Coord t_b, Coord t_c, Coord point_o) {
55 /*@Brief : Caculate triangle arear.
60 Real abc = (ab.cross(ac)).norm() * 0.5;
62 Coord ao = point_o - t_a;
63 Coord bo = point_o - t_b;
66 Real abo = (ab.cross(ao)).norm() * 0.5;
67 Real aco = (ac.cross(ao)).norm() * 0.5;
68 Real bco = (bc.cross(bo)).norm() * 0.5;
70 return ((abo + aco + bco) - abc);
75 template<typename Coord, typename Triangle>
76 __global__ void CalculateSquareFromTriangle(
77 DArray<Coord> square_a,
78 DArray<Coord> square_b,
79 DArray<Coord> square_c,
80 DArray<Coord> square_d,
81 DArray<Triangle> triangles,
82 DArray<Coord> vertices
85 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
86 if (tId >= triangles.size()) return;
88 Triangle t = triangles[tId];
89 const Coord& v0 = vertices[t[0]];
90 const Coord& v1 = vertices[t[1]];
91 const Coord& v2 = vertices[t[2]];
93 Real lv01 = (v0 - v1).norm();
94 Real lv12 = (v1 - v2).norm();
95 Real lv02 = (v0 - v2).norm();
98 if ((lv01 >= lv12) && (lv01 >= lv02))
104 else if ((lv12 >= lv01) && (lv12 >= lv02))
110 else if ((lv02 >= lv01) && (lv02 >= lv12))
117 Coord AB = square_b[tId] - square_a[tId];
118 Coord n_AB = AB / AB.norm();
119 Coord AC = C - square_a[tId];
120 Coord proj_O = square_a[tId] + (AC.dot(n_AB)) * (n_AB);
121 Coord trans_vec = C - proj_O;
123 square_c[tId] = square_a[tId] + trans_vec;
124 square_d[tId] = square_b[tId] + trans_vec;
128 template<typename Coord, typename Triangle>
129 __global__ void CalculateNewTriangle(
130 DArray<Triangle> NewTriangles,
131 DArray<Coord> square_a,
132 DArray<Coord> square_b,
133 DArray<Coord> square_c,
134 DArray<Coord> square_d,
135 DArray<Coord> vertices
138 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
139 if (tId >= square_a.size()) return;
143 vertices[v_id] = square_a[tId];
144 vertices[v_id + 1] = square_b[tId];
145 vertices[v_id + 2] = square_c[tId];
146 vertices[v_id + 3] = square_d[tId];
150 Triangle& t0 = NewTriangles[t_id];
155 Triangle& t1 = NewTriangles[t_id + 1];
164 template<typename Coord, typename Triangle, typename Real>
165 __global__ void CalculateTriangleBasicVector(
166 DArray<Triangle> triangles,
167 DArray<Coord> vertices,
168 DArray<Coord> basic_x,
169 DArray<Coord> basic_y,
170 DArray<Coord> basic_z,
171 DArray<Coord> square_a,
172 DArray<Coord> square_b,
173 DArray<Coord> square_c,
174 DArray<Coord> square_d,
178 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
179 if (tId >= triangles.size()) return;
181 Coord& n_x = basic_x[tId];
182 Coord& n_y = basic_y[tId];
183 Coord& n_z = basic_z[tId];
185 n_x = (square_b[tId] - square_a[tId]) / (square_b[tId] - square_a[tId]).norm();
186 n_y = (square_c[tId] - square_a[tId]) / (square_c[tId] - square_a[tId]).norm();
188 n_z = n_x.cross(n_y);
189 n_z = n_z / n_z.norm();
193 template<typename Coord, typename Real, typename Triangle>
194 __global__ void CalculatePointSizeInSquare(
195 DArray<int> PointSize,
196 DArray<Triangle> triangles,
197 DArray<Coord> vertices,
198 DArray<Coord> basic_x,
199 DArray<Coord> basic_y,
200 DArray<Coord> basic_z,
201 DArray<Coord> square_a,
202 DArray<Coord> square_b,
203 DArray<Coord> square_c,
204 DArray<Coord> square_d,
208 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
209 if (tId >= PointSize.size()) return;
211 int& size = PointSize[tId];
214 int num_x = (int)((square_a[tId] - square_c[tId]).norm() / dx);
215 int num_y = (int)((square_a[tId] - square_b[tId]).norm() / dx);
217 Triangle t = triangles[tId];
218 const Coord& v0 = vertices[t[0]];
219 const Coord& v1 = vertices[t[1]];
220 const Coord& v2 = vertices[t[2]];
222 for (int j = 0; j <= num_y + 1; j++)
224 for (int i = 0; i <= num_x + 1; i++)
226 int count = i + j * num_x;
228 //if (count < size) {
229 Coord candi = square_a[tId] + (Real)(j)*dx * basic_x[tId] + (Real)(i)*dx * basic_y[tId];
230 Real value = WhetherPointInsideTriangle(v0, v1, v2, candi);
231 if (value < 100000000 * dx * dx * EPSILON) {
240 template<typename Matrix, typename Coord, typename Real, typename Triangle>
241 __global__ void CalculatePointsOnPlane(
242 DArray<Matrix> Rotation,
243 DArray<Coord> Normal,
244 DArray<Triangle> triangles,
248 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
249 if (tId >= Normal.size()) return;
254 template<typename Coord, typename Real, typename Triangle>
255 __global__ void CalculatePointInSquare(
256 DArray<Coord> Points,
257 DArray<int> PointSize,
259 DArray<Coord> PointNormal,
260 DArray<int> PointOfTriangle,
261 DArray<Triangle> triangles,
262 DArray<Coord> vertices,
263 DArray<Coord> basic_x,
264 DArray<Coord> basic_y,
265 DArray<Coord> PlaneNormal,
266 DArray<Coord> square_a,
267 DArray<Coord> square_b,
268 DArray<Coord> square_c,
269 DArray<Coord> square_d,
274 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
275 if (tId >= PointSize.size()) return;
278 int num_x = (int)((square_a[tId] - square_c[tId]).norm() / dx);
279 int num_y = (int)((square_a[tId] - square_b[tId]).norm() / dx);
280 int& begin = tIndex[tId];
281 int& size = PointSize[tId];
284 Triangle t = triangles[tId];
285 const Coord& v0 = vertices[t[0]];
286 const Coord& v1 = vertices[t[1]];
287 const Coord& v2 = vertices[t[2]];
291 for (int j = 0; j <= num_y + 1; j++)
293 for (int i = 0; i <= num_x + 1; i++)
295 //int count = i + j * num_x;
296 if (counter < size) {
298 Coord candi = square_a[tId] + (Real)(j)*dx * basic_x[tId] + (Real)(i)*dx * basic_y[tId];
299 Real value = WhetherPointInsideTriangle(v0, v1, v2, candi);
301 if (value < 100000000 * dx * dx * EPSILON)
303 Points[begin + counter] = candi;
304 PointOfTriangle[begin + counter] = tId;
305 PointNormal[begin + counter] = -1.0 * PlaneNormal[tId];
314 template<typename Coord, typename Real>
315 __global__ void CalculateGrowingPointSize(
316 DArray<Coord> GrowingPoints,
317 DArray<Coord> SeedPoints,
318 DArray<Coord> Normals,
319 DArray<Coord> outPointNormals,
320 DArray<int> SeedOfTriangleId,
321 DArray<int> PointOfTriangleId,
328 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
329 if (tId >= SeedPoints.size()) return;
331 if (direction == true)
333 SeedPoints[tId] -= Normals[tId] * dx * 0.5;
334 for (int i = 0; i < pointsLayer; i++)
336 GrowingPoints[pointsLayer * tId + i] = SeedPoints[tId] - (Real)(i)*dx * Normals[tId];
337 outPointNormals[pointsLayer * tId + i] = Normals[tId];
338 PointOfTriangleId[pointsLayer * tId + i] = SeedOfTriangleId[tId];
343 SeedPoints[tId] += Normals[tId] * dx * 0.5;
344 for (int i = 0; i < pointsLayer; i++)
346 GrowingPoints[pointsLayer * tId + i] = SeedPoints[tId] + (Real)(i)*dx * Normals[tId];
347 outPointNormals[pointsLayer * tId + i] = -Normals[tId];
348 PointOfTriangleId[pointsLayer * tId + i] = SeedOfTriangleId[tId];
355 template<typename Coord, typename Real>
356 __global__ void CalculateRemovingPointFlag(
358 DArray<Coord> positions,
359 DArrayList<int> neighbors,
363 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
364 if (pId >= flags.size()) return;
368 List<int>& list_i = neighbors[pId];
369 int nbSize = list_i.size();
370 for (int ne = 0; ne < nbSize; ne++)
373 if (pId == j) continue;
374 Real r = (positions[pId] - positions[j]).norm();
375 if ((threshold_r > r) && (pId < j)) //
383 __global__ void CalculateGhostCounter(
388 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
389 if (tId >= flags.size()) return;
391 counter[tId] = flags[tId] ? 0 : 1;
395 template<typename Coord>
396 __global__ void CalculateLastGhostPoints(
397 DArray<Coord> lastPoints,
398 DArray<Coord> originalPoints,
399 DArray<Coord> lastNormals,
400 DArray<Coord> originalNormals,
404 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
405 if (pId >= originalPoints.size()) return;
407 if (pId == originalPoints.size() - 1 || radix[pId] != radix[pId + 1])
409 lastPoints[radix[pId]] = originalPoints[pId];
410 lastNormals[radix[pId]] = originalNormals[pId];
414 template< typename Coord>
415 __global__ void PtsBehindMesh_UpdateTriangleNormal(
416 DArray<TopologyModule::Triangle> d_triangles,
417 DArray<Coord> d_points,
418 DArray<Coord> normal,
422 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
423 if (pId >= d_triangles.size()) return;
425 int a = d_triangles[pId][0];
426 int b = d_triangles[pId][1];
427 int c = d_triangles[pId][2];
429 float x = (d_points[a][0] + d_points[b][0] + d_points[c][0]) / 3;
430 float y = (d_points[a][1] + d_points[b][1] + d_points[c][1]) / 3;
431 float z = (d_points[a][2] + d_points[b][2] + d_points[c][2]) / 3;
433 Coord ca = d_points[b] - d_points[a];
434 Coord cb = d_points[b] - d_points[c];
438 dirNormal = ca.cross(cb).normalize() * -1 * length;
440 dirNormal = ca.cross(cb) * -1 * length;
442 normal[pId] = dirNormal.normalize();
446 template<typename TDataType>
447 void PointsBehindMesh<TDataType>::resetStates()
449 //Normal<TDataType>::resetStates();
451 int triangle_num = this->inTriangleSet()->getData().getTriangles().size();
452 //auto& m_triangle_normal = this->stateNormal()->getData();
454 if (triangle_num == 0) return;
456 this->outPointGrowthDirection()->setValue(this->varGeneratingDirection()->getValue());
458 Real dx = this->varSamplingDistance()->getValue();
460 if (mTriangleNormal.size() != triangle_num)
462 mTriangleNormal.resize(triangle_num);
465 if (msquare_1.size() != triangle_num)
467 msquare_1.resize(triangle_num);
468 msquare_2.resize(triangle_num);
469 msquare_3.resize(triangle_num);
470 msquare_4.resize(triangle_num);
473 if (mBasicVector_x.size() != triangle_num)
475 mBasicVector_x.resize(triangle_num);
476 mBasicVector_y.resize(triangle_num);
477 mBasicVector_z.resize(triangle_num);
478 mThinPointSize.resize(triangle_num);
481 if (mTriangleTempt.size() != 2 * triangle_num)
482 mTriangleTempt.resize(2 * triangle_num);
483 if (mVerticesTempt.size() != 4 * triangle_num)
484 mVerticesTempt.resize(4 * triangle_num);
486 cuExecute(triangle_num,
487 PtsBehindMesh_UpdateTriangleNormal,
488 this->inTriangleSet()->getData().getTriangles(), //DArray<TopologyModule::Triangle> d_triangles,
489 this->inTriangleSet()->getData().getPoints(),
490 //DArray<TopologyModule::Edge> edges,
491 //DArray<Coord> normal_points,
493 //DArray<Coord> triangleCenter,
500 cuExecute(triangle_num,
501 CalculateSquareFromTriangle,
506 this->inTriangleSet()->getData().getTriangles(),
507 this->inTriangleSet()->getData().getPoints()
510 cuExecute(triangle_num,
511 CalculateNewTriangle,
520 auto& temp_triangleSet = this->statePlane()->getData();
521 temp_triangleSet.setTriangles(mTriangleTempt);
522 temp_triangleSet.setPoints(mVerticesTempt);
524 cuExecute(triangle_num,
525 CalculateTriangleBasicVector,
526 this->inTriangleSet()->getData().getTriangles(),
527 this->inTriangleSet()->getData().getPoints(),
535 this->varSamplingDistance()->getValue()
538 cuExecute(triangle_num,
539 CalculatePointSizeInSquare,
541 this->inTriangleSet()->getData().getTriangles(),
542 this->inTriangleSet()->getData().getPoints(),
550 this->varSamplingDistance()->getValue()
553 Reduction<int> reduce;
554 int total_ghostpoint_number = reduce.accumulate(mThinPointSize.begin(), mThinPointSize.size());
556 if (total_ghostpoint_number <= 0)
562 tIndex.assign(mThinPointSize);
565 DArray<Coord> mThinPointNormal;
566 mThinPointNormal.resize(total_ghostpoint_number);
568 mThinPoints.resize(total_ghostpoint_number);
569 mSeedOfTriangleId.resize(total_ghostpoint_number);
571 thrust::exclusive_scan(thrust::device, tIndex.begin(), tIndex.begin() + tIndex.size(), tIndex.begin());
573 cuExecute(triangle_num,
574 CalculatePointInSquare,
580 this->inTriangleSet()->getData().getTriangles(),
581 this->inTriangleSet()->getData().getPoints(),
584 mTriangleNormal, //this->stateNormal()->getData(),
589 this->varSamplingDistance()->getValue()
592 int pointLayerCount = (int)(this->varThickness()->getValue() / this->varSamplingDistance()->getValue());
593 pointLayerCount = pointLayerCount < 1 ? 1 : pointLayerCount;
595 mThickPoints.resize(mThinPoints.size() * pointLayerCount);
597 mPointOfTriangleId.resize(mThinPoints.size() * pointLayerCount);
600 DArray<Coord> mThickPointNormals;
601 mThickPointNormals.resize(mThinPoints.size() * pointLayerCount);
603 cuExecute(mThinPoints.size(),
604 CalculateGrowingPointSize,
611 this->varThickness()->getValue(),
613 this->varGeneratingDirection()->getValue(),
617 if (mRemovingFlag.size() != mThickPoints.size())
619 mRemovingFlag.resize(mThickPoints.size());
622 this->statePosition()->getData().assign(mThickPoints);
623 this->statePosition()->connect(m_NeighborPointQuery->inPosition());
624 m_NeighborPointQuery->inRadius()->setValue(this->varSamplingDistance()->getValue() * 1.0);
625 m_NeighborPointQuery->update();
627 cuExecute(mThickPoints.size(),
628 CalculateRemovingPointFlag,
631 m_NeighborPointQuery->outNeighborIds()->getData(),
632 0.75f * this->varSamplingDistance()->getValue()
635 DArray<int> ghost_counter(mRemovingFlag.size());
637 cuExecute(mThickPoints.size(),
638 CalculateGhostCounter,
643 int last_ghostpoint_number = reduce.accumulate(ghost_counter.begin(), ghost_counter.size());
644 scan.exclusive(ghost_counter.begin(), ghost_counter.size());
646 DArray<Coord> lastPoints(last_ghostpoint_number);
647 auto& lastPointNormal = this->statePointNormal()->getData();
648 lastPointNormal.resize(last_ghostpoint_number);
650 this->statePointNormal()->resize(last_ghostpoint_number);
652 if (last_ghostpoint_number > 0)
654 cuExecute(mThickPoints.size(),
655 CalculateLastGhostPoints,
658 this->statePointNormal()->getData(),
664 auto& ghostPointSet = this->statePointSet()->getData();
665 this->statePosition()->getData().clear();
666 this->statePosition()->getData().assign(lastPoints);
667 this->statePointSet()->getData().clear();
668 this->statePointSet()->getData().setPoints(lastPoints);
670 this->outSamplingDistance()->setValue(this->varSamplingDistance()->getValue());
671 this->statePointBelongTriangleIndex()->assign(mPointOfTriangleId);
678 ghost_counter.clear();
679 mThinPointNormal.clear();
680 mThickPointNormals.clear();
685 DEFINE_CLASS(PointsBehindMesh);