iMSTK
Interactive Medical Simulation Toolkit
imstkTriangleToTetMap.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 "imstkTriangleToTetMap.h"
8 #include "imstkTetrahedralMesh.h"
9 #include "imstkSurfaceMesh.h"
10 #include "imstkVecDataArray.h"
11 
12 namespace imstk
13 {
14 TriangleToTetMap::TriangleToTetMap()
15 {
16  setRequiredInputType<TetrahedralMesh>(0);
17  setRequiredInputType<SurfaceMesh>(1);
18 }
19 
20 TriangleToTetMap::TriangleToTetMap(
21  std::shared_ptr<Geometry> parent,
22  std::shared_ptr<Geometry> child)
23 {
24  setParentGeometry(parent);
25  setChildGeometry(child);
26 
27  setRequiredInputType<TetrahedralMesh>(0);
28  setRequiredInputType<SurfaceMesh>(1);
29 }
30 
31 void
33 {
35 
36  m_triToTetMap.clear();
37  computeTriToTetMap(m_triToTetMap);
38 }
39 
40 void
41 TriangleToTetMap::computeTriToTetMap(std::unordered_map<int, int>& triToTetMap)
42 {
43  triToTetMap.clear();
44 
45  const std::array<Vec3i, 4> facePattern = {
46  Vec3i(0, 1, 2), Vec3i(0, 1, 3), Vec3i(0, 2, 3), Vec3i(1, 2, 3)
47  };
48 
49  auto tetMesh = std::dynamic_pointer_cast<TetrahedralMesh>(getParentGeometry());
50  auto surfMesh = std::dynamic_pointer_cast<SurfaceMesh>(getChildGeometry());
51 
52  std::shared_ptr<VecDataArray<int, 4>> tetIndicesPtr = tetMesh->getCells();
53  const VecDataArray<int, 4>& tetIndices = *tetIndicesPtr;
54 
55  std::shared_ptr<VecDataArray<int, 3>> surfIndicesPtr = surfMesh->getCells();
56  const VecDataArray<int, 3>& surfIndices = *surfIndicesPtr;
57 
58  // Hash all the triangles from the surface
59  std::unordered_map<TriCell, int> triToFaceId;
60  for (int i = 0; i < surfIndices.size(); i++)
61  {
62  const Vec3i& tri = surfIndices[i];
63 
64  // Find the corresponding parent id
65  // These are the vertex ids of the tet mesh
66  const int id0 = getParentVertexId(tri[0]);
67  const int id1 = getParentVertexId(tri[1]);
68  const int id2 = getParentVertexId(tri[2]);
69 
70  // Hash the triangle with the tet mesh ids
71  TriCell cell_a(id0, id1, id2);
72 
73  triToFaceId[cell_a] = i;
74  }
75 
76  // Hash all the triangles from the tetrahedron faces. Take note of
77  // collisions
78  // Find the corresponding tet
79  for (int i = 0; i < tetIndices.size(); i++)
80  {
81  const Vec4i& tet = tetIndices[i];
82 
83  // For every face of the tet
84  for (int k = 0; k < 4; k++)
85  {
86  TriCell cell_b(
87  tet[facePattern[k][0]],
88  tet[facePattern[k][1]],
89  tet[facePattern[k][2]]);
90 
91  // If this tet face exists in the map of hashed triangles
92  auto iter = triToFaceId.find(cell_b);
93  if (iter != triToFaceId.end())
94  {
95  const int triId = iter->second;
96  triToTetMap[triId] = i; // Map tri to tet id
97  }
98  }
99  }
100 }
101 
102 int
103 TriangleToTetMap::getParentTetId(const int triId) const
104 {
105  auto citer = m_triToTetMap.find(triId);
106  return (citer != m_triToTetMap.end()) ? citer->second : -1;
107 }
108 } // namespace imstk
Utility for triangle comparison.
void compute() override
Compute the map.
void setParentGeometry(std::shared_ptr< Geometry > parent)
Get/Set parent geometry.
int getParentTetId(const int triId) const
Get the tet id that contains the triangle.
Compound Geometry.
void computeTriToTetMap(std::unordered_map< int, int > &triToTetMap)
Compute tet vertex id to surf vertex id map.
int getParentVertexId(const int childVertexId) const
Get the mapped/corresponding parent index, given a child index. returns -1 if no correspondence found...
Represents a set of tetrahedrons & vertices via an array of Vec3d double vertices & Vec4i integer ind...
void setChildGeometry(std::shared_ptr< Geometry > child)
Get/Set child geometry.
Represents a set of triangles & vertices via an array of Vec3d double vertices & Vec3i integer indice...
void compute() override
Compute the tetra-triangle mesh map.