11template <
typename dataType,
typename triangulationType>
13 const std::vector<Cell> &vpath,
14 const triangulationType &triangulation)
const {
19 const SimplexId numberOfCellsInPath = vpath.size();
20#ifndef TTK_ENABLE_KAMIKAZE
21 if(numberOfCellsInPath > 0) {
25 "Persistence calculation must start with a critical saddle(dim=1)");
29 for(
SimplexId i = 0; i < numberOfCellsInPath - 1; i++) {
30 Cell firstCell = vpath[i];
33 Cell secondCell = vpath[i + 1];
39 switch(firstCell.
dim_) {
41 triangulation.getVertexPoint(
42 firstCell.
id_, firstCenter[0], firstCenter[1], firstCenter[2]);
46 triangulation.getEdgeVertex(firstCell.
id_, 0, v);
47 triangulation.getVertexPoint(
48 v, firstCenter[0], firstCenter[1], firstCenter[2]);
50 triangulation.getEdgeVertex(firstCell.
id_, 1, v);
51 triangulation.getVertexPoint(v, pointAdd[0], pointAdd[1], pointAdd[2]);
52 firstCenter = firstCenter + pointAdd;
53 firstCenter = firstCenter / 2;
57 triangulation.getTriangleVertex(firstCell.
id_, 0, v);
58 triangulation.getVertexPoint(
59 v, firstCenter[0], firstCenter[1], firstCenter[2]);
61 triangulation.getTriangleVertex(firstCell.
id_, 1, v);
62 triangulation.getVertexPoint(v, pointAdd[0], pointAdd[1], pointAdd[2]);
63 firstCenter = firstCenter + pointAdd;
65 triangulation.getTriangleVertex(firstCell.
id_, 2, v);
66 triangulation.getVertexPoint(v, pointAdd[0], pointAdd[1], pointAdd[2]);
67 firstCenter = firstCenter + pointAdd;
68 firstCenter = firstCenter / 3;
72 triangulation.getCellVertex(firstCell.
id_, 0, v);
73 triangulation.getVertexPoint(
74 v, firstCenter[0], firstCenter[1], firstCenter[2]);
76 triangulation.getCellVertex(firstCell.
id_, 1, v);
77 triangulation.getVertexPoint(v, pointAdd[0], pointAdd[1], pointAdd[2]);
78 firstCenter = firstCenter + pointAdd;
80 triangulation.getCellVertex(firstCell.
id_, 2, v);
81 triangulation.getVertexPoint(v, pointAdd[0], pointAdd[1], pointAdd[2]);
82 firstCenter = firstCenter + pointAdd;
84 triangulation.getCellVertex(firstCell.
id_, 3, v);
85 triangulation.getVertexPoint(v, pointAdd[0], pointAdd[1], pointAdd[2]);
86 firstCenter = firstCenter + pointAdd;
87 firstCenter = firstCenter / 4;
91 switch(secondCell.
dim_) {
93 triangulation.getVertexPoint(
94 secondCell.
id_, secondCenter[0], secondCenter[1], secondCenter[2]);
98 triangulation.getEdgeVertex(secondCell.
id_, 0, v);
99 triangulation.getVertexPoint(
100 v, secondCenter[0], secondCenter[1], secondCenter[2]);
102 triangulation.getEdgeVertex(secondCell.
id_, 1, v);
103 triangulation.getVertexPoint(v, pointAdd[0], pointAdd[1], pointAdd[2]);
104 secondCenter = secondCenter + pointAdd;
105 secondCenter = secondCenter / 2;
109 triangulation.getTriangleVertex(secondCell.
id_, 0, v);
110 triangulation.getVertexPoint(
111 v, secondCenter[0], secondCenter[1], secondCenter[2]);
113 triangulation.getTriangleVertex(secondCell.
id_, 1, v);
114 triangulation.getVertexPoint(v, pointAdd[0], pointAdd[1], pointAdd[2]);
115 secondCenter = secondCenter + pointAdd;
117 triangulation.getTriangleVertex(secondCell.
id_, 2, v);
118 triangulation.getVertexPoint(v, pointAdd[0], pointAdd[1], pointAdd[2]);
119 secondCenter = secondCenter + pointAdd;
120 secondCenter = secondCenter / 3;
124 triangulation.getCellVertex(secondCell.
id_, 0, v);
125 triangulation.getVertexPoint(
126 v, secondCenter[0], secondCenter[1], secondCenter[2]);
128 triangulation.getCellVertex(secondCell.
id_, 1, v);
129 triangulation.getVertexPoint(v, pointAdd[0], pointAdd[1], pointAdd[2]);
130 secondCenter = secondCenter + pointAdd;
132 triangulation.getCellVertex(secondCell.
id_, 2, v);
133 triangulation.getVertexPoint(v, pointAdd[0], pointAdd[1], pointAdd[2]);
134 secondCenter = secondCenter + pointAdd;
136 triangulation.getCellVertex(secondCell.
id_, 3, v);
137 triangulation.getVertexPoint(v, pointAdd[0], pointAdd[1], pointAdd[2]);
138 secondCenter = secondCenter + pointAdd;
139 secondCenter = secondCenter / 4;
145 if(firstCell.
dim_ < secondCell.
dim_) {
146 changeDirection = secondCenter - firstCenter;
148 changeDirection = firstCenter - secondCenter;
150 vectorValue avgVector = (firstVector + secondVector) / 2;
162template <
typename dataType,
typename triangulationType>
171 this->initMemory(triangulation);
175 this->processOutwardStars<dataType, triangulationType>(triangulation);
178 "Built discrete vectors", 1.0, tm.getElapsedTime(), this->threadNumber_);
183template <
typename dataType,
typename triangulationType>
185 const std::array<std::vector<SimplexId>, 4> &criticalCellsByDim,
186 std::vector<std::array<float, 3>> &points,
187 std::vector<char> &cellDimensions,
188 std::vector<SimplexId> &cellIds,
189 std::vector<char> &isOnBoundary,
190 std::vector<SimplexId> &PLVertexIdentifiers,
191 const triangulationType &triangulation)
const {
193 std::array<size_t, 5> partSums{};
194 for(
size_t i = 0; i < criticalCellsByDim.size(); ++i) {
195 partSums[i + 1] = partSums[i] + criticalCellsByDim[i].size();
198 const auto nCritPoints = partSums.back();
200 points.resize(nCritPoints);
201 cellDimensions.resize(nCritPoints);
202 cellIds.resize(nCritPoints);
203 isOnBoundary.resize(nCritPoints);
204 PLVertexIdentifiers.resize(nCritPoints);
206 for(
size_t i = 0; i < criticalCellsByDim.size(); ++i) {
207#ifdef TTK_ENABLE_OPENMP
208#pragma omp parallel for num_threads(threadNumber_)
210 for(
size_t j = 0; j < criticalCellsByDim[i].size(); ++j) {
211 const SimplexId cellId = criticalCellsByDim[i][j];
212 const int cellDim = i;
213 const auto o{partSums[i] + j};
215 triangulation.getCellIncenter(cellId, i, points[o].data());
216 cellDimensions[o] = cellDim;
219 triangulation.getDistributedGlobalCellId(cellId, cellDim, globalId);
220 cellIds[o] = globalId;
224 const Cell cell{
static_cast<int>(i), cellId};
227 PLVertexIdentifiers[o]
229 cell, triangulation);
236 = std::vector<std::string>{
"#" + std::to_string(i) +
"-cell(s)",
237 std::to_string(criticalCellsByDim[i].size())};
244template <
typename dataType,
typename triangulationType>
246 std::vector<std::array<float, 3>> &points,
247 std::vector<char> &cellDimensions,
248 std::vector<SimplexId> &cellIds,
249 std::vector<char> &isOnBoundary,
250 std::vector<SimplexId> &PLVertexIdentifiers,
251 const triangulationType &triangulation)
const {
253 std::array<std::vector<SimplexId>, 4> criticalCellsByDim;
256 criticalCellsByDim, points, cellDimensions, cellIds, isOnBoundary,
257 PLVertexIdentifiers, triangulation);
262template <
typename triangulationType>
264 std::array<std::vector<SimplexId>, 4> &criticalCellsByDim,
265 const triangulationType &triangulation)
const {
268 for(
int i = 0; i < dims; ++i) {
271 std::vector<std::vector<SimplexId>> critCellsPerThread(this->
threadNumber_);
277#ifdef TTK_ENABLE_OPENMP
278#pragma omp parallel for num_threads(this->threadNumber_) schedule(static)
280 for(
SimplexId j = 0; j < numberOfCells; ++j) {
281#ifdef TTK_ENABLE_OPENMP
282 const auto tid = omp_get_thread_num();
288 critCellsPerThread[tid].emplace_back(j);
292 criticalCellsByDim[i] = std::move(critCellsPerThread[0]);
293 for(
size_t j = 1; j < critCellsPerThread.size(); ++j) {
294 const auto &vec{critCellsPerThread[j]};
295 criticalCellsByDim[i].insert(
296 criticalCellsByDim[i].
end(), vec.begin(), vec.end());
303template <
typename triangulationType>
305 const int dimension,
const triangulationType &triangulation)
const {
313 return triangulation.getNumberOfVertices();
317 return triangulation.getNumberOfEdges();
321 return triangulation.getNumberOfTriangles();
325 return triangulation.getNumberOfCells();
332template <
typename dataType,
typename triangulationType>
336 float &weightValue)
const {
339#ifndef TTK_ENABLE_KAMIKAZE
340 if(vertexA == -1 || vertexB == -1) {
341 this->
printErr(
"Passed Null value to compare()");
342 return vertexA < vertexB;
344 SimplexId numberOfVertices = triangulation.getNumberOfVertices();
345 if(vertexA < 0 || vertexB < 0 || vertexA >= numberOfVertices
346 || vertexB >= numberOfVertices) {
347 std::cout << vertexA <<
"," << vertexB << std::endl;
348 this->
printErr(
"Passed invalid vertex values");
349 return vertexA < vertexB;
354 triangulation.getVertexPoint(
355 vertexA, locationA[0], locationA[1], locationA[2]);
358 triangulation.getVertexPoint(
359 vertexB, locationB[0], locationB[1], locationB[2]);
373 return vertexA < vertexB;
376template <
typename dataType,
typename triangulationType>
377inline void DiscreteVectorField::OutwardStar(
380 const triangulationType &triangulation)
const {
383 for(
auto &vec : os) {
391 const auto nedges = triangulation.getVertexEdgeNumber(a);
392 os[1].reserve(nedges);
395 triangulation.getVertexEdge(a, i, edgeId);
397 triangulation.getEdgeVertex(edgeId, 0, vertexId);
399 triangulation.getEdgeVertex(edgeId, 1, vertexId);
403 triangulation, a, vertexId, edgeWeight)) {
404 os[1].emplace_back(CellOutExt{1,
407 {-(edgeWeight), -INFINITY, -INFINITY},
412 if(os[1].size() < 2) {
417 const auto processTriangle
420 std::array<SimplexId, 3> lowVerts{-1, -1, -1};
432 float edgeWeight1, edgeWeight2;
434 triangulation, a, lowVerts[0], edgeWeight1)
436 triangulation, a, lowVerts[1],
441 std::array<uint8_t, 3>
444 for(
const auto &e : os[1]) {
445 if(e.lowVerts_[0] == lowVerts[0] || e.lowVerts_[0] == lowVerts[1]) {
451 std::array<float, 3> lowVertWeights
452 = {-(edgeWeight1), -(edgeWeight2), -INFINITY};
455 lowVertWeights[0] = -(edgeWeight2);
456 lowVertWeights[1] = -(edgeWeight1);
459 CellOutExt{2, triangleId, lowVerts, lowVertWeights, faces});
469 const auto ncells = triangulation.getVertexStarNumber(a);
470 os[2].reserve(ncells);
473 triangulation.getVertexStar(a, i, cellId);
475 triangulation.getCellVertex(cellId, 0, v0);
476 triangulation.getCellVertex(cellId, 1, v1);
477 triangulation.getCellVertex(cellId, 2, v2);
478 processTriangle(cellId, v0, v1, v2);
482 const auto ntri = triangulation.getVertexTriangleNumber(a);
486 triangulation.getVertexTriangle(a, i, triangleId);
488 triangulation.getTriangleVertex(triangleId, 0, v0);
489 triangulation.getTriangleVertex(triangleId, 1, v1);
490 triangulation.getTriangleVertex(triangleId, 2, v2);
491 processTriangle(triangleId, v0, v1, v2);
495 if(os[2].size() >= 3) {
497 const auto ncells = triangulation.getVertexStarNumber(a);
498 os[3].reserve(ncells);
501 triangulation.getVertexStar(a, i, cellId);
502 std::array<SimplexId, 3> lowVerts{-1, -1, -1};
504 triangulation.getCellVertex(cellId, 0, v0);
505 triangulation.getCellVertex(cellId, 1, v1);
506 triangulation.getCellVertex(cellId, 2, v2);
507 triangulation.getCellVertex(cellId, 3, v3);
526 float eWeight0, eWeight1, eWeight2;
528 triangulation, a, lowVerts[0], eWeight0)
530 triangulation, a, lowVerts[1], eWeight1)
532 triangulation, a, lowVerts[2], eWeight2)) {
536 std::array<uint8_t, 3> faces{};
537 for(
const auto &t : os[2]) {
541 = std::find(lowVerts.begin(), lowVerts.end(), t.lowVerts_[0])
544 = std::find(lowVerts.begin(), lowVerts.end(), t.lowVerts_[1])
547 if(vert1Found && vert2Found) {
552 std::array<float, 3> lowVertWeights
553 = {-(eWeight0), -(eWeight1), -(eWeight2)};
554 std::sort(lowVertWeights.rbegin(),
558 CellOutExt{3, cellId, lowVerts, lowVertWeights, faces});
565template <
typename triangulationType>
566inline void DiscreteVectorField::pairCells(
568#ifdef TTK_ENABLE_DCG_OPTIMIZE_MEMORY
569 char localBId{0}, localAId{0};
575 triangulation.getEdgeVertex(beta.
id_, i, a);
581 const auto nedges = triangulation.getVertexEdgeNumber(alpha.
id_);
583 triangulation.getVertexEdge(alpha.
id_, i, b);
589 }
else if(beta.
dim_ == 2) {
591 triangulation.getTriangleEdge(beta.
id_, i, a);
597 const auto ntri = triangulation.getEdgeTriangleNumber(alpha.
id_);
599 triangulation.getEdgeTriangle(alpha.
id_, i, b);
607 triangulation.getCellTriangle(beta.
id_, i, a);
613 const auto ntetra = triangulation.getTriangleStarNumber(alpha.
id_);
615 triangulation.getTriangleStar(alpha.
id_, i, b);
622 (*vectors_)[2 * alpha.
dim_][alpha.
id_] = localBId;
623 (*vectors_)[2 * alpha.
dim_ + 1][beta.
id_] = localAId;
626 (*vectors_)[2 * alpha.
dim_][alpha.
id_] = beta.
id_;
627 (*vectors_)[2 * alpha.
dim_ + 1][beta.
id_] = alpha.
id_;
633template <
typename dataType,
typename triangulationType>
634int DiscreteVectorField::processOutwardStars(
635 const triangulationType &triangulation) {
639 auto nverts = triangulation.getNumberOfVertices();
642 const auto orderCells
643 = [&](
const CellOutExt &a,
const CellOutExt &b) ->
bool {
649 = std::priority_queue<std::reference_wrapper<CellOutExt>,
650 std::vector<std::reference_wrapper<CellOutExt>>,
651 decltype(orderCells)>;
659 pqType pqZero{orderCells}, pqOne{orderCells};
664#ifdef TTK_ENABLE_OPENMP
665#pragma omp parallel for num_threads(threadNumber_) \
666 firstprivate(Lx, pqZero, pqOne)
672 while(!pqZero.empty()) {
675 while(!pqOne.empty()) {
680 const auto insertCofacets = [&](
const CellOutExt &ca, outwardStarType &ls) {
682 for(
auto &beta : ls[2]) {
684 || ls[1][beta.
faces_[1]].id_ == ca.
id_) {
686 if(numUnpairedFacesTriangle(beta, ls).first == 1) {
692 }
else if(ca.
dim_ == 2) {
693 for(
auto &beta : ls[3]) {
696 || ls[2][beta.
faces_[2]].id_ == ca.
id_) {
698 if(numUnpairedFacesTetra(beta, ls).first == 1) {
706 OutwardStar<dataType, triangulationType>(Lx, x, triangulation);
710 if(ttk::isRunningWithMPI()
712 int sizeDim = Lx.size();
713 for(
int i = 0; i < sizeDim; i++) {
714 int nCells = Lx[i].size();
715 for(
int j = 0; j < nCells; j++) {
716 setCellToGhost(Lx[i][j].dim_, Lx[i][j].id_);
728 for(
size_t i = 1; i < Lx[1].size(); ++i) {
730 const auto &b = Lx[1][i].lowVertWeights_[0];
736 auto &c_delta = Lx[1][minId];
739 pairCells(Lx[0][0], c_delta, triangulation);
742 for(
auto &alpha : Lx[1]) {
743 if(alpha.
id_ != c_delta.id_) {
751 insertCofacets(c_delta, Lx);
753 while(!pqOne.empty() || !pqZero.empty()) {
754 while(!pqOne.empty()) {
755 auto &c_alpha = pqOne.top().get();
757 auto unpairedFaces = numUnpairedFaces(c_alpha, Lx);
758 if(unpairedFaces.first == 0) {
759 pqZero.push(c_alpha);
761 auto &c_pair_alpha = Lx[c_alpha.dim_ - 1][unpairedFaces.second];
764 pairCells(c_pair_alpha, c_alpha, triangulation);
767 insertCofacets(c_alpha, Lx);
768 insertCofacets(c_pair_alpha, Lx);
774 while(!pqZero.empty() && pqZero.top().get().paired_) {
778 if(!pqZero.empty()) {
779 auto &c_gamma = pqZero.top().get();
784 c_gamma.paired_ =
true;
787 insertCofacets(c_gamma, Lx);
797template <
typename dataType,
typename triangulationType>
799 const Cell &cell,
const triangulationType &triangulation)
const {
801 if(cell.
dim_ > this->dimensionality_ || cell.
dim_ < 0 || cell.
id_ < 0) {
806 cell, triangulation)};
810 return triangulation.isVertexOnBoundary(vert);
813template <
typename triangulationType>
816 const triangulationType &triangulation,
817 bool isReverse)
const {
821 std::is_base_of<AbstractTriangulation, triangulationType>(),
822 "triangulationType should be an AbstractTriangulation derivative");
824#ifndef TTK_ENABLE_DCG_OPTIMIZE_MEMORY
828 if((cell.
dim_ > this->dimensionality_ - 1 && !isReverse)
829 || (cell.
dim_ > this->dimensionality_ && isReverse) || cell.
dim_ < 0) {
837#ifdef TTK_ENABLE_DCG_OPTIMIZE_MEMORY
838 const auto locId{(*vectors_)[0][cell.
id_]};
840 triangulation.getVertexEdge(cell.
id_, locId,
id);
843 id = (*vectors_)[0][cell.
id_];
848 else if(cell.
dim_ == 1) {
850#ifdef TTK_ENABLE_DCG_OPTIMIZE_MEMORY
851 const auto locId{(*vectors_)[1][cell.
id_]};
853 triangulation.getEdgeVertex(cell.
id_, locId,
id);
856 id = (*vectors_)[1][cell.
id_];
859#ifdef TTK_ENABLE_DCG_OPTIMIZE_MEMORY
860 const auto locId{(*vectors_)[2][cell.
id_]};
862 triangulation.getEdgeTriangle(cell.
id_, locId,
id);
865 id = (*vectors_)[2][cell.
id_];
870 else if(cell.
dim_ == 2) {
872#ifdef TTK_ENABLE_DCG_OPTIMIZE_MEMORY
873 const auto locId{(*vectors_)[3][cell.
id_]};
875 triangulation.getTriangleEdge(cell.
id_, locId,
id);
878 id = (*vectors_)[3][cell.
id_];
881#ifdef TTK_ENABLE_DCG_OPTIMIZE_MEMORY
882 const auto locId{(*vectors_)[4][cell.
id_]};
884 triangulation.getTriangleStar(cell.
id_, locId,
id);
887 id = (*vectors_)[4][cell.
id_];
892 else if(cell.
dim_ == 3) {
894#ifdef TTK_ENABLE_DCG_OPTIMIZE_MEMORY
895 const auto locId{(*vectors_)[5][cell.
id_]};
897 triangulation.getCellTriangle(cell.
id_, locId,
id);
900 id = (*vectors_)[5][cell.
id_];
908template <
typename dataType,
typename triangulationType>
911 std::vector<Cell> &vpath,
912 const triangulationType &triangulation,
913 const bool stopOnCycle)
const {
915 const SimplexId numberOfVerts = triangulation.getNumberOfVertices();
916 std::vector<char> isCycle;
917 isCycle.resize(numberOfVerts, 0);
918 int numAlternates{0};
926 if(isCycle[currentId] == 0) {
927 isCycle[currentId] = 1;
935 while(!(vpath.back() ==
Cell(0, currentId))) {
943 const Cell vertex(0, currentId);
946 connectedEdgeId = vpath.back().id_;
949 float bestWeight{std::numeric_limits<float>::max()};
950 bool firstCellCritical{
false};
951 std::vector<Cell> vpathBest;
952 int bestAlternates{0};
954 = triangulation.getEdgeTriangleNumber(connectedEdgeId);
955 for(
SimplexId i = 0; i < triangleNumber; ++i) {
957 std::vector<Cell> newVpath;
958 newVpath.emplace_back(
959 Cell(1, connectedEdgeId));
961 std::vector<char> ascIsCycle;
962 const SimplexId numberOfCells = triangulation.getNumberOfCells();
963 ascIsCycle.resize(numberOfCells, 0);
964 triangulation.getEdgeTriangle(connectedEdgeId, i, triangle);
965 Cell firstTriangle =
Cell(2, triangle);
968 firstTriangle, newVpath, triangulation, isCycle, ascIsCycle);
970 newVpath, triangulation);
973 vpathBest = newVpath;
974 bestAlternates = alternates;
977 || (weight < bestWeight
980 vpathBest = newVpath;
981 bestAlternates = alternates;
982 firstCellCritical =
true;
986 for(
Cell newCell : vpathBest) {
987 vpath.emplace_back(newCell);
989 numAlternates = 1 + bestAlternates;
994 const Cell vertex(0, currentId);
995 vpath.emplace_back(vertex);
1002 if(connectedEdgeId == -1) {
1007 const Cell edge(1, connectedEdgeId);
1008 vpath.emplace_back(edge);
1014 for(
int i = 0; i < 2; ++i) {
1016 triangulation.getEdgeVertex(connectedEdgeId, i, vertexId);
1018 if(vertexId != currentId) {
1019 currentId = vertexId;
1024 }
while(connectedEdgeId != -1);
1027 return numAlternates;
1030template <
typename dataType,
typename triangulationType>
1033 std::vector<Cell> &vpath,
1034 const triangulationType &triangulation,
1035 std::vector<char> &previousDescPaths,
1036 std::vector<char> &previousAscPaths)
const {
1038 const SimplexId numberOfVerts = triangulation.getNumberOfVertices();
1039 std::vector<char> isCycle;
1040 isCycle.resize(numberOfVerts, 0);
1041 int numAlternates{0};
1043 if(cell.
dim_ == 0) {
1049 if(isCycle[currentId] == 0) {
1050 if(previousDescPaths[currentId] == 1) {
1051 if(vpath.size() == 0) {
1053 const Cell vertex(0, currentId);
1054 vpath.emplace_back(vertex);
1058 isCycle[currentId] = 1;
1059 previousDescPaths[currentId] = 1;
1067 while(!(vpath.back() ==
Cell(0, currentId))) {
1075 const Cell vertex(0, currentId);
1078 connectedEdgeId = vpath.back().id_;
1081 float bestWeight{std::numeric_limits<float>::max()};
1082 bool firstCellCritical{
false};
1083 std::vector<Cell> vpathBest;
1084 int bestAlternates{0};
1086 = triangulation.getEdgeTriangleNumber(connectedEdgeId);
1087 for(
SimplexId i = 0; i < triangleNumber; ++i) {
1089 std::vector<Cell> newVpath;
1090 newVpath.emplace_back(
Cell(1, connectedEdgeId));
1091 triangulation.getEdgeTriangle(connectedEdgeId, i, triangle);
1092 Cell firstTriangle =
Cell(2, triangle);
1095 firstTriangle, newVpath, triangulation, previousDescPaths,
1098 newVpath, triangulation);
1100 bestWeight = weight;
1101 vpathBest = newVpath;
1102 bestAlternates = alternates;
1104 }
else if((!firstCellCritical &&
isCellCritical(newVpath.back()))
1105 || (weight < bestWeight
1107 bestWeight = weight;
1108 vpathBest = newVpath;
1109 bestAlternates = alternates;
1110 firstCellCritical =
true;
1114 for(
Cell newCell : vpathBest) {
1115 vpath.emplace_back(newCell);
1117 numAlternates = 1 + bestAlternates;
1122 const Cell vertex(0, currentId);
1123 vpath.emplace_back(vertex);
1130 if(connectedEdgeId == -1) {
1135 const Cell edge(1, connectedEdgeId);
1136 vpath.emplace_back(edge);
1142 for(
int i = 0; i < 2; ++i) {
1144 triangulation.getEdgeVertex(connectedEdgeId, i, vertexId);
1146 if(vertexId != currentId) {
1147 currentId = vertexId;
1152 }
while(connectedEdgeId != -1);
1155 return numAlternates;
1158template <
typename triangulationType>
1160 const Cell &saddle2,
1161 const Cell &saddle1,
1162 const std::vector<bool> &isVisited,
1163 std::vector<Cell> *
const vpath,
1164 const triangulationType &triangulation,
1165 const bool stopIfMultiConnected,
1166 const bool enableCycleDetector)
const {
1169 const SimplexId numberOfEdges = triangulation.getNumberOfEdges();
1170 std::vector<char> isCycle;
1171 if(enableCycleDetector) {
1172 isCycle.resize(numberOfEdges, 0);
1177 if(vpath !=
nullptr) {
1178 vpath->emplace_back(saddle2);
1183 int nconnections = 0;
1184 for(
int i = 0; i < 3; ++i) {
1186 triangulation.getTriangleEdge(saddle2.
id_, i, edgeId);
1187 if(isVisited[edgeId]) {
1190 if(vpath !=
nullptr) {
1191 vpath->emplace_back(
Cell(1, edgeId));
1200 if(stopIfMultiConnected && nconnections > 1) {
1209 if(enableCycleDetector) {
1210 if(isCycle[currentId] == 0) {
1211 isCycle[currentId] = 1;
1213 this->
printErr(
"Cycle detected on the wall of 1-saddle "
1214 + std::to_string(saddle1.
id_));
1222 const Cell edge(1, currentId);
1223 if(vpath !=
nullptr) {
1224 vpath->emplace_back(edge);
1234 const Cell triangle(2, connectedTriangleId);
1235 if(vpath !=
nullptr) {
1236 vpath->emplace_back(triangle);
1243 int nconnections = 0;
1244 for(
int i = 0; i < 3; ++i) {
1246 triangulation.getTriangleEdge(connectedTriangleId, i, edgeId);
1248 if(isVisited[edgeId] and edgeId != oldId) {
1253 if(stopIfMultiConnected && nconnections > 1) {
1258 }
while(currentId != oldId);
1264template <
typename dataType,
typename triangulationType>
1267 std::vector<Cell> &vpath,
1268 const triangulationType &triangulation,
1269 const bool stopOnCycle)
const {
1271 const SimplexId numberOfCells = triangulation.getNumberOfCells();
1272 std::vector<char> isCycle;
1273 isCycle.resize(numberOfCells, 0);
1274 int numAlternates{0};
1277 if(cell.
dim_ == 2) {
1283 if(isCycle[currentId] == 0) {
1284 isCycle[currentId] = 1;
1293 while(!(vpath.back() ==
Cell(2, currentId))) {
1301 const Cell triangle(2, currentId);
1302 connectedEdgeId =
getPairedCell(triangle, triangulation,
true);
1304 connectedEdgeId = vpath.back().id_;
1309 float bestWeight{std::numeric_limits<float>::max()};
1310 int bestAlternates{0};
1311 bool firstCellCritical{
false};
1312 std::vector<Cell> vpathBest;
1313 for(
int i = 0; i < 2; ++i) {
1315 std::vector<Cell> newVpath;
1316 newVpath.emplace_back(
Cell(1, connectedEdgeId));
1317 const SimplexId numberOfVerts = triangulation.getNumberOfVertices();
1318 std::vector<char> descIsCycle;
1319 descIsCycle.resize(numberOfVerts, 0);
1320 triangulation.getEdgeVertex(connectedEdgeId, i, vertex);
1321 Cell firstVertex =
Cell(0, vertex);
1324 firstVertex, newVpath, triangulation, descIsCycle, isCycle);
1326 newVpath, triangulation);
1328 bestWeight = weight;
1329 bestAlternates = alternates;
1330 vpathBest = newVpath;
1332 }
else if((!firstCellCritical &&
isCellCritical(newVpath.back()))
1333 || (weight < bestWeight
1335 bestWeight = weight;
1336 bestAlternates = alternates;
1337 vpathBest = newVpath;
1338 firstCellCritical =
true;
1342 for(
Cell newCell : vpathBest) {
1343 vpath.emplace_back(newCell);
1345 numAlternates = 1 + bestAlternates;
1350 const Cell triangle(2, currentId);
1351 vpath.emplace_back(triangle);
1359 if(connectedEdgeId == -1) {
1364 const Cell edge(1, connectedEdgeId);
1365 vpath.emplace_back(edge);
1372 = triangulation.getEdgeStarNumber(connectedEdgeId);
1373 for(
SimplexId i = 0; i < starNumber; ++i) {
1375 triangulation.getEdgeStar(connectedEdgeId, i, starId);
1377 if(starId != currentId) {
1384 }
while(currentId != oldId);
1387 if(cell.
dim_ == 3) {
1393 if(isCycle[currentId] == 0) {
1394 isCycle[currentId] = 1;
1402 const Cell tetra(3, currentId);
1403 vpath.emplace_back(tetra);
1411 if(connectedTriangleId == -1) {
1416 const Cell triangle(2, connectedTriangleId);
1417 vpath.emplace_back(triangle);
1424 = triangulation.getTriangleStarNumber(connectedTriangleId);
1425 for(
SimplexId i = 0; i < starNumber; ++i) {
1427 triangulation.getTriangleStar(connectedTriangleId, i, starId);
1429 if(starId != currentId) {
1436 }
while(currentId != oldId);
1440 return numAlternates;
1443template <
typename dataType,
typename triangulationType>
1446 std::vector<Cell> &vpath,
1447 const triangulationType &triangulation,
1448 std::vector<char> &previousDescPaths,
1449 std::vector<char> &previousAscPaths)
const {
1451 const SimplexId numberOfCells = triangulation.getNumberOfCells();
1452 std::vector<char> isCycle;
1453 isCycle.resize(numberOfCells, 0);
1454 int numAlternates{0};
1457 if(cell.
dim_ == 2) {
1463 if(isCycle[currentId] == 0) {
1464 if(previousAscPaths[currentId] == 1) {
1465 if(vpath.size() == 0) {
1467 const Cell triangle(2, currentId);
1468 vpath.emplace_back(triangle);
1472 isCycle[currentId] = 1;
1473 previousAscPaths[currentId] = 1;
1480 while(!(vpath.back() ==
Cell(2, currentId))) {
1488 const Cell triangle(2, currentId);
1489 connectedEdgeId =
getPairedCell(triangle, triangulation,
true);
1491 connectedEdgeId = vpath.back().id_;
1494 float bestWeight{std::numeric_limits<float>::max()};
1495 int bestAlternates{0};
1496 bool firstCellCritical{
false};
1497 std::vector<Cell> vpathBest;
1498 for(
int i = 0; i < 2; ++i) {
1500 std::vector<Cell> newVpath;
1501 newVpath.emplace_back(
Cell(1, connectedEdgeId));
1502 triangulation.getEdgeVertex(connectedEdgeId, i, vertex);
1503 Cell firstVertex =
Cell(0, vertex);
1506 firstVertex, newVpath, triangulation, previousDescPaths,
1509 newVpath, triangulation);
1511 bestWeight = weight;
1512 bestAlternates = alternates;
1513 vpathBest = newVpath;
1515 }
else if((!firstCellCritical &&
isCellCritical(newVpath.back()))
1516 || (weight < bestWeight
1518 bestWeight = weight;
1519 bestAlternates = alternates;
1520 vpathBest = newVpath;
1521 firstCellCritical =
true;
1525 for(
Cell newCell : vpathBest) {
1526 vpath.emplace_back(newCell);
1528 numAlternates = 1 + bestAlternates;
1533 const Cell triangle(2, currentId);
1534 vpath.emplace_back(triangle);
1542 if(connectedEdgeId == -1) {
1547 const Cell edge(1, connectedEdgeId);
1548 vpath.emplace_back(edge);
1555 = triangulation.getEdgeStarNumber(connectedEdgeId);
1556 for(
SimplexId i = 0; i < starNumber; ++i) {
1558 triangulation.getEdgeStar(connectedEdgeId, i, starId);
1560 if(starId != currentId) {
1567 }
while(currentId != oldId);
1570 if(cell.
dim_ == 3) {
1576 if(isCycle[currentId] == 0) {
1577 isCycle[currentId] = 1;
1585 const Cell tetra(3, currentId);
1586 vpath.emplace_back(tetra);
1594 if(connectedTriangleId == -1) {
1599 const Cell triangle(2, connectedTriangleId);
1600 vpath.emplace_back(triangle);
1607 = triangulation.getTriangleStarNumber(connectedTriangleId);
1608 for(
SimplexId i = 0; i < starNumber; ++i) {
1610 triangulation.getTriangleStar(connectedTriangleId, i, starId);
1612 if(starId != currentId) {
1619 }
while(currentId != oldId);
1623 return numAlternates;
1626template <
typename triangulationType>
1628 const Cell &saddle1,
1629 const Cell &saddle2,
1630 const std::vector<bool> &isVisited,
1631 std::vector<Cell> *
const vpath,
1632 const triangulationType &triangulation)
const {
1634 const SimplexId numberOfTriangles = triangulation.getNumberOfTriangles();
1635 std::vector<char> isCycle;
1636 isCycle.resize(numberOfTriangles, 0);
1637 std::vector<SimplexId> alternatePathStack;
1641 if(vpath !=
nullptr) {
1642 vpath->emplace_back(saddle1);
1647 int nconnections = 0;
1649 = triangulation.getEdgeTriangleNumber(saddle1.
id_);
1650 for(
SimplexId i = 0; i < triangleNumber; ++i) {
1652 triangulation.getEdgeTriangle(saddle1.
id_, i, triangleId);
1653 if(isVisited[triangleId]) {
1656 if(vpath !=
nullptr) {
1657 vpath->emplace_back(
Cell(2, triangleId));
1661 if(nconnections < 1) {
1662 currentId = triangleId;
1665 alternatePathStack.emplace_back(triangleId);
1671 if(currentId == -1) {
1673 "Current ID not updated for getAscendingPathThroughWall()");
1680 if(isCycle[currentId] == 0) {
1681 isCycle[currentId] = 1;
1684 this->
printErr(
"Cycle detected on the wall of 2-saddle "
1685 + std::to_string(saddle2.
id_));
1692 const Cell triangle(2, currentId);
1693 if(vpath !=
nullptr) {
1694 vpath->emplace_back(triangle);
1705 const Cell edge(1, connectedEdgeId);
1706 if(vpath !=
nullptr) {
1707 vpath->emplace_back(edge);
1714 int nconnections = 0;
1716 = triangulation.getEdgeTriangleNumber(connectedEdgeId);
1717 for(
SimplexId i = 0; i < triangleNumber; ++i) {
1719 triangulation.getEdgeTriangle(connectedEdgeId, i, triangleId);
1721 if(isVisited[triangleId] and triangleId != oldId
1722 and isCycle[triangleId] == 0) {
1723 if(nconnections < 1) {
1724 currentId = triangleId;
1727 alternatePathStack.emplace_back(triangleId);
1731 if(nconnections == 0) {
1733 if(!alternatePathStack.empty()) {
1734 currentId = alternatePathStack.back();
1735 alternatePathStack.pop_back();
1739 "No alternate paths detected for getAscendingPathThroughWall()");
1745 }
while(currentId != oldId);
1751template <
typename triangulationType>
1755 const triangulationType &triangulation,
1756 std::vector<Cell> *
const wall,
1757 std::vector<SimplexId> *
const saddles)
const {
1759 if(saddles !=
nullptr) {
1764 if(cell.
dim_ == 2) {
1768 std::queue<SimplexId> bfs;
1772 while(!bfs.empty()) {
1773 const SimplexId triangleId = bfs.front();
1781 if(wall !=
nullptr) {
1782 wall->emplace_back(
Cell(2, triangleId));
1785 for(
int j = 0; j < 3; ++j) {
1787 triangulation.getTriangleEdge(triangleId, j, edgeId);
1790 saddles->emplace_back(edgeId);
1796 if(pairedCellId != -1 and pairedCellId != triangleId) {
1797 bfs.push(pairedCellId);
1803 if(saddles !=
nullptr && saddles->size() > 1) {
1804 std::sort(saddles->begin(), saddles->end());
1805 const auto last = std::unique(saddles->begin(), saddles->end());
1806 saddles->erase(last, saddles->end());
1814template <
typename triangulationType>
1818 const triangulationType &triangulation,
1819 std::vector<Cell> *
const wall,
1820 std::vector<SimplexId> *
const saddles)
const {
1822 if(saddles !=
nullptr) {
1827 if(cell.
dim_ == 1) {
1831 std::queue<SimplexId> bfs;
1835 while(!bfs.empty()) {
1844 if(wall !=
nullptr) {
1845 wall->emplace_back(
Cell(1, edgeId));
1849 = triangulation.getEdgeTriangleNumber(edgeId);
1850 for(
SimplexId j = 0; j < triangleNumber; ++j) {
1852 triangulation.getEdgeTriangle(edgeId, j, triangleId);
1855 saddles->emplace_back(triangleId);
1861 if(pairedCellId != -1 and pairedCellId != edgeId) {
1862 bfs.push(pairedCellId);
1868 if(saddles !=
nullptr && saddles->size() > 1) {
1869 std::sort(saddles->begin(), saddles->end());
1870 const auto last = std::unique(saddles->begin(), saddles->end());
1871 saddles->erase(last, saddles->end());
1879template <
typename triangulationType>
1881 const std::vector<Cell> &vpath,
1882 const triangulationType &triangulation)
const {
1886 const SimplexId numberOfCellsInPath = vpath.size();
1887 for(
SimplexId i = 0; i < numberOfCellsInPath; i += 2) {
1890 if((i + 1) == numberOfCellsInPath) {
1895 const SimplexId triangleId = vpath[i + 1].id_;
1897#ifdef TTK_ENABLE_DCG_OPTIMIZE_MEMORY
1898 for(
int k = 0; k < 3; ++k) {
1900 triangulation.getCellEdge(triangleId, k, tmp);
1902 (*vectors_)[3][triangleId] = k;
1906 for(
int k = 0; k < triangulation.getEdgeStarNumber(edgeId); ++k) {
1908 triangulation.getEdgeStar(edgeId, k, tmp);
1909 if(tmp == triangleId) {
1910 (*vectors_)[2][edgeId] = k;
1916 (*vectors_)[3][triangleId] = edgeId;
1917 (*vectors_)[2][edgeId] = triangleId;
1922 const SimplexId numberOfCellsInPath = vpath.size();
1923 for(
SimplexId i = 0; i < numberOfCellsInPath; i += 2) {
1924 const SimplexId triangleId = vpath[i].id_;
1925 if((i + 1) == numberOfCellsInPath) {
1929 const SimplexId tetraId = vpath[i + 1].id_;
1931#ifdef TTK_ENABLE_DCG_OPTIMIZE_MEMORY
1932 for(
int k = 0; k < 4; ++k) {
1934 triangulation.getCellTriangle(tetraId, k, tmp);
1935 if(tmp == triangleId) {
1936 (*vectors_)[5][tetraId] = k;
1940 for(
int k = 0; k < triangulation.getTriangleStarNumber(triangleId); ++k) {
1942 triangulation.getTriangleStar(triangleId, k, tmp);
1943 if(tmp == tetraId) {
1944 (*vectors_)[4][triangleId] = k;
1949 (*vectors_)[5][tetraId] = triangleId;
1950 (*vectors_)[4][triangleId] = tetraId;
1958template <
typename triangulationType>
1960 const std::vector<Cell> &vpath,
1961 const triangulationType &triangulation)
const {
1964 for(
size_t i = 0; i < vpath.size(); i += 2) {
1966 if((i + 1) == vpath.size()) {
1971 const SimplexId vertId = vpath[i + 1].id_;
1973#ifdef TTK_ENABLE_DCG_OPTIMIZE_MEMORY
1974 const auto nneighs = triangulation.getVertexEdgeNumber();
1975 for(
int k = 0; k < nneighs; ++k) {
1977 triangulation.getVertexEdge(vertId, k, tmp);
1979 (*vectors_)[0][vertId] = k;
1983 const auto nverts = triangulation.getEdgeStarNumber(edgeId);
1984 for(
int k = 0; k < nverts; ++k) {
1986 triangulation.getEdgeVertex(edgeId, k, tmp);
1988 (*vectors_)[1][edgeId] = k;
1994 (*vectors_)[0][vertId] = edgeId;
1995 (*vectors_)[1][edgeId] = vertId;
2002template <
typename triangulationType>
2004 const std::vector<Cell> &vpath,
2005 const triangulationType &triangulation)
const {
2007 const SimplexId numberOfCellsInPath = vpath.size();
2008 std::vector<Cell> currentVpath;
2010 if(numberOfCellsInPath > 1) {
2011 currentDim = vpath[1].dim_;
2013 this->
printErr(
"Rotating vpath not large enough to call reverse");
2016 for(
SimplexId i = 0; i < numberOfCellsInPath; i += 2) {
2017 currentVpath.emplace_back(vpath[i]);
2018 if(currentDim == vpath[i + 1].dim_) {
2019 currentVpath.emplace_back(vpath[i + 1]);
2021 if(currentDim == 0) {
2026 currentVpath.clear();
2027 currentVpath.emplace_back(vpath[i]);
2028 currentDim = vpath[i + 1].dim_;
2029 currentVpath.emplace_back(vpath[i + 1]);
2032 if(currentDim == 0) {
2041template <
typename triangulationType>
2043 const std::vector<Cell> &vpath,
2044 const triangulationType &triangulation)
const {
2048 const SimplexId numberOfCellsInPath = vpath.size();
2049 for(
SimplexId i = 0; i < numberOfCellsInPath; i += 2) {
2051 const SimplexId triangleId = vpath[i + 1].id_;
2053#ifdef TTK_ENABLE_DCG_OPTIMIZE_MEMORY
2054 for(
int k = 0; k < 3; ++k) {
2056 triangulation.getTriangleEdge(triangleId, k, tmp);
2058 (*vectors_)[3][triangleId] = k;
2062 for(
int k = 0; k < triangulation.getEdgeTriangleNumber(edgeId); ++k) {
2064 triangulation.getEdgeTriangle(edgeId, k, tmp);
2065 if(tmp == triangleId) {
2066 (*vectors_)[2][edgeId] = k;
2072 (*vectors_)[3][triangleId] = edgeId;
2073 (*vectors_)[2][edgeId] = triangleId;
2081template <
typename triangulationType>
2083 const std::vector<Cell> &vpath,
2084 const triangulationType &triangulation)
const {
2088 const SimplexId numberOfCellsInPath = vpath.size();
2089 for(
SimplexId i = 0; i < numberOfCellsInPath; i += 2) {
2090 const SimplexId triangleId = vpath[i].id_;
2091 const SimplexId edgeId = vpath[i + 1].id_;
2093#ifdef TTK_ENABLE_DCG_OPTIMIZE_MEMORY
2094 for(
int k = 0; k < 3; ++k) {
2096 triangulation.getTriangleEdge(triangleId, k, tmp);
2098 (*vectors_)[3][triangleId] = k;
2102 for(
int k = 0; k < triangulation.getEdgeTriangleNumber(edgeId); ++k) {
2104 triangulation.getEdgeTriangle(edgeId, k, tmp);
2105 if(tmp == triangleId) {
2106 (*vectors_)[2][edgeId] = k;
2112 (*vectors_)[2][edgeId] = triangleId;
2113 (*vectors_)[3][triangleId] = edgeId;
2121template <
typename dataType,
typename triangulationType>
2123 const Cell c,
const triangulationType &triangulation)
const {
2125 auto cellDim = c.
dim_;
2126 auto cellId = c.
id_;
2132 else if(cellDim == 1) {
2135 triangulation.getEdgeVertex(cellId, 0, v0);
2136 triangulation.getEdgeVertex(cellId, 1, v1);
2139 triangulation, v0, v1, edgeWeight)) {
2146 else if(cellDim == 2) {
2148 triangulation.getTriangleVertex(cellId, 0, v0);
2149 triangulation.getTriangleVertex(cellId, 1, v1);
2150 triangulation.getTriangleVertex(cellId, 2, v2);
2158 if(hasV0For1 && hasV0For2) {
2160 }
else if(!hasV0For1 && hasV1For2) {
2162 }
else if(!hasV0For2 && !hasV1For2) {
2169 else if(cellDim == 3) {
2171 triangulation.getCellVertex(cellId, 0, v0);
2172 triangulation.getCellVertex(cellId, 1, v1);
2173 triangulation.getCellVertex(cellId, 2, v2);
2174 triangulation.getCellVertex(cellId, 3, v3);
2188 if(hasV0For1 && hasV0For2 && hasV0For3) {
2190 }
else if(!hasV0For1 && hasV1For2 && hasV1For3) {
2192 }
else if(!hasV0For2 && !hasV1For2 && hasV2For3) {
2194 }
else if(!hasV0For3 && !hasV1For3 && !hasV2For3) {
2203template <
typename dataType,
typename triangulationType>
2205 const Cell c,
const triangulationType &triangulation)
const {
2207 auto cellDim = c.
dim_;
2208 auto cellId = c.
id_;
2215 else if(cellDim == 1) {
2218 triangulation.getEdgeVertex(cellId, 0, v0);
2219 triangulation.getEdgeVertex(cellId, 1, v1);
2222 triangulation, v1, v0, edgeWeight)) {
2229 else if(cellDim == 2) {
2231 triangulation.getTriangleVertex(cellId, 0, v0);
2232 triangulation.getTriangleVertex(cellId, 1, v1);
2233 triangulation.getTriangleVertex(cellId, 2, v2);
2241 if(!(hasV0For1) && !(hasV0For2)) {
2243 }
else if(hasV0For1 && !hasV1For2) {
2245 }
else if(hasV1For2 && hasV0For2) {
2252 else if(cellDim == 3) {
2254 triangulation.getCellVertex(cellId, 0, v0);
2255 triangulation.getCellVertex(cellId, 1, v1);
2256 triangulation.getCellVertex(cellId, 2, v2);
2257 triangulation.getCellVertex(cellId, 3, v3);
2271 if(!hasV0For1 && !hasV0For2 && !hasV0For3) {
2273 }
else if(hasV0For1 && !hasV1For2 && !hasV1For3) {
2275 }
else if(hasV0For2 && hasV1For2 && !hasV2For3) {
2277 }
else if(hasV0For3 && hasV1For3 && hasV2For3) {
2286template <
typename triangulationType>
2288 std::vector<std::array<float, 3>> &points,
2289 std::vector<char> &points_pairOrigins,
2290 std::vector<char> &cells_pairTypes,
2291 std::vector<SimplexId> &cellIds,
2292 std::vector<char> &cellDimensions,
2293 const triangulationType &triangulation)
const {
2298 std::vector<size_t> nGlyphsPerDim(nDims);
2300#ifdef TTK_ENABLE_OPENMP
2301#pragma omp parallel for num_threads(threadNumber_)
2303 for(
int i = 0; i < nDims - 1; ++i) {
2313 std::vector<size_t> offsets(nDims + 1);
2315 offsets[i + 1] = offsets[i] + nGlyphsPerDim[i];
2319 const auto nGlyphs = offsets.back();
2322 points.resize(2 * nGlyphs);
2323 points_pairOrigins.resize(2 * nGlyphs);
2324 cells_pairTypes.resize(nGlyphs);
2325 cellIds.resize(2 * nGlyphs);
2326 cellDimensions.resize(2 * nGlyphs);
2328#ifdef TTK_ENABLE_OPENMP
2329#pragma omp parallel for num_threads(threadNumber_)
2331 for(
int i = 0; i < nDims - 1; ++i) {
2333 size_t nProcessedGlyphs{offsets[i]};
2338 const Cell pc{i + 1, pcid};
2339 triangulation.getCellIncenter(
2340 c.id_, c.dim_, points[2 * nProcessedGlyphs].data());
2341 triangulation.getCellIncenter(
2342 pc.id_, pc.dim_, points[2 * nProcessedGlyphs + 1].data());
2343 points_pairOrigins[2 * nProcessedGlyphs] = 0;
2344 points_pairOrigins[2 * nProcessedGlyphs + 1] = 1;
2345 cells_pairTypes[nProcessedGlyphs] = i;
2346#ifdef TTK_ENABLE_MPI
2348 triangulation.getDistributedGlobalCellId(j, i, globalId);
2349 cellIds[2 * nProcessedGlyphs + 0] = globalId;
2350 triangulation.getDistributedGlobalCellId(pcid, i + 1, globalId);
2351 cellIds[2 * nProcessedGlyphs + 1] = globalId;
2353 cellIds[2 * nProcessedGlyphs + 0] = j;
2354 cellIds[2 * nProcessedGlyphs + 1] = pcid;
2356 cellDimensions[2 * nProcessedGlyphs + 0] = i;
2357 cellDimensions[2 * nProcessedGlyphs + 1] = i + 1;
#define TTK_FORCE_USE(x)
Force the compiler to use the function/method parameter.
float getPersistence(const std::vector< Cell > &vpath, const triangulationType &triangulation) const
int printErr(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
TTK discreteVectorField processing package.
int reverseAscendingPath(const std::vector< Cell > &vpath, const triangulationType &triangulation) const
bool isCellCritical(const int cellDim, const SimplexId cellId) const
int setCriticalPoints(const std::array< std::vector< SimplexId >, 4 > &criticalCellsByDim, std::vector< std::array< float, 3 > > &points, std::vector< char > &cellDimensions, std::vector< SimplexId > &cellIds, std::vector< char > &isOnBoundary, std::vector< SimplexId > &PLVertexIdentifiers, const triangulationType &triangulation) const
std::array< std::vector< SimplexId >, 6 > localVectors_
int getAscendingWall(const Cell &cell, VisitedMask &mask, const triangulationType &triangulation, std::vector< Cell > *const wall=nullptr, std::vector< SimplexId > *const saddles=nullptr) const
SimplexId getPairedCell(const Cell &cell, const triangulationType &triangulation, bool isReverse=false) const
vectorValue getVectorValueAt(SimplexId &vertex) const
int getNumberOfDimensions() const
std::array< std::vector< SimplexId >, 6 > * vectors_
int getDescendingPathRecursive(const Cell &cell, std::vector< Cell > &vpath, const triangulationType &triangulation, std::vector< char > &previousDescPaths, std::vector< char > &previousAscPaths) const
int reverseDescendingPathOnWall(const std::vector< Cell > &vpath, const triangulationType &triangulation) const
float getPersistence(const std::vector< Cell > &vpath, const triangulationType &triangulation) const
int getCriticalPoints(std::array< std::vector< SimplexId >, 4 > &criticalCellsByDim, const triangulationType &triangulation) const
SimplexId getCellLowerVertex(const Cell c, const triangulationType &triangulation) const
int getAscendingPath(const Cell &cell, std::vector< Cell > &vpath, const triangulationType &triangulation, const bool stopOnCycle) const
SimplexId getNumberOfCells(const int dimension, const triangulationType &triangulation) const
int setVectorGlyphs(std::vector< std::array< float, 3 > > &points, std::vector< char > &points_pairOrigins, std::vector< char > &cells_pairTypes, std::vector< SimplexId > &cellsIds, std::vector< char > &cellsDimensions, const triangulationType &triangulation) const
int buildField(const triangulationType &triangulation)
SimplexId numberOfVertices_
bool compare(const triangulationType &triangulation, SimplexId vertexA, SimplexId vertexB, float &weightValue) const
void getAscendingPathThroughWall(const Cell &saddle1, const Cell &saddle2, const std::vector< bool > &isVisited, std::vector< Cell > *const vpath, const triangulationType &triangulation) const
bool isBoundary(const Cell &cell, const triangulationType &triangulation) const
int reverseAlternatingPath(const std::vector< Cell > &vpath, const triangulationType &triangulation) const
int getDescendingPath(const Cell &cell, std::vector< Cell > &vpath, const triangulationType &triangulation, const bool stopOnCycle) const
int getDescendingWall(const Cell &cell, VisitedMask &mask, const triangulationType &triangulation, std::vector< Cell > *const wall=nullptr, std::vector< SimplexId > *const saddles=nullptr) const
SimplexId getCellGreaterVertex(const Cell c, const triangulationType &triangulation) const
int reverseDescendingPath(const std::vector< Cell > &vpath, const triangulationType &triangulation) const
int reverseAscendingPathOnWall(const std::vector< Cell > &vpath, const triangulationType &triangulation) const
int getAscendingPathRecursive(const Cell &cell, std::vector< Cell > &vpath, const triangulationType &triangulation, std::vector< char > &previousDescPaths, std::vector< char > &previousAscPaths) const
bool getDescendingPathThroughWall(const Cell &saddle2, const Cell &saddle1, const std::vector< bool > &isVisited, std::vector< Cell > *const vpath, const triangulationType &triangulation, const bool stopIfMultiConnected=false, const bool enableCycleDetector=false) const
T dotProduct(const T *vA0, const T *vA1, const T *vB0, const T *vB1)
SurfaceGeometrySmoother::Point vectorValue
int SimplexId
Identifier type for simplices of any dimension.
COMMON_EXPORTS int MPIrank_
T end(std::pair< T, T > &p)
Auto-cleaning re-usable graph propagations data structure.
std::vector< bool > & isVisited_
std::vector< SimplexId > & visitedIds_
Extended Cell structure for processOutwardStars.
const std::array< float, 3 > lowVertWeights_
const std::array< uint8_t, 3 > faces_
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/| (_) |"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)