67 template <
typename triangulationType>
70 const triangulationType &triangulation)
const;
78 std::array<SimplexId, 4> faceIds_{-1, -1, -1, -1};
80 std::array<SimplexId, 4> vertsOrder_{-1, -1, -1, -1};
82 friend bool operator<(
const Simplex &lhs,
const Simplex &rhs) {
83 return lhs.vertsOrder_ < rhs.vertsOrder_;
90 this->vertsOrder_[0] = offset[v];
93 template <
typename triangulationType>
97 const triangulationType &triangulation) {
101 triangulation.getEdgeVertex(e, 0, this->faceIds_[0]);
102 triangulation.getEdgeVertex(e, 1, this->faceIds_[1]);
103 this->vertsOrder_[0] = offset[this->faceIds_[0]];
104 this->vertsOrder_[1] = offset[this->faceIds_[1]];
105 std::sort(this->vertsOrder_.rbegin(), this->vertsOrder_.rend());
108 template <
typename triangulationType>
112 const triangulationType &triangulation) {
116 triangulation.getTriangleEdge(t, 0, this->faceIds_[0]);
117 triangulation.getTriangleEdge(t, 1, this->faceIds_[1]);
118 triangulation.getTriangleEdge(t, 2, this->faceIds_[2]);
119 triangulation.getTriangleVertex(t, 0, this->vertsOrder_[0]);
120 triangulation.getTriangleVertex(t, 1, this->vertsOrder_[1]);
121 triangulation.getTriangleVertex(t, 2, this->vertsOrder_[2]);
122 this->vertsOrder_[0] = offset[this->vertsOrder_[0]];
123 this->vertsOrder_[1] = offset[this->vertsOrder_[1]];
124 this->vertsOrder_[2] = offset[this->vertsOrder_[2]];
125 std::sort(this->vertsOrder_.rbegin(), this->vertsOrder_.rend());
128 template <
typename triangulationType>
132 const triangulationType &triangulation) {
136 triangulation.getCellTriangle(T, 0, this->faceIds_[0]);
137 triangulation.getCellTriangle(T, 1, this->faceIds_[1]);
138 triangulation.getCellTriangle(T, 2, this->faceIds_[2]);
139 triangulation.getCellTriangle(T, 3, this->faceIds_[3]);
140 triangulation.getCellVertex(T, 0, this->vertsOrder_[0]);
141 triangulation.getCellVertex(T, 1, this->vertsOrder_[1]);
142 triangulation.getCellVertex(T, 2, this->vertsOrder_[2]);
143 triangulation.getCellVertex(T, 3, this->vertsOrder_[3]);
144 this->vertsOrder_[0] = offset[this->vertsOrder_[0]];
145 this->vertsOrder_[1] = offset[this->vertsOrder_[1]];
146 this->vertsOrder_[2] = offset[this->vertsOrder_[2]];
147 this->vertsOrder_[3] = offset[this->vertsOrder_[3]];
148 std::sort(this->vertsOrder_.rbegin(), this->vertsOrder_.rend());
152 template <
typename triangulationType>
154 computeFiltrationOrder(
const SimplexId *
const offset,
155 const triangulationType &triangulation)
const;
157 inline void addCellBoundary(
const Simplex &c, VisitedMask &boundary)
const {
158 for(
SimplexId i = 0; i < c.dim_ + 1; ++i) {
159 const auto f{c.faceIds_[i]};
160 if(!boundary.isVisited_[f]) {
172 }
else if(cdim == 1) {
173 return cid + this->nVerts_;
174 }
else if(cdim == 2) {
175 return cid + this->nVerts_ + this->nEdges_;
176 }
else if(cdim == 3) {
177 return cid + this->nVerts_ + this->nEdges_ + this->nTri_;
182 SimplexId eliminateBoundaries(
const Simplex &c,
183 VisitedMask &boundary,
184 const std::vector<SimplexId> &filtOrder,
185 const std::vector<Simplex> &partners)
const;
187 int pairCells(std::vector<PersistencePair> &pairs,
188 std::array<std::vector<bool>, 3> &boundaries,
189 const std::vector<Simplex> &filtration,
190 const std::vector<SimplexId> &filtOrder)
const;
202 std::vector<ttk::PersistentSimplexPairs::PersistencePair> &pairs,
204 const triangulationType &triangulation)
const {
209 const auto filtration
210 = this->computeFiltrationOrder(orderField, triangulation);
212 std::array<std::vector<bool>, 3> boundaries{};
213 boundaries[0].resize(this->nVerts_,
false);
214 boundaries[1].resize(this->nEdges_,
false);
215 boundaries[2].resize(this->nTri_,
false);
218 std::vector<SimplexId> filtOrder(filtration.size());
220#ifdef TTK_ENABLE_OPENMP
221#pragma omp parallel for num_threads(threadNumber_)
223 for(
size_t i = 0; i < filtration.size(); ++i) {
224 filtOrder[filtration[i].cellId_] = i;
227 this->pairCells(pairs, boundaries, filtration, filtOrder);
229 this->
printMsg(
"Computed " + std::to_string(pairs.size())
230 +
" persistence pair" + (pairs.size() > 1 ?
"s" :
""),
231 1.0, tm.getElapsedTime(), 1);
238 ttk::PersistentSimplexPairs::computeFiltrationOrder(
240 const triangulationType &triangulation)
const {
244 std::vector<Simplex> res(this->nVerts_ + this->nEdges_ + this->nTri_
247#ifdef TTK_ENABLE_OPENMP
248#pragma omp parallel num_threads(threadNumber_)
251#ifdef TTK_ENABLE_OPENMP
252#pragma omp for nowait
254 for(
SimplexId i = 0; i < this->nVerts_; ++i) {
255 res[i].fillVert(i, offset);
258#ifdef TTK_ENABLE_OPENMP
259#pragma omp for nowait
261 for(
SimplexId i = 0; i < this->nEdges_; ++i) {
262 const auto o = this->nVerts_ + i;
263 res[o].fillEdge(i, o, offset, triangulation);
266#ifdef TTK_ENABLE_OPENMP
267#pragma omp for nowait
269 for(
SimplexId i = 0; i < this->nTri_; ++i) {
270 const auto o = this->nVerts_ + this->nEdges_ + i;
271 res[o].fillTriangle(i, o, offset, triangulation);
274#ifdef TTK_ENABLE_OPENMP
277 for(
SimplexId i = 0; i < this->nTetra_; ++i) {
278 const auto o = this->nVerts_ + this->nEdges_ + this->nTri_ + i;
279 res[o].fillTetra(i, o, offset, triangulation);
283 TTK_PSORT(this->threadNumber_, res.begin(), res.end());
286 "Computed filtration order", 1.0, tm.getElapsedTime(), this->threadNumber_);