iMSTK
Interactive Medical Simulation Toolkit
imstkTetraToPointSetCD.cpp
1 /*
2 ** This file is part of the Interactive Medical Simulation Toolkit (iMSTK)
3 ** iMSTK is distributed under the Apache License, Version 2.0.
4 ** See accompanying NOTICE for details.
5 */
6 
7 #include "imstkTetraToPointSetCD.h"
8 #include "imstkCollisionData.h"
9 #include "imstkParallelUtils.h"
10 #include "imstkTetrahedralMesh.h"
11 
12 namespace imstk
13 {
14 TetraToPointSetCD::TetraToPointSetCD()
15 {
16  setRequiredInputType<TetrahedralMesh>(0);
17  setRequiredInputType<PointSet>(1);
18 }
19 
20 void
22  std::shared_ptr<Geometry> geomA,
23  std::shared_ptr<Geometry> geomB,
24  std::vector<CollisionElement>& elementsA,
25  std::vector<CollisionElement>& elementsB)
26 {
27  std::shared_ptr<TetrahedralMesh> tetMesh = std::dynamic_pointer_cast<TetrahedralMesh>(geomA);
28  std::shared_ptr<PointSet> pointSet = std::dynamic_pointer_cast<PointSet>(geomB);
29 
31  m_hashTableB.insertPoints(*pointSet->getVertexPositions());
32 
33  constexpr const double eps = IMSTK_DOUBLE_EPS;
34 
35  //const VecDataArray<double, 3>& verticesMeshA = *m_tetMesh->getVertexPositions();
36  std::shared_ptr<VecDataArray<double, 3>> verticesMeshBPtr = pointSet->getVertexPositions();
37  const VecDataArray<double, 3>& verticesMeshB = *verticesMeshBPtr;
38 
39  // For every tet in meshA, test if any points lie in it
41  ParallelUtils::parallelFor(tetMesh->getNumCells(),
42  [&](const int tetIdA)
43  {
44  // Compute the bounding box of the tet
45  Vec3d min, max;
46  tetMesh->computeTetrahedronBoundingBox(tetIdA, min, max);
47 
48  // For every other point in near the bounding box
49  std::vector<size_t> meshBVertexIds = m_hashTableB.getPointsInAABB(min, max);
50  for (size_t vertexIdB : meshBVertexIds)
51  {
52  Vec3d vPos = verticesMeshB[vertexIdB];
53 
54  // Now compute if the point is actually within the tet
55  const Vec4d bCoord = tetMesh->computeBarycentricWeights(tetIdA, vPos);
56  if (bCoord[0] >= -eps
57  && bCoord[1] >= -eps
58  && bCoord[2] >= -eps
59  && bCoord[3] >= -eps)
60  {
61  CellIndexElement elemA;
62  elemA.ids[0] = tetIdA;
63  elemA.idCount = 1;
64  elemA.cellType = IMSTK_TETRAHEDRON;
65 
66  CellIndexElement elemB;
67  elemB.ids[0] = static_cast<int>(vertexIdB);
68  elemB.idCount = 1;
69  elemB.cellType = IMSTK_VERTEX;
70 
71  lock.lock();
72  elementsA.push_back(elemA);
73  elementsB.push_back(elemB);
74  lock.unlock();
75  }
76  }
77  });
78 }
79 } // namespace imstk
The SpinLock class.
Definition: imstkSpinLock.h:20
void unlock()
End a thread-safe region.
Definition: imstkSpinLock.h:53
Base class for all geometries represented by discrete points and elements The pointsets follow a pipe...
Definition: imstkPointSet.h:25
Compound Geometry.
void insertPoints(const VecDataArray< double, 3 > &points)
Insert an array of points.
SpatialHashTableSeparateChaining m_hashTableB
Spatial hash table.
std::vector< size_t > getPointsInAABB(const Vec3d &corner1, const Vec3d &corner2)
Finds IDs of all points in an AABB.
Represents a set of tetrahedrons & vertices via an array of Vec3d double vertices & Vec4i integer ind...
void lock()
Start a thread-safe region, where only one thread can execute at a time until a call to the unlock fu...
Definition: imstkSpinLock.h:45
Represents a cell by a single cell id OR by N vertex ids. Which case can be determined by the idCount...
void computeCollisionDataAB(std::shared_ptr< Geometry > geomA, std::shared_ptr< Geometry > geomB, std::vector< CollisionElement > &elementsA, std::vector< CollisionElement > &elementsB) override
Compute collision data for both sides simultaneously.