iMSTK
Interactive Medical Simulation Toolkit
imstkCellMesh.h
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 "imstkAbstractCellMesh.h"
8 
9 #pragma once
10 
11 namespace imstk
12 {
22 template<int N>
23 class CellMesh : public AbstractCellMesh
24 {
25 public:
26  static constexpr int CellVertexCount = N;
29  using CellType = Eigen::Matrix<int, N, 1>;
30 
31  CellMesh() : m_indices(std::make_shared<VecDataArray<int, N>>()) { }
32  ~CellMesh() override = default;
33 
38  void initialize(std::shared_ptr<VecDataArray<double, 3>> vertices,
39  std::shared_ptr<VecDataArray<int, N>> indices)
40  {
41  clear();
42 
43  PointSet::initialize(vertices);
44  setCells(indices);
45  }
46 
50  int getCellVertexCount() const override { return CellVertexCount; }
51 
52  void clear() override
53  {
55  if (m_indices != nullptr)
56  {
57  m_indices->clear();
58  }
59  }
60 
64  void computeVertexToCellMap() override
65  {
66  m_vertexToCells.clear();
67  m_vertexToCells.resize(m_vertexPositions->size());
68 
69  int cellId = 0;
70  for (const auto& cell : *m_indices)
71  {
72  // \todo: Could variadic unfold
73  // Subclasses can implement a more efficient version if needbe
74  for (int i = 0; i < N; i++)
75  {
76  m_vertexToCells.at(cell[i]).insert(cellId);
77  }
78  cellId++;
79  }
80  }
81 
85  void computeVertexNeighbors() override
86  {
88  m_vertexToNeighborVertex.resize(m_vertexPositions->size());
89  this->computeVertexToCellMap();
90 
91  // For every vertex
92  const VecDataArray<int, N>& indices = *m_indices;
93  for (size_t vertexId = 0; vertexId < m_vertexToNeighborVertex.size(); vertexId++)
94  {
95  // For every cell it is connected too
96  for (const int cellId : m_vertexToCells.at(vertexId))
97  {
98  // For every vertex of that cell
99  for (int i = 0; i < N; i++)
100  {
101  // So long as its not the source vertex (not a neighbor of itself)
102  const int vertexId2 = indices[cellId][i];
103  if (vertexId2 != static_cast<int>(vertexId))
104  {
105  m_vertexToNeighborVertex.at(vertexId).insert(vertexId2);
106  }
107  }
108  }
109  }
110  }
111 
115  virtual Eigen::Vector<double, N> computeBarycentricWeights(const int imstkNotUsed(cellId),
116  const Vec3d& imstkNotUsed(pos)) const
117  {
118  return Eigen::Vector<double, N>::Zero();
119  }
120 
124  Vec3d computeWorldPosition(const int cellId,
125  const Eigen::Matrix<double, N, 1>& bary) const
126  {
127  Vec3d position = Vec3d::Zero();
128 
129  const VecDataArray<double, 3>& vertices = *m_vertexPositions;
130  const VecDataArray<int, N>& indices = *m_indices;
131 
132  const Eigen::Matrix<int, N, 1>& cell = indices[cellId];
133 
134  for (int i = 0; i < N; i++)
135  {
136  position += vertices[cell[i]] * bary[i];
137  }
138  return position;
139  }
140 
141  std::shared_ptr<AbstractDataArray> getAbstractCells() const override { return m_indices; }
142 
146  void setCells(std::shared_ptr<VecDataArray<int, N>> indices) { m_indices = indices; }
147  std::shared_ptr<VecDataArray<int, N>> getCells() const { return m_indices; }
149 
153  int getNumCells() const override { return m_indices->size(); }
154 
159  std::unique_ptr<CellMesh<N>> clone()
160  {
161  return std::unique_ptr<CellMesh<N>>(cloneImplementation());
162  }
163 
164 protected:
165  std::shared_ptr<VecDataArray<int, N>> m_indices = nullptr;
166 
167 private:
168  CellMesh<N>* cloneImplementation() const
169  {
170  // Do shallow copy
171  CellMesh<N>* geom = new CellMesh<N>(*this);
172  // Deal with deep copy members
173  geom->m_indices = std::make_shared<VecDataArray<int, N>>(*m_indices);
174  for (auto i : m_cellAttributes)
175  {
176  geom->m_cellAttributes[i.first] = i.second->clone();
177  }
178  geom->m_initialVertexPositions = std::make_shared<VecDataArray<double, 3>>(*m_initialVertexPositions);
179  geom->m_vertexPositions = std::make_shared<VecDataArray<double, 3>>(*m_vertexPositions);
180  for (auto i : m_vertexAttributes)
181  {
182  geom->m_vertexAttributes[i.first] = i.second->clone();
183  }
184  return geom;
185  }
186 };
187 } // namespace imstk
void initialize(std::shared_ptr< VecDataArray< double, 3 >> positions)
Initializes the data structure given vertex positions.
std::unique_ptr< CellMesh< N > > clone()
Polymorphic clone, hides the declaration in superclass return own type.
virtual Eigen::Vector< double, N > computeBarycentricWeights(const int imstkNotUsed(cellId), const Vec3d &imstkNotUsed(pos)) const
compute the barycentric weights of a given point in 3D space for a given the cell ...
void computeVertexNeighbors() override
Computes neighboring vertices for all vertices.
Definition: imstkCellMesh.h:85
std::shared_ptr< AbstractDataArray > getAbstractCells() const override
Get cells as abstract array. Overridden by derived classes to return cells as point indices...
std::vector< std::unordered_set< int > > m_vertexToNeighborVertex
Map of vertices to neighbor vertices.
void clear() override
Clears all the mesh data.
Compound Geometry.
void initialize(std::shared_ptr< VecDataArray< double, 3 >> vertices, std::shared_ptr< VecDataArray< int, N >> indices)
Initializes the rest of the data structures given vertex positions and connectivity.
Definition: imstkCellMesh.h:38
int getNumCells() const override
Returns the number of cells.
void setCells(std::shared_ptr< VecDataArray< int, N >> indices)
Get/Set cell connectivity.
std::vector< std::unordered_set< int > > m_vertexToCells
Map of vertices to neighbor cells.
void clear() override
Clears all the mesh data.
Definition: imstkCellMesh.h:52
Abstract template base class for all meshes that have homogenous cell types. This class allows templa...
Definition: imstkCellMesh.h:23
Vec3d computeWorldPosition(const int cellId, const Eigen::Matrix< double, N, 1 > &bary) const
compute the world position of a point in 3D given the cellId and a set of barycentric coordinates ...
int getCellVertexCount() const override
Number of verticies associated with the cell type.
Definition: imstkCellMesh.h:50
Provides non templated base for cell based meshes.
void computeVertexToCellMap() override
Computes neighboring cells for all vertices.
Definition: imstkCellMesh.h:64