9#include <unordered_map>
21template <
typename ScalarType,
typename triangulationType>
23 const idVertex seed, Propagation *localProp, idSuperArc currentArc) {
26 PRINT(seed <<
" :: " << localProp->getNbArcs());
27 if(!localProp->getNbArcs()) {
28 PRINT(seed <<
" Stop direct");
29#ifdef TTK_ENABLE_FTR_TASK_STATS
35#pragma omp atomic capture seq_cst
40#pragma omp critical(stats)
41 { curTime = sweepStart_.getElapsedTime(); }
42 propTimes_[curProp - 1] = curTime;
49 bool isJoinLast =
false;
50 bool isJoin =
false, isSplit =
false;
57 while(!isJoin && !isSplit && !localProp->empty()) {
58 localProp->nextVertex();
59 const idVertex curVert = localProp->getCurVertex();
60 idSuperArc mergeIn = nullSuperArc;
62 if(localProp->getNbArcs() == 0) {
63#ifdef TTK_ENABLE_FTR_TASK_STATS
69#pragma omp atomic capture seq_cst
74#pragma omp critical(stats)
75 { curTime = sweepStart_.getElapsedTime(); }
76 propTimes_[curProp - 1] = curTime;
82 PRINT(
"<" << curVert <<
" " << localProp->goUp() <<
" a "
83 << localProp->getNbArcs());
85#ifdef TTK_ENABLE_FTR_VERT_STATS
86 graph_.incTouch(curVert);
87 graph_.setNbArcActive(curVert, localProp->getNbArcs());
90 visitStar(localProp, star);
92 if(propagations_.hasVisitedOpposite(
93 curVert, localProp) ) {
94 bool ignoreVert =
false;
95 for(
auto edge : star.lower) {
96 const idSuperArc tmpLowArc = dynGraph(localProp).getSubtreeArc(edge);
97 if(tmpLowArc != nullSuperArc && !graph_.getArc(tmpLowArc).isVisible()
98 && graph_.getArc(tmpLowArc).getPropagation() == localProp) {
99 PRINT(
"-" << curVert <<
" " << graph_.printArc(tmpLowArc));
100#ifdef TTK_ENABLE_FTR_VERT_STATS
105 }
else if(tmpLowArc != nullSuperArc) {
106 PRINT(
"!" << graph_.printArc(tmpLowArc));
113#ifndef TTK_DISABLE_FTR_LAZY
114 if(valences_.lower[curVert] < 2 && valences_.upper[curVert] < 2) {
117 if(star.lower.size()) {
119 currentArc = dynGraph(localProp).getSubtreeArc(star.lower[0]);
120 if(currentArc == nullSuperArc) {
121 PRINT(
"n-" << curVert);
124 if(valences_.upper[curVert] && valences_.lower[curVert]) {
126 graph_.getArc(currentArc).visit(curVert);
130 mergeIn = visit(localProp, currentArc);
132 lazyUpdatePreimage(localProp, currentArc);
135 for(
const idEdge dgNode : star.upper) {
136 dynGraph(localProp).setCorArc(dgNode, currentArc);
140 for(
const idEdge e : star.lower) {
141 const auto node{dynGraph(localProp).getNode(e)};
143 = node !=
nullptr ? node->findRootArc() : nullSuperArc;
144 if(a != nullSuperArc && graph_.getArc(a).isVisible()
145 && graph_.getArc(a).getPropagation()->getId()
146 == localProp->getId()) {
147 lazyApply(localProp, a);
153 comp.lower = lowerComps(star.lower, localProp);
155 if(comp.lower.size() > 1) {
157 isJoinLast = checkLast(localProp, star.lower);
160 if(comp.lower.size()) {
161 currentArc = (*comp.lower.begin())->getCorArc();
162 if(currentArc == nullSuperArc) {
163 PRINT(
"n--" << curVert);
167 mergeIn = visit(localProp, currentArc);
169 updatePreimage(localProp, currentArc);
170 comp.upper = upperComps(star.upper, localProp);
171 if(comp.upper.size() > 1) {
175 if(!isJoin && !isSplit && comp.upper.size()) {
177 graph_.getArc(currentArc).visit(curVert);
182 if(mergeIn != nullSuperArc && graph_.getArc(currentArc).isVisible()) {
183 graph_.getArc(currentArc).merge(mergeIn);
184 localProp->lessArc();
185 PRINT(
">" << graph_.printArc(currentArc) <<
" "
186 << graph_.printArc(mergeIn));
193 if(!star.upper.size()) {
195 const idNode leafNode = graph_.makeNode(curVert);
196 graph_.closeArc(currentArc, leafNode);
197 PRINT(
"^" << graph_.printArc(currentArc));
198 if(graph_.getArc(currentArc).isVisible()) {
200 localProp->lessArc();
202 if(localProp->getNbArcs() == 0) {
204 PRINT(curVert <<
" stop");
205#ifdef TTK_ENABLE_FTR_TASK_STATS
211#pragma omp atomic capture seq_cst
216#pragma omp critical(stats)
217 { curTime = sweepStart_.getElapsedTime(); }
218 propTimes_[curProp - 1] = curTime;
226 localGrowth(localProp, star.upper);
231 const idVertex upVert = localProp->getCurVertex();
233 if(localProp->getNbArcs() == 0 || localProp->empty()) {
234 PRINT(upVert <<
" stop " << localProp->getNbArcs());
235#ifdef TTK_ENABLE_FTR_TASK_STATS
241#pragma omp atomic capture seq_cst
246#pragma omp critical(stats)
247 { curTime = sweepStart_.getElapsedTime(); }
248 propTimes_[curProp - 1] = curTime;
254 PRINT(upVert <<
" active " << localProp->getNbArcs());
259 idSuperArc joinParentArc{};
260 bool hideFromHere =
false;
262#ifdef TTK_ENABLE_OPENMP4
266 bool const alreadyNode = graph_.isNode(upVert);
267 hideFromHere = alreadyNode;
269 PRINT(upVert <<
" join " << isJoinLast <<
" h " << hideFromHere);
271 graph_.makeNode(upVert);
275 PRINT(upVert <<
" split " << hideFromHere);
276 graph_.makeNode(upVert);
287 visitStar(localProp, star);
288 comp.lower = lowerComps(star.lower, localProp);
290 saddleNode = graph_.getNodeId(upVert);
291 idSuperArc
const visibleMerged
292 = mergeAtSaddle(saddleNode, localProp, comp.lower);
293 localProp->lessArc(visibleMerged - 1);
295 localGrowth(localProp, star.upper);
297 joinParentArc = graph_.openArc(saddleNode, localProp);
298 visit(localProp, joinParentArc);
299 updatePreimage(localProp, joinParentArc);
300 comp.upper = upperComps(star.upper, localProp);
304 if(graph_.getArc(joinParentArc).hide()) {
305 localProp->lessArc();
310 if(comp.upper.size() > 1) {
314 if(graph_.getArc(joinParentArc).hide()) {
315 localProp->lessArc();
319 PRINT(
"+" << graph_.printArc(joinParentArc));
322 saddleNode = graph_.getNodeId(upVert);
323 graph_.closeArc(currentArc, saddleNode);
324 if(localProp->getNbArcs() == 0) {
326 PRINT(upVert <<
" stop");
327#ifdef TTK_ENABLE_FTR_TASK_STATS
333#pragma omp atomic capture seq_cst
338#pragma omp critical(stats)
339 { curTime = sweepStart_.getElapsedTime(); }
340 propTimes_[curProp - 1] = curTime;
345 if(graph_.getArc(currentArc).isVisible()) {
347 localProp->lessArc();
349 PRINT(
"|" << graph_.printArc(currentArc));
353 splitAtSaddle(localProp, comp.upper, hideFromHere);
355 localProp->moreArc(comp.upper.size());
360 if(isSplit && (!isJoin || isJoinLast)) {
361#ifdef TTK_ENABLE_OPENMP4
362#pragma omp task OPTIONAL_PRIORITY(PriorityLevel::Low)
364 growthFromSeed(upVert, localProp);
366 }
else if(isJoinLast) {
368#ifdef TTK_ENABLE_OPENMP4
369#pragma omp task OPTIONAL_PRIORITY(PriorityLevel::Average)
371 growthFromSeed(upVert, localProp, joinParentArc);
373#ifdef TTK_ENABLE_FTR_TASK_STATS
379#pragma omp atomic capture seq_cst
384#pragma omp critical(stats)
385 { curTime = sweepStart_.getElapsedTime(); }
386 propTimes_[curProp - 1] = curTime;
391template <
typename ScalarType,
typename triangulationType>
393 const idVertex
begin,
const idVertex stop) {
397 const bool fromMin =
begin < stop;
398 Propagation *localProp
399 = newPropagation(scalars_.getSortedVert(
begin), fromMin);
400 const idVertex incr = fromMin ? 1 : -1;
401 for(idVertex idv =
begin; idv < stop; idv = idv + incr) {
402 const idVertex curVert = scalars_.getSortedVert(idv);
403 localProp->setCurvert(curVert);
405 idSuperArc currentArc = nullSuperArc;
406 visitStar(localProp, star);
408 if(valences_.lower[curVert] == 0) {
409 const idNode minNode = graph_.makeNode(curVert);
410 currentArc = graph_.openArc(minNode, localProp);
413#ifndef TTK_DISABLE_FTR_LAZY
414 if(valences_.lower[curVert] < 2 && valences_.upper[curVert] < 2) {
417 if(!star.lower.empty()) {
419 currentArc = dynGraph(localProp).getSubtreeArc(star.lower[0]);
420 if(valences_.upper[curVert] && valences_.lower[curVert]) {
422 graph_.getArc(currentArc).visit(curVert);
425 if(star.upper.size()) {
426 for(
const idEdge dgNode : star.upper) {
427 dynGraph(localProp).setCorArc(dgNode, currentArc);
430 const idNode maxNode = graph_.makeNode(curVert);
431 graph_.closeArc(currentArc, maxNode);
434 visit(localProp, currentArc);
436 lazyUpdatePreimage(localProp, currentArc);
440 for(
const idEdge e : star.lower) {
441 const idSuperArc a = dynGraph(localProp).getNode(e)->findRootArc();
442 if(!lazy_.isEmpty(a)) {
449 lazyApply(localProp, a);
456 comp.lower = lowerComps(star.lower, localProp);
457 if(comp.lower.size() == 1) {
458 currentArc = (*comp.lower.begin())->getCorArc();
459 }
else if(comp.lower.size() > 1) {
460 const idNode sadNode = graph_.makeNode(curVert);
461 currentArc = graph_.openArc(sadNode, localProp);
462 mergeAtSaddle(sadNode, comp.lower);
466 graph_.visit(curVert, currentArc);
467 propagations_.visit(curVert, localProp);
468 updatePreimage(localProp, currentArc);
470 comp.upper = upperComps(star.upper, localProp);
471 if(!comp.upper.size()) {
472 const idNode maxNode = graph_.makeNode(curVert);
473 graph_.closeArc(currentArc, maxNode);
474 }
else if(comp.upper.size() < 2) {
477 graph_.getArc(currentArc).visit(curVert);
481 graph_.getArc(currentArc).hide();
483 const idNode splitNode = graph_.makeNode(curVert);
484 graph_.closeArc(currentArc, splitNode);
486 splitAtSaddle(localProp, comp.upper);
492template <
typename ScalarType,
typename triangulationType>
494 const Propagation *
const localProp, Star &star)
const {
499 const idEdge nbAdjEdges
500 = mesh_.getVertexEdgeNumber(localProp->getCurVertex());
501 star.lower.reserve(nbAdjEdges);
502 star.upper.reserve(nbAdjEdges);
504 for(idEdge e = 0; e < nbAdjEdges; ++e) {
506 mesh_.getVertexEdge(localProp->getCurVertex(), e, edgeId);
507 idVertex edgeLowerVert, edgeUpperVert;
508 std::tie(edgeLowerVert, edgeUpperVert)
509 = mesh_.getOrderedEdge(edgeId, localProp->goUp());
510 if(edgeLowerVert == localProp->getCurVertex()) {
511 star.upper.emplace_back(edgeId);
513 star.lower.emplace_back(edgeId);
518template <
typename ScalarType,
typename triangulationType>
519std::set<ttk::ftr::DynGraphNode<ttk::ftr::idVertex> *>
521 const std::vector<idEdge> &finishingEdges,
522 const Propagation *
const localProp) {
523 return dynGraph(localProp).findRoot(finishingEdges);
526template <
typename ScalarType,
typename triangulationType>
527std::set<ttk::ftr::DynGraphNode<ttk::ftr::idVertex> *>
529 const std::vector<idEdge> &startingEdges,
530 const Propagation *
const localProp) {
531 return dynGraph(localProp).findRoot(startingEdges);
534template <
typename ScalarType,
typename triangulationType>
536 const std::vector<DynGraphNode<idVertex> *> &compVect) {
537 for(
const auto *dgNode : compVect) {
538 const idSuperArc arc = dgNode->getCorArc();
539 if(arc != nullSuperArc && !graph_.getArc(arc).isVisible()) {
546template <
typename ScalarType,
typename triangulationType>
547std::pair<ttk::ftr::valence, ttk::ftr::valence>
549 const idVertex curVert,
550 LocalForests &localForests,
551 const VertCompFN &comp) {
553 std::unordered_map<idEdge, std::size_t> mapNeighDown, mapNeighUp;
554 std::size_t nextId = 0;
556 localForests.up.reset();
557 localForests.down.reset();
558 const idVertex oldUpCC = localForests.up.getNbCC();
559 const idVertex oldDownCC = localForests.down.getNbCC();
560 const idCell nbTri = mesh_.getVertexTriangleNumber(curVert);
561 for(idCell t = 0; t < nbTri; ++t) {
563 mesh_.getVertexTriangle(curVert, t, curTri);
565 std::size_t downSide[2], upSide[2];
566 unsigned char curDownSide = 0, curUpSide = 0;
567 for(idVertex v = 0; v < 3; ++v) {
569 mesh_.getTriangleEdge(curTri, v, triEdge);
571 mesh_.getEdgeVertex(triEdge, 0, v0);
572 mesh_.getEdgeVertex(triEdge, 1, v1);
576 if(comp(curVert, v1)) {
577 if(mapNeighUp.count(triEdge)) {
578 upSide[curUpSide++] = mapNeighUp[triEdge];
580 upSide[curUpSide++] = nextId;
581 mapNeighUp[triEdge] = nextId++;
584 if(mapNeighDown.count(triEdge)) {
585 downSide[curDownSide++] = mapNeighDown[triEdge];
587 downSide[curDownSide++] = nextId;
588 mapNeighDown[triEdge] = nextId++;
591 }
else if(v1 == curVert) {
592 if(comp(curVert, v0)) {
593 if(mapNeighUp.count(triEdge)) {
594 upSide[curUpSide++] = mapNeighUp[triEdge];
596 upSide[curUpSide++] = nextId;
597 mapNeighUp[triEdge] = nextId++;
600 if(mapNeighDown.count(triEdge)) {
601 downSide[curDownSide++] = mapNeighDown[triEdge];
603 downSide[curDownSide++] = nextId;
604 mapNeighDown[triEdge] = nextId++;
612 if(curDownSide == 2) {
613 localForests.down.insertEdge(downSide[0], downSide[1], 0, nullSuperArc);
614 }
else if(curUpSide == 2) {
615 localForests.up.insertEdge(upSide[0], upSide[1], 0, nullSuperArc);
620 = mapNeighDown.size() - (oldDownCC - localForests.down.getNbCC());
621 const valence up = mapNeighUp.size() - (oldUpCC - localForests.up.getNbCC());
625template <
typename ScalarType,
typename triangulationType>
627 const Propagation *
const localProp,
const idSuperArc curArc) {
628 const idCell nbAdjTriangles
629 = mesh_.getVertexTriangleNumber(localProp->getCurVertex());
631 orderedTriangle oTriangle;
635 for(idCell t = 0; t < nbAdjTriangles; ++t) {
637 idCell curTriangleid;
638 mesh_.getVertexTriangle(localProp->getCurVertex(), t, curTriangleid);
640 mesh_.getOrderedTriangle(curTriangleid, localProp->goUp(), oTriangle);
641 vertPosInTriangle
const curVertPos
642 = getVertPosInTriangle(oTriangle, localProp);
648 case vertPosInTriangle::Start:
649 updatePreimageStartCell(oTriangle, localProp, curArc);
651 case vertPosInTriangle::Middle:
652 updatePreimageMiddleCell(oTriangle, localProp, curArc);
654 case vertPosInTriangle::End:
655 updatePreimageEndCell(oTriangle, localProp, curArc);
658 std::cout <<
"[FTR]: update preimage error, unknown vertPos type"
665template <
typename ScalarType,
typename triangulationType>
667 const orderedTriangle &oTriangle,
668 const Propagation *
const localProp,
669 const idSuperArc curArc) {
671 = mesh_.getOrderedEdge(std::get<0>(oTriangle), localProp->goUp());
673 = mesh_.getOrderedEdge(std::get<1>(oTriangle), localProp->goUp());
674 const idVertex w = getWeight(e0, e1, localProp);
677 dynGraph(localProp).insertEdge(
678 std::get<1>(oTriangle), std::get<0>(oTriangle), w, curArc);
681template <
typename ScalarType,
typename triangulationType>
684 const Propagation *
const localProp,
685 const idSuperArc curArc) {
689 dynGraph(localProp).removeEdge(
690 std::get<0>(oTriangle), std::get<1>(oTriangle));
693 dynGraph(localProp).setCorArc(std::get<0>(oTriangle), curArc);
697 = mesh_.getOrderedEdge(std::get<1>(oTriangle), localProp->goUp());
699 = mesh_.getOrderedEdge(std::get<2>(oTriangle), localProp->goUp());
700 const idVertex w = getWeight(e1, e2, localProp);
703 dynGraph(localProp).insertEdge(
704 std::get<1>(oTriangle), std::get<2>(oTriangle), w, curArc);
707template <
typename ScalarType,
typename triangulationType>
709 const orderedTriangle &oTriangle,
710 const Propagation *
const localProp,
711 const idSuperArc curArc) {
712 dynGraph(localProp).removeEdge(
713 std::get<1>(oTriangle), std::get<2>(oTriangle));
714 dynGraph(localProp).setCorArc(std::get<1>(oTriangle), curArc);
718template <
typename ScalarType,
typename triangulationType>
721 const idEdge neigEdge,
722 const idSuperArc curArc,
723 const Propagation *
const localProp) {
726 mesh_.getEdgeVertex(neigEdge, 0, v0);
727 mesh_.getEdgeVertex(neigEdge, 1, v1);
729 const idVertex other = (v0 == seed) ? v1 : v0;
731 if(localProp->compare(seed, other)) {
732 dynGraph(localProp).setSubtreeArc(neigEdge, curArc);
736#ifndef TTK_DISABLE_FTR_LAZY
737template <
typename ScalarType,
typename triangulationType>
739 Propagation *
const localProp,
const idSuperArc curArc) {
740 const idCell nbAdjTriangles
741 = mesh_.getVertexTriangleNumber(localProp->getCurVertex());
743 orderedTriangle oTriangle;
745 for(idCell t = 0; t < nbAdjTriangles; ++t) {
747 idCell curTriangleid;
748 mesh_.getVertexTriangle(localProp->getCurVertex(), t, curTriangleid);
750 mesh_.getOrderedTriangle(curTriangleid, localProp->goUp(), oTriangle);
751 vertPosInTriangle
const curVertPos
752 = getVertPosInTriangle(oTriangle, localProp);
758 case vertPosInTriangle::Start:
759 updateLazyStart(oTriangle, localProp, curArc);
761 case vertPosInTriangle::Middle:
762 updateLazyMiddle(oTriangle, localProp, curArc);
764 case vertPosInTriangle::End:
765 updateLazyEnd(oTriangle, localProp, curArc);
768 std::cout <<
"[FTR]: lazy update preimage error, unknown vertPos type"
775template <
typename ScalarType,
typename triangulationType>
777 const orderedTriangle &oTriangle,
779 const idSuperArc curArc) {
780 lazy_.addEmplace(std::get<0>(oTriangle), std::get<1>(oTriangle), curArc);
783template <
typename ScalarType,
typename triangulationType>
785 const orderedTriangle &oTriangle,
786 Propagation *
const localProp,
787 const idSuperArc curArc) {
788 lazy_.delEmplace(std::get<0>(oTriangle), std::get<1>(oTriangle), curArc);
789 dynGraph(localProp).removeEdge(
790 std::get<0>(oTriangle), std::get<1>(oTriangle));
791 dynGraph(localProp).setCorArc(std::get<0>(oTriangle), curArc);
792 dynGraph(localProp).setCorArc(std::get<1>(oTriangle), curArc);
793 lazy_.addEmplace(std::get<1>(oTriangle), std::get<2>(oTriangle), curArc);
796template <
typename ScalarType,
typename triangulationType>
798 const orderedTriangle &oTriangle,
799 Propagation *
const localProp,
800 const idSuperArc curArc) {
801 lazy_.delEmplace(std::get<1>(oTriangle), std::get<2>(oTriangle), curArc);
802 dynGraph(localProp).removeEdge(
803 std::get<1>(oTriangle), std::get<2>(oTriangle));
804 dynGraph(localProp).setCorArc(std::get<1>(oTriangle), curArc);
805 dynGraph(localProp).setCorArc(std::get<2>(oTriangle), curArc);
808template <
typename ScalarType,
typename triangulationType>
810 const Propagation *
const localProp,
812 const idSuperArc arc) {
814 = mesh_.getOrderedEdge(std::get<0>(edge), localProp->goUp());
816 = mesh_.getOrderedEdge(std::get<1>(edge), localProp->goUp());
817 const idVertex w = getWeight(e0, e1, localProp);
818 dynGraph(localProp).insertEdge(std::get<1>(edge), std::get<0>(edge), w, arc);
821template <
typename ScalarType,
typename triangulationType>
823 const Propagation *
const localProp,
826 dynGraph(localProp).removeEdge(std::get<0>(edge), std::get<1>(edge));
829template <
typename ScalarType,
typename triangulationType>
831 Propagation *
const localProp,
const idSuperArc a) {
832 auto add = lazy_.addGetNext(a);
833 while(add != nullLink) {
834 updateLazyAdd(localProp, add, a);
835 add = lazy_.addGetNext(a);
841template <
typename ScalarType,
typename triangulationType>
844 const idSuperArc curArc,
845 const Propagation *
const localProp) {
846 const idVertex nbEdgesNeigh = mesh_.getVertexEdgeNumber(seed);
847 for(idVertex nid = 0; nid < nbEdgesNeigh; ++nid) {
849 mesh_.getVertexEdge(seed, nid, edgeId);
851 updateDynGraphCurArc(seed, edgeId, curArc, localProp);
855template <
typename ScalarType,
typename triangulationType>
857 Propagation *
const localProp,
const std::vector<idEdge> &upperEdges) {
858 const idVertex curVert = localProp->getCurVertex();
859 for(
const idEdge e : upperEdges) {
861 mesh_.getEdgeVertex(e, 0, v0);
862 mesh_.getEdgeVertex(e, 1, v1);
863 const idVertex other = (v0 == curVert) ? v1 : v0;
864 if(localProp->compare(curVert, other)) {
865 if(!propagations_.willVisit(other, localProp)) {
866 localProp->addNewVertex(other);
867 propagations_.toVisit(other, localProp);
873template <
typename ScalarType,
typename triangulationType>
875 Propagation *
const localProp,
const std::vector<idEdge> &starVect) {
876 const idVertex curSaddle = localProp->getCurVertex();
877 AtomicUF *curId = localProp->getId();
884 for(idEdge
const edgeId : starVect) {
885 const idSuperArc edgeArc = dynGraph(localProp).getSubtreeArc(edgeId);
886 if(edgeArc == nullSuperArc) {
889 AtomicUF *tmpId = graph_.getArc(edgeArc).getPropagation()->getId();
891 graph_.getArc(edgeArc).setEnd(curSaddle);
897#pragma GCC diagnostic push
898#pragma GCC diagnostic ignored "-Wunused-value"
902 if(localProp->goUp()) {
904 valence *
const vd = &graph_.valDown_[curSaddle];
905#ifdef TTK_ENABLE_OPENMP4
906#pragma omp atomic capture
914 valence *
const vu = &graph_.valUp_[curSaddle];
915#ifdef TTK_ENABLE_OPENMP4
916#pragma omp atomic capture
926 idVertex
const totalVal = starVect.size();
928 if(localProp->goUp()) {
929 valence *
const vd = &graph_.valDown_[curSaddle];
930#ifdef TTK_ENABLE_OPENMP4
931#pragma omp atomic capture
935 *vd += (totalVal + 1);
939 valence *
const vu = &graph_.valUp_[curSaddle];
940#ifdef TTK_ENABLE_OPENMP4
941#pragma omp atomic capture
945 *vu += (totalVal + 1);
948 oldVal = decr + newVal + (totalVal + 1);
952#pragma GCC diagnostic pop
955 return oldVal == decr;
958template <
typename ScalarType,
typename triangulationType>
961 const idNode saddleId,
962 Propagation *localProp,
963 const std::set<DynGraphNode<idVertex> *> &compVect) {
965#ifndef TTK_ENABLE_KAMIKAZE
966 if(compVect.size() < 2) {
967 std::cerr <<
"[FTR]: merge at saddle with only one lower CC" << std::endl;
971 idSuperArc visibleClosed = 0;
972 for(
auto *dgNode : compVect) {
974 const idSuperArc endingArc = dgNode->getCorArc();
975 graph_.closeArc(endingArc, saddleId);
976 PRINT(
"/" << graph_.printArc(endingArc));
977 if(graph_.getArc(endingArc).isVisible()) {
980 Propagation *arcProp = graph_.getArc(endingArc).getPropagation();
981 localProp->merge(*arcProp);
983 return visibleClosed;
986template <
typename ScalarType,
typename triangulationType>
989 const idNode saddleId,
const std::set<DynGraphNode<idVertex> *> &compVect) {
992#ifndef TTK_ENABLE_KAMIKAZE
993 if(compVect.size() < 2) {
994 std::cerr <<
"[FTR]: merge at saddle with only one lower CC" << std::endl;
998 idSuperArc visibleClosed = 0;
999 for(
auto *dgNode : compVect) {
1000 const idSuperArc endingArc = dgNode->getCorArc();
1001 graph_.closeArc(endingArc, saddleId);
1002 PRINT(
"/" << graph_.printArc(endingArc));
1003 if(graph_.getArc(endingArc).isVisible()) {
1007 return visibleClosed;
1010template <
typename ScalarType,
typename triangulationType>
1012 Propagation *
const localProp,
1013 const std::set<DynGraphNode<idVertex> *> &compVect,
1014 const bool hidden) {
1015 const idVertex curVert = localProp->getCurVertex();
1016 const idNode curNode = graph_.getNodeId(curVert);
1018 for(
auto *dgNode : compVect) {
1019 const idSuperArc newArc = graph_.openArc(curNode, localProp);
1020 dgNode->setRootArc(newArc);
1021 visit(localProp, newArc);
1024 graph_.getArc(newArc).hide();
1026 PRINT(
"v" << graph_.printArc(newArc));
1030template <
typename ScalarType,
typename triangulationType>
1032 Propagation *
const localProp,
const idSuperArc curArc) {
1033 const idVertex curVert = localProp->getCurVertex();
1038 propagations_.visit(curVert, localProp);
1039 opposite = propagations_.visitOpposite(curVert, localProp);
1041#ifdef TTK_ENABLE_OPENMP4
1042#pragma omp atomic read seq_cst
1044 done = opposite.done;
1046 graph_.visit(curVert, curArc);
1047 retArc = nullSuperArc;
1049 retArc = graph_.getArcId(curVert);
1057template <
typename ScalarType,
typename triangulationType>
1060 const idVertex leaf,
const bool fromMin) {
1063 comp = [&](idVertex a, idVertex b) {
return scalars_.isHigher(a, b); };
1065 comp = [&](idVertex a, idVertex b) {
return scalars_.isLower(a, b); };
1066 return propagations_.newPropagation(leaf, comp, fromMin);
1069template <
typename ScalarType,
typename triangulationType>
1071 const orderedEdge &e0,
1072 const orderedEdge &e1,
1073 const Propagation *
const localProp) {
1074 const idVertex end0 = std::get<1>(e0);
1075 const idVertex end1 = std::get<1>(e1);
1077 if(localProp->compare(end0, end1)) {
1078 if(localProp->goDown()) {
1079 return -scalars_.getMirror(end0);
1081 return scalars_.getMirror(end0);
1084 if(localProp->goDown()) {
1085 return -scalars_.getMirror(end1);
1087 return scalars_.getMirror(end1);
1090template <
typename ScalarType,
typename triangulationType>
1093 const orderedTriangle &oTriangle,
1094 const Propagation *
const localProp)
const {
1095 orderedEdge firstEdge
1096 = mesh_.getOrderedEdge(std::get<0>(oTriangle), localProp->goUp());
1097 if(std::get<0>(firstEdge) == localProp->getCurVertex()) {
1098 return vertPosInTriangle::Start;
1099 }
else if(std::get<1>(firstEdge) == localProp->getCurVertex()) {
1100 return vertPosInTriangle::Middle;
1102 return vertPosInTriangle::End;
1106template <
typename ScalarType,
typename triangulationType>
1109 const orderedTriangle &oTriangle,
1110 const Propagation *
const localProp)
const {
1111 const orderedEdge &higherEdge
1112 = mesh_.getOrderedEdge(std::get<1>(oTriangle), localProp->goUp());
1113 return std::get<1>(higherEdge);
1116template <
typename ScalarType,
typename triangulationType>
1119 const orderedTriangle oTri,
const idVertex v0,
const idVertex v1) {
1120 idVertex edge0Vert, edge1Vert;
1122 mesh_.getEdgeVertex(std::get<0>(oTri), 0, edge0Vert);
1123 mesh_.getEdgeVertex(std::get<0>(oTri), 1, edge1Vert);
1124 if((edge0Vert == v0 && edge1Vert == v1)
1125 || (edge0Vert == v1 && edge1Vert == v0)) {
1126 return std::get<0>(oTri);
1129 mesh_.getEdgeVertex(std::get<1>(oTri), 0, edge0Vert);
1130 mesh_.getEdgeVertex(std::get<1>(oTri), 1, edge1Vert);
1131 if((edge0Vert == v0 && edge1Vert == v1)
1132 || (edge0Vert == v1 && edge1Vert == v0)) {
1133 return std::get<1>(oTri);
1136#ifndef TTK_ENABLE_KAMIKAZE
1137 mesh_.getEdgeVertex(std::get<2>(oTri), 0, edge0Vert);
1138 mesh_.getEdgeVertex(std::get<2>(oTri), 1, edge1Vert);
1139 if((edge0Vert == v0 && edge1Vert == v1)
1140 || (edge0Vert == v1 && edge1Vert == v0)) {
1141 return std::get<2>(oTri);
1144 std::cout <<
"[FTR]: edge not found in triangle " << v0 <<
" " << v1
1148 return std::get<2>(oTri);
#define TTK_FORCE_USE(x)
Force the compiler to use the function/method parameter.
#define ttkNotUsed(x)
Mark function/method parameters that are not used in the function body at all.
TTK processing package that efficiently computes the contour tree of scalar data and more (data segme...
TTK FTRGraph processing package.
TTK fTRGraph propagation management with Fibonacci heaps.
vertPosInTriangle
position of a vertex in a triangle
long unsigned int idSuperArc
SuperArc index in vect_superArcs_.
SimplexId idVertex
Vertex index in scalars_.
SimplexId idEdge
Edge index in vect_edgeList_.
T begin(std::pair< T, T > &p)