7 #include "imstkPointToTetMap.h" 8 #include "imstkLogger.h" 9 #include "imstkParallelUtils.h" 10 #include "imstkTetrahedralMesh.h" 11 #include "imstkVecDataArray.h" 15 PointToTetMap::PointToTetMap() : m_boundingBoxAvailable(false)
17 setRequiredInputType<TetrahedralMesh>(0);
18 setRequiredInputType<PointSet>(1);
21 PointToTetMap::PointToTetMap(
22 std::shared_ptr<Geometry> parent,
23 std::shared_ptr<Geometry> child)
24 : m_boundingBoxAvailable(false)
26 setRequiredInputType<TetrahedralMesh>(0);
27 setRequiredInputType<PointSet>(1);
38 LOG(WARNING) <<
"PointToTetMap failed to run, inputs not satisfied";
41 auto tetMesh = std::dynamic_pointer_cast<
TetrahedralMesh>(getParentGeometry());
42 auto triMesh = std::dynamic_pointer_cast<
PointSet>(getChildGeometry());
44 m_verticesEnclosingTetraId.
clear();
45 m_verticesWeights.clear();
46 m_verticesEnclosingTetraId.resize(triMesh->getNumVertices());
47 m_verticesWeights.resize(triMesh->getNumVertices());
48 m_childVerts = triMesh->getVertexPositions();
51 if (!m_boundingBoxAvailable)
57 ParallelUtils::parallelFor(triMesh->getNumVertices(),
58 [&](
const int vertexIdx)
64 const Vec3d& surfVertPos = triMesh->getVertexPosition(vertexIdx);
67 int closestTetId = findEnclosingTetrahedron(surfVertPos);
68 if (closestTetId == IMSTK_INT_MAX)
70 closestTetId = findClosestTetrahedron(surfVertPos);
72 if (closestTetId == IMSTK_INT_MAX)
74 LOG(WARNING) <<
"Could not find closest tetrahedron";
80 const Vec4d weights = tetMesh->computeBarycentricWeights(closestTetId, surfVertPos);
82 m_verticesEnclosingTetraId[vertexIdx] = closestTetId;
83 m_verticesWeights[vertexIdx] = weights;
89 m_verticesEnclosingTetraId.clear();
90 m_verticesWeights.clear();
97 auto tetMesh = std::dynamic_pointer_cast<
TetrahedralMesh>(getParentGeometry());
98 auto pointSet = std::dynamic_pointer_cast<
PointSet>(getChildGeometry());
100 std::shared_ptr<VecDataArray<int, 4>> parentIndicesPtr = tetMesh->getCells();
102 std::shared_ptr<VecDataArray<double, 3>> parentVertsPtr = tetMesh->getVertexPositions();
107 ParallelUtils::parallelFor(pointSet->getNumVertices(),
108 [&](
const int vertexId)
111 parentIndices[m_verticesEnclosingTetraId[vertexId]];
112 const Vec4d& weights = m_verticesWeights[vertexId];
114 childVerts[vertexId] = parentVerts[tet[0]] * weights[0] +
115 parentVerts[tet[1]] * weights[1] +
116 parentVerts[tet[2]] * weights[2] +
117 parentVerts[tet[3]] * weights[3];
128 auto tetMesh = std::dynamic_pointer_cast<
TetrahedralMesh>(getParentGeometry());
129 double closestDistanceSqr = IMSTK_DOUBLE_MAX;
130 int closestTetrahedron = IMSTK_INT_MAX;
131 Vec3d center(0.0, 0.0, 0.0);
133 for (
int tetId = 0; tetId < tetMesh->getNumCells(); tetId++)
135 center = Vec3d::Zero();
136 const Vec4i& vert = (*tetMesh->getCells())[tetId];
137 for (
int i = 0; i < 4; i++)
139 center += tetMesh->getInitialVertexPosition(vert[i]);
141 center = center / 4.0;
143 const double distSqr = (pos - center).squaredNorm();
144 if (distSqr < closestDistanceSqr)
146 closestDistanceSqr = distSqr;
147 closestTetrahedron = tetId;
151 return closestTetrahedron;
157 auto tetMesh = std::dynamic_pointer_cast<
TetrahedralMesh>(getParentGeometry());
158 int enclosingTetrahedron = IMSTK_INT_MAX;
160 for (
int idx = 0; idx < tetMesh->getNumCells(); idx++)
162 const bool inBox = (pos[0] >= m_bBoxMin[idx][0] && pos[0] <= m_bBoxMax[idx][0])
163 && (pos[1] >= m_bBoxMin[idx][1] && pos[1] <= m_bBoxMax[idx][1])
164 && (pos[2] >= m_bBoxMin[idx][2] && pos[2] <= m_bBoxMax[idx][2]);
173 const Vec4d weights = tetMesh->computeBarycentricWeights(idx, pos);
174 if (weights[0] >= 0 && weights[1] >= 0 && weights[2] >= 0 && weights[3] >= 0)
176 enclosingTetrahedron = idx;
181 return enclosingTetrahedron;
187 auto tetMesh = std::dynamic_pointer_cast<
TetrahedralMesh>(getParentGeometry());
188 m_bBoxMin.resize(tetMesh->getNumCells());
189 m_bBoxMax.resize(tetMesh->getNumCells());
191 ParallelUtils::parallelFor(tetMesh->getNumCells(),
194 tetMesh->computeTetrahedronBoundingBox(tid, m_bBoxMin[tid], m_bBoxMax[tid]);
197 m_boundingBoxAvailable =
true;
Base class for all geometries represented by discrete points and elements The pointsets follow a pipe...
void compute() override
Compute the tetra-triangle mesh map.
void requestUpdate() override
Apply (if active) the tetra-triangle mesh map.
void updateBoundingBox()
Update bounding box of each tetrahedra of the mesh.
void setParentGeometry(std::shared_ptr< Geometry > parent)
Get/Set parent geometry.
int findClosestTetrahedron(const Vec3d &pos) const
Find the closest tetrahedron based on the distance to their centroids for a given point in 3D space...
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.
void postModified()
emits signal to all observers, informing them on the current address in memory and size of array ...
virtual void clear()
Clears all the mesh data.
virtual bool areInputsValid()
Check inputs are correct.
void setOutput(std::shared_ptr< Geometry > inputGeometry, const size_t port=0)
Set the output at the port.
int findEnclosingTetrahedron(const Vec3d &pos) const
Find the tetrahedron that encloses a given point in 3D space.