9#include <unordered_map>
21template <
typename ScalarType,
typename triangulationType>
22void ttk::ftr::FTRGraph<ScalarType, triangulationType>::growthFromSeed(
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>
392void ttk::ftr::FTRGraph<ScalarType, triangulationType>::growthSequential(
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>
493void ttk::ftr::FTRGraph<ScalarType, triangulationType>::visitStar(
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> *>
520 ttk::ftr::FTRGraph<ScalarType, triangulationType>::lowerComps(
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> *>
528 ttk::ftr::FTRGraph<ScalarType, triangulationType>::upperComps(
529 const std::vector<idEdge> &startingEdges,
530 const Propagation *
const localProp) {
531 return dynGraph(localProp).findRoot(startingEdges);
534template <
typename ScalarType,
typename triangulationType>
535bool ttk::ftr::FTRGraph<ScalarType, triangulationType>::checkStop(
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>
548 ttk::ftr::FTRGraph<ScalarType, triangulationType>::getLinkNbCC(
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>
626void ttk::ftr::FTRGraph<ScalarType, triangulationType>::updatePreimage(
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>
666void ttk::ftr::FTRGraph<ScalarType, triangulationType>::updatePreimageStartCell(
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>
708void ttk::ftr::FTRGraph<ScalarType, triangulationType>::updatePreimageEndCell(
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>
719void ttk::ftr::FTRGraph<ScalarType, triangulationType>::updateDynGraphCurArc(
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>
738void ttk::ftr::FTRGraph<ScalarType, triangulationType>::lazyUpdatePreimage(
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>
776void ttk::ftr::FTRGraph<ScalarType, triangulationType>::updateLazyStart(
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>
784void ttk::ftr::FTRGraph<ScalarType, triangulationType>::updateLazyMiddle(
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>
797void ttk::ftr::FTRGraph<ScalarType, triangulationType>::updateLazyEnd(
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>
809void ttk::ftr::FTRGraph<ScalarType, triangulationType>::updateLazyAdd(
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>
822void ttk::ftr::FTRGraph<ScalarType, triangulationType>::updateLazyDel(
823 const Propagation *
const localProp,
826 dynGraph(localProp).removeEdge(std::get<0>(edge), std::get<1>(edge));
829template <
typename ScalarType,
typename triangulationType>
830void ttk::ftr::FTRGraph<ScalarType, triangulationType>::lazyApply(
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>
842void ttk::ftr::FTRGraph<ScalarType, triangulationType>::updateDynGraphCurArc(
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>
856void ttk::ftr::FTRGraph<ScalarType, triangulationType>::localGrowth(
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>
874bool ttk::ftr::FTRGraph<ScalarType, triangulationType>::checkLast(
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>
960 ttk::ftr::FTRGraph<ScalarType, triangulationType>::mergeAtSaddle(
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>
988 ttk::ftr::FTRGraph<ScalarType, triangulationType>::mergeAtSaddle(
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>
1011void ttk::ftr::FTRGraph<ScalarType, triangulationType>::splitAtSaddle(
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>
1059 ttk::ftr::FTRGraph<ScalarType, triangulationType>::newPropagation(
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>
1092 ttk::ftr::FTRGraph<ScalarType, triangulationType>::getVertPosInTriangle(
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>
1108 ttk::ftr::FTRGraph<ScalarType, triangulationType>::getEndVertexInTriangle(
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>
1118 ttk::ftr::FTRGraph<ScalarType, triangulationType>::getEdgeFromOTri(
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 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)