48 template <
typename scalarType>
50 const scalarType *scalars,
51 scalarType *
const fakeScalars,
53 int *
const outputMonotonyOffsets);
55 template <
typename scalarType>
57 scalarType *fakeScalars,
59 int *outputMonotonyOffsets);
61 template <
typename scalarType,
typename offsetType>
64 std::vector<std::vector<std::pair<polarity, polarity>>>
66 std::vector<polarity> &toProcess,
67 const scalarType *fakeScalars,
68 const offsetType *
const offsets,
69 const int *
const monotonyOffsets)
const;
71 template <
typename scalarType,
typename offsetType>
73 std::vector<polarity> &toPropagateMin,
74 std::vector<polarity> &toPropagateMax,
75 std::vector<std::vector<SimplexId>> &vertexRepresentativesMin,
76 std::vector<std::vector<SimplexId>> &vertexRepresentativesMax,
77 std::vector<std::vector<SimplexId>> &saddleCCMin,
78 std::vector<std::vector<SimplexId>> &saddleCCMax,
79 std::vector<Lock> &vertLockMin,
80 std::vector<Lock> &vertLockMax,
81 std::vector<polarity> &isUpdatedMin,
82 std::vector<polarity> &isUpdatedMax,
83 const scalarType *fakeScalars,
84 const offsetType *
const offsetField,
85 const int *
const monotonyOffsets);
87 template <
typename scalarType,
typename offsetType>
90 std::vector<std::pair<polarity, polarity>> &vlp,
91 const scalarType *fakeScalars,
92 const offsetType *
const offsetField,
93 const int *
const monotonyOffsets)
const;
95 template <
typename ScalarType,
typename OffsetType>
97 const ScalarType *
const scalars,
98 const ScalarType *
const fakeScalars,
99 const OffsetType *
const offsets,
100 const int *
const monotonyOffsets,
101 const bool splitTree)
const;
103 template <
typename scalarType,
typename offsetType>
106 std::vector<std::pair<polarity, polarity>> &vlp,
110 const scalarType *fakeScalars,
111 const offsetType *
const offsets,
112 const int *
const monotonyOffsets)
const;
114 template <
typename ScalarType,
typename offsetType>
116 std::vector<std::vector<std::pair<polarity, polarity>>>
118 std::vector<polarity> &toPropagateMin,
119 std::vector<polarity> &toPropagateMax,
120 std::vector<polarity> &toProcess,
121 std::vector<DynamicTree> &link,
122 std::vector<uint8_t> &vertexLink,
124 std::vector<std::vector<SimplexId>> &saddleCCMin,
125 std::vector<std::vector<SimplexId>> &saddleCCMax,
126 ScalarType *fakeScalars,
127 const offsetType *
const offsets,
128 int *monotonyOffsets);
130 template <
typename scalarType,
typename offsetType>
133 std::vector<Lock> &vertLock,
134 std::vector<polarity> &toPropagate,
135 std::vector<std::vector<SimplexId>> &vertexRepresentatives,
136 std::vector<std::vector<SimplexId>> &saddleCC,
137 std::vector<polarity> &isUpdated,
138 std::vector<SimplexId> &globalExtremum,
139 const bool splitTree,
140 const scalarType *fakeScalars,
141 const offsetType *
const offsetField,
142 const int *
const monotonyOffsets)
const;
144 template <
typename ScalarType,
typename offsetType>
146 std::vector<PersistencePair> &CTDiagram,
147 const ScalarType *
const fakeScalars,
148 const offsetType *
const offsets,
149 const int *
const monotonyOffsets,
150 std::vector<std::vector<SimplexId>> &vertexRepresentativesMin,
151 std::vector<std::vector<SimplexId>> &vertexRepresentativesMax,
152 const std::vector<polarity> &toPropagateMin,
153 const std::vector<polarity> &toPropagateMax)
const;
155 template <
typename scalarType,
typename offsetType>
157 std::vector<SimplexId> &sortedVertices,
159 const scalarType *
const fakeScalars,
160 const offsetType *
const offsetField,
161 const int *
const monotonyOffsets);
163 template <
typename scalarType>
165 scalarType *fakeScalars,
167 int *monotonyOffsets)
const;
173 = std::array<std::vector<std::pair<SimplexId, SimplexId>>,
nLink_>;
177 std::vector<std::vector<std::pair<polarity, polarity>>>
179 std::vector<polarity> &toProcess,
180 std::vector<DynamicTree> &link,
181 std::vector<uint8_t> &vertexLink,
183 std::vector<char> &vertexTypes,
187 std::vector<std::vector<std::pair<polarity, polarity>>>
189 std::vector<polarity> &toPropagateMin,
190 std::vector<polarity> &toPropagateMax,
191 std::vector<polarity> &toProcess,
192 std::vector<DynamicTree> &link,
193 std::vector<uint8_t> &vertexLink,
195 std::vector<std::vector<SimplexId>> &saddleCCMin,
196 std::vector<std::vector<SimplexId>> &saddleCCMax,
199 template <
typename scalarType,
typename offsetType>
201 std::vector<polarity> &toPropagateMin,
202 std::vector<polarity> &toPropagateMax,
203 std::vector<std::vector<SimplexId>> &vertexRepresentativesMin,
204 std::vector<std::vector<SimplexId>> &vertexRepresentativesMax,
205 std::vector<std::vector<SimplexId>> &saddleCCMin,
206 std::vector<std::vector<SimplexId>> &saddleCCMax,
207 std::vector<Lock> &vertLockMin,
208 std::vector<Lock> &vertLockMax,
209 std::vector<polarity> &isUpdatedMin,
210 std::vector<polarity> &isUpdatedMax,
211 const scalarType *fakeScalars,
212 const offsetType *
const offsets,
213 const int *
const monotonyOffsets)
const;
215 template <
typename scalarType,
typename offsetType>
218 std::vector<std::pair<polarity, polarity>> &vlp,
219 const scalarType *fakeScalars,
220 const offsetType *
const offsets,
221 const int *
const monotonyOffsets)
const;
223 template <
typename ScalarType,
typename OffsetType>
225 const ScalarType *
const fakeScalars,
226 const OffsetType *
const offsets,
227 const int *
const monotonyOffsets,
228 const bool splitTree)
const;
230 template <
typename scalarType,
typename offsetType>
232 std::vector<PersistencePair> &pairs,
233 std::vector<std::vector<SimplexId>> &vertexRepresentatives,
234 std::vector<triplet> &triplets,
235 const scalarType *
const fakeScalars,
236 const offsetType *
const offsets,
237 const int *
const monotonyOffsets,
238 const bool splitTree)
const;
240 template <
typename scalarType,
typename offsetType>
244 const std::vector<polarity> &isNew,
245 std::vector<polarity> &toProcess,
246 std::vector<polarity> &toReprocess,
247 std::vector<std::pair<polarity, polarity>> &vlp,
248 scalarType *fakeScalars,
249 const offsetType *
const offsets,
250 int *monotonyOffsets)
const;
252 template <
typename ScalarType,
typename offsetType>
255 std::vector<polarity> &isNew,
256 std::vector<std::vector<std::pair<polarity, polarity>>>
258 std::vector<polarity> &toProcess,
259 std::vector<polarity> &toReprocess,
260 ScalarType *fakeScalars,
261 const offsetType *
const offsets,
262 int *monotonyOffsets)
const;
266 std::vector<Lock> &vertLock,
267 std::vector<polarity> &toPropagate,
268 std::vector<std::vector<SimplexId>> &vertexRepresentatives,
269 std::vector<std::vector<SimplexId>> &saddleCC,
270 std::vector<polarity> &isUpdated,
271 std::vector<SimplexId> &globalExtremum,
273 const bool splitTree)
const;
276 std::vector<PersistencePair> &CTDiagram,
278 std::vector<std::vector<SimplexId>> &vertexRepresentativesMin,
279 std::vector<std::vector<SimplexId>> &vertexRepresentativesMax,
280 const std::vector<polarity> &toPropagateMin,
281 const std::vector<polarity> &toPropagateMax)
const;
283 template <
typename scalarType,
typename offsetType>
286 std::vector<std::vector<std::pair<polarity, polarity>>>
288 const scalarType *scalars,
289 const scalarType *fakeScalars,
290 const offsetType *
const offsets,
291 const int *
const monotonyOffsets,
292 bool verbose =
false);
302 scalarType *fakeScalars,
304 int *outputMonotonyOffsets) {
308 SimplexId *
const vertsOrder = outputOffsets;
314 int *monotonyOffsets = outputMonotonyOffsets;
316#ifdef TTK_ENABLE_KAMIKAZE
317 if(vertexNumber == 0) {
318 this->
printErr(
"No points in triangulation");
326 const size_t maxNeigh = dim == 3 ? 14 : (dim == 2 ? 6 : 0);
328 std::vector<std::vector<SimplexId>> saddleCCMin(vertexNumber),
329 saddleCCMax(vertexNumber);
330 std::vector<std::vector<SimplexId>> vertexRepresentativesMin(vertexNumber),
331 vertexRepresentativesMax(vertexNumber);
333 std::vector<std::vector<std::pair<polarity, polarity>>> vertexLinkPolarity(
336 std::vector<polarity> isNew(vertexNumber, 255);
337 std::vector<polarity> toPropagateMin(vertexNumber, 0),
338 toPropagateMax(vertexNumber, 0);
339 std::vector<polarity> isUpToDateMin(vertexNumber, 0),
340 isUpToDateMax(vertexNumber, 0);
343 std::vector<uint8_t> vertexLink(vertexNumber);
345 std::vector<DynamicTree> link(vertexNumber);
346 std::vector<polarity> toProcess(vertexNumber, 0), toReprocess{};
348 std::vector<SimplexId> offsetsVec(vertexNumber);
349 std::iota(offsetsVec.begin(), offsetsVec.end(), 0);
350 const SimplexId *
const offsets = offsetsVec.data();
354 toReprocess.resize(vertexNumber, 0);
357 std::vector<Lock> vertLockMin(vertexNumber), vertLockMax(vertexNumber);
363 for(
SimplexId i = 0; i < vertexNumber; ++i) {
367 vertexLinkPolarity[i].reserve(maxNeigh);
368 link[i].alloc(maxNeigh);
370 printMsg(
"Pre-allocating data structures", 1,
378 std::vector<SimplexId> boundReps{};
381#ifdef TTK_ENABLE_OPENMP
382#pragma omp parallel for num_threads(threadNumber_)
384 for(
size_t i = 0; i < boundReps.size(); i++) {
385 if(boundReps[i] != -1) {
415 toProcess, toReprocess, fakeScalars,
416 offsets, monotonyOffsets);
418 std::cout <<
"Found ERROR - aborting" << std::endl;
424 toProcess, link, vertexLink, vertexLinkByBoundaryType,
425 saddleCCMin, saddleCCMax, fakeScalars, offsets,
429 vertexRepresentativesMax, saddleCCMin, saddleCCMax,
430 vertLockMin, vertLockMax, isUpToDateMin, isUpToDateMax,
431 fakeScalars, offsets, monotonyOffsets);
434 CTDiagram_, fakeScalars, offsets, monotonyOffsets, vertexRepresentativesMin,
435 vertexRepresentativesMax, toPropagateMin, toPropagateMax);
444 this->threadNumber_);
449 CTDiagram_, fakeScalars, offsets, monotonyOffsets);
453 std::vector<SimplexId> sortedVertices{};
454 sortVertices(vertexNumber, sortedVertices, vertsOrder, fakeScalars, offsets,
461 std::vector<PersistencePair> &CTDiagram,
462 const ScalarType *
const fakeScalars,
463 const OffsetType *
const offsets,
464 const int *
const monotonyOffsets,
465 std::vector<std::vector<SimplexId>> &vertexRepresentativesMin,
466 std::vector<std::vector<SimplexId>> &vertexRepresentativesMax,
467 const std::vector<polarity> &toPropagateMin,
468 const std::vector<polarity> &toPropagateMax)
const {
472 std::vector<triplet> tripletsMax{}, tripletsMin{};
475 for(
SimplexId localId = 0; localId < nbDecVert; localId++) {
478 if(toPropagateMin[globalId]) {
481 if(toPropagateMax[globalId]) {
486 sortTriplets(tripletsMax, fakeScalars, offsets, monotonyOffsets,
true);
487 sortTriplets(tripletsMin, fakeScalars, offsets, monotonyOffsets,
false);
489 const auto tm_sort = timer.getElapsedTime();
491 typename std::remove_reference<
decltype(CTDiagram)>::type CTDiagramMin{},
494#ifdef TTK_ENABLE_OPENMP
495#pragma omp parallel sections num_threads(threadNumber_)
498#ifdef TTK_ENABLE_OPENMP
502 tripletsMax, fakeScalars, offsets,
503 monotonyOffsets,
true);
504#ifdef TTK_ENABLE_OPENMP
508 tripletsMin, fakeScalars, offsets,
509 monotonyOffsets,
false);
511 CTDiagram = std::move(CTDiagramMin);
512 CTDiagram.insert(CTDiagram.end(), CTDiagramMax.begin(), CTDiagramMax.end());
515 std::cout <<
"PAIRS " << timer.getElapsedTime() - tm_sort << std::endl;
670 const std::vector<polarity> &isNew,
671 std::vector<polarity> &toProcess,
672 std::vector<polarity> &toReprocess,
673 std::vector<std::pair<polarity, polarity>> &vlp,
674 scalarType *fakeScalars,
675 const offsetType *
const offsets,
676 int *monotonyOffsets)
const {
678 int hasMonotonyChanged = 0;
681 for(
SimplexId i = 0; i < neighborNumber; i++) {
690 const bool lowerDynamic
691 = ((fakeScalars[neighborId] < fakeScalars[vertexId])
692 || (fakeScalars[neighborId] == fakeScalars[vertexId]
693 && ((monotonyOffsets[neighborId] < monotonyOffsets[vertexId])
694 || (monotonyOffsets[neighborId] == monotonyOffsets[vertexId]
695 && offsets[neighborId] < offsets[vertexId]))));
697 const polarity isUpperDynamic = lowerDynamic ? 0 : 255;
699 const polarity isUpperOld = vlp[i].first;
701 if(isUpperDynamic != isUpperOld) {
705 vertexId, i, oldNeighbor, oldDecimation);
707 double const replacementValueDynamic
708 = (0.5 * (double)fakeScalars[oldNeighbor]
709 + .5 * (double)fakeScalars[vertexId]);
710 double const deltaDynamic
711 = fabs((
double)fakeScalars[neighborId] - replacementValueDynamic);
717 for(
SimplexId iii = 0; iii < nnumber; iii++) {
720 if(!isNew[neighborId2]) {
725 if(deltaDynamic > eps or !isNew[neighborId] or oldNeighNumber > 2) {
726 hasMonotonyChanged = 1;
728 toReprocess[vertexId] = 255;
729 if(isNew[neighborId]) {
730 toProcess[neighborId] = 255;
732 toReprocess[neighborId] = 255;
736 for(
SimplexId j = 0; j < neighborNumberNew; j++) {
739 neighborId, j, neighborIdNew);
740 if(isNew[neighborIdNew])
741 toProcess[neighborIdNew] = 255;
745 fakeScalars[neighborId] = replacementValueDynamic;
748 if(fakeScalars[neighborId] == fakeScalars[oldNeighbor]) {
749 fakeScalars[neighborId] = fakeScalars[vertexId];
759 if(offsets[vertexId] > offsets[neighborId]) {
760 monotonyOffsets[neighborId]
762 if(monotonyOffsets[vertexId] == monotonyOffsets[oldNeighbor]
763 and fakeScalars[vertexId] == fakeScalars[oldNeighbor]) {
764 std::cout <<
"THIS IS AN ISSUE" << std::endl;
767 monotonyOffsets[neighborId] = monotonyOffsets[vertexId];
770 if(offsets[vertexId] < offsets[neighborId]) {
771 monotonyOffsets[neighborId]
773 if(monotonyOffsets[vertexId] == monotonyOffsets[oldNeighbor]
774 and fakeScalars[vertexId] == fakeScalars[oldNeighbor]) {
775 std::cout <<
"THIS IS AN ISSUE" << std::endl;
778 monotonyOffsets[neighborId] = monotonyOffsets[vertexId];
784 return hasMonotonyChanged;
790 std::vector<Lock> &vertLock,
791 std::vector<polarity> &toPropagate,
792 std::vector<std::vector<SimplexId>> &vertexRepresentatives,
793 std::vector<std::vector<SimplexId>> &saddleCC,
794 std::vector<polarity> &isUpdated,
795 std::vector<SimplexId> &globalExtremum,
796 const bool splitTree,
797 const scalarType *fakeScalars,
798 const offsetType *
const offsets,
799 const int *
const monotonyOffsets)
const {
801 auto &toProp = toPropagate[vertexId];
802 auto &reps = vertexRepresentatives[vertexId];
803 auto &updated = isUpdated[vertexId];
816 return ((fakeScalars[v1] > fakeScalars[v2])
817 || (fakeScalars[v1] == fakeScalars[v2]
818 && ((monotonyOffsets[v1] > monotonyOffsets[v2])
819 || (monotonyOffsets[v1] == monotonyOffsets[v2]
820 && offsets[v1] > offsets[v2]))))
825 vertLock[vertexId].lock();
827 if(saddleCC[vertexId].size()
833 printMsg(
"to saddle " + std::to_string(vertexId) +
" "
834 + std::to_string(saddleCC[vertexId].size()));
841 const auto &CC = saddleCC[vertexId];
843 reps.reserve(CC.size());
844 for(
size_t r = 0; r < CC.size(); r++) {
853 neighborId, vertLock, toPropagate, vertexRepresentatives, saddleCC,
854 isUpdated, globalExtremum, splitTree, fakeScalars, offsets,
856 reps.emplace_back(ret);
859 if(reps.size() > 1) {
861 std::sort(reps.begin(), reps.end(), gt);
862 const auto last = std::unique(reps.begin(), reps.end());
863 reps.erase(last, reps.end());
868 vertLock[vertexId].unlock();
875 printMsg(
"to non saddle " + std::to_string(vertexId) +
" "
876 + std::to_string(saddleCC[vertexId].size()));
883 for(
SimplexId i = 0; i < neighborNumber; i++) {
886 if(gt(neighborId, maxNeighbor)) {
887 maxNeighbor = neighborId;
890 if(maxNeighbor != vertexId) {
892 vertexRepresentatives, saddleCC, isUpdated,
893 globalExtremum, splitTree, fakeScalars,
894 offsets, monotonyOffsets);
897#ifdef TTK_ENABLE_OPENMP
898 const auto tid = omp_get_thread_num();
902 if(gt(vertexId, globalExtremum[tid])) {
907 globalExtremum[tid] = vertexId;
914 vertLock[vertexId].unlock();
922 std::vector<polarity> &toPropagateMin,
923 std::vector<polarity> &toPropagateMax,
924 std::vector<std::vector<SimplexId>> &vertexRepresentativesMin,
925 std::vector<std::vector<SimplexId>> &vertexRepresentativesMax,
926 std::vector<std::vector<SimplexId>> &saddleCCMin,
927 std::vector<std::vector<SimplexId>> &saddleCCMax,
928 std::vector<Lock> &vertLockMin,
929 std::vector<Lock> &vertLockMax,
930 std::vector<polarity> &isUpdatedMin,
931 std::vector<polarity> &isUpdatedMax,
932 const scalarType *fakeScalars,
933 const offsetType *
const offsets,
934 const int *
const monotonyOffsets) {
940 const auto pred = [](
const polarity a) {
return a > 0; };
941 const auto numberOfCandidatesToPropagateMax
942 = std::count_if(toPropagateMax.begin(), toPropagateMax.end(), pred);
943 std::cout <<
" sad-max we have " << numberOfCandidatesToPropagateMax
944 <<
" vertices to propagate from outta " << nDecVerts << std::endl;
945 const auto numberOfCandidatesToPropagateMin
946 = std::count_if(toPropagateMin.begin(), toPropagateMin.end(), pred);
947 std::cout <<
" min-sad we have " << numberOfCandidatesToPropagateMin
948 <<
" vertices to propagate from outta " << nDecVerts << std::endl;
955#ifdef TTK_ENABLE_OPENMP
956#pragma omp parallel for num_threads(threadNumber_)
958 for(
size_t i = 0; i < nDecVerts; i++) {
965#ifdef TTK_ENABLE_OPENMP
966#pragma omp parallel for num_threads(threadNumber_)
968 for(
size_t i = 0; i < nDecVerts; i++) {
970 if(toPropagateMin[v]) {
972 vertexRepresentativesMin, saddleCCMin, isUpdatedMin,
973 globalMinThr,
false, fakeScalars, offsets,
976 if(toPropagateMax[v]) {
978 vertexRepresentativesMax, saddleCCMax, isUpdatedMax,
979 globalMaxThr,
true, fakeScalars, offsets,
985 return ((fakeScalars[a] < fakeScalars[b])
986 || (fakeScalars[a] == fakeScalars[b]
987 && ((monotonyOffsets[a] < monotonyOffsets[b])
988 || (monotonyOffsets[a] == monotonyOffsets[b]
989 && offsets[a] < offsets[b]))));
992 globalMin_ = *std::min_element(globalMinThr.begin(), globalMinThr.end(), lt);
993 globalMax_ = *std::max_element(globalMaxThr.begin(), globalMaxThr.end(), lt);
996#ifdef TTK_ENABLE_OPENMP
997#pragma omp parallel for num_threads(threadNumber_)
999 for(
size_t i = 0; i < nDecVerts; i++) {
1002#ifdef TTK_ENABLE_OPENMP
1003 const auto tid = omp_get_thread_num();
1008 if(lt(globalMaxThr[tid], v)) {
1009 globalMaxThr[tid] = v;
1011 if(lt(v, globalMinThr[tid])) {
1012 globalMinThr[tid] = v;
1016 = *std::min_element(globalMinThr.begin(), globalMinThr.end(), lt);
1018 = *std::max_element(globalMaxThr.begin(), globalMaxThr.end(), lt);
1057 std::vector<polarity> &isNew,
1059 std::vector<std::vector<std::pair<polarity, polarity>>> &vertexLinkPolarity,
1060 const scalarType *scalars,
1061 const scalarType *fakeScalars,
1062 const offsetType *
const offsets,
1063 const int *
const monotonyOffsets,
1067 std::stringstream mymsg;
1068 std::vector<std::pair<polarity, polarity>> &vlp
1069 = vertexLinkPolarity[vertexId];
1070 mymsg <<
"POLARITY PRINT"
1072 mymsg <<
"vertex " << vertexId <<
" has "
1076 mymsg <<
"\tself f:" << fakeScalars[vertexId] <<
" s:" << scalars[vertexId]
1077 <<
" o:" << offsets[vertexId] <<
" m:" << monotonyOffsets[vertexId]
1078 <<
" isnew: " << (int)isNew[vertexId] <<
"\n";
1081 std::cout <<
"\tpolarity not initialized for " << vertexId << std::endl;
1082 std::cout << mymsg.str() << std::endl;
1091 std::vector<std::pair<polarity, polarity>> &vlp2 = vertexLinkPolarity[nId];
1099 if(nId2 == vertexId) {
1100 rpol = vlp2[j].first;
1107 = ((fakeScalars[nId] < fakeScalars[vertexId])
1108 || (fakeScalars[nId] == fakeScalars[vertexId]
1109 && ((monotonyOffsets[nId] < monotonyOffsets[vertexId])
1110 || (monotonyOffsets[nId] == monotonyOffsets[vertexId]
1111 && offsets[nId] < offsets[vertexId]))));
1113 const polarity isUpper = lower ? 0 : 255;
1115 mymsg <<
" " << i <<
"th: " << nId <<
" f:" << fakeScalars[nId]
1116 <<
" s:" << scalars[nId] <<
" o:" << offsets[nId]
1117 <<
" m:" << monotonyOffsets[nId] <<
" , pol:" << (bool)vlp[i].first
1118 <<
"(" << (
bool)vlp[i].second <<
")"
1119 <<
" rpol:" << (bool)rpol <<
" true pol:" << (
bool)isUpper
1120 <<
" init " << init <<
" isnew: " << (int)isNew[nId] <<
"\n";
1121 if((rpol == isUpper and !vlp2.empty())
1122 or (isUpper != vlp[i].first and !vlp[i].second)) {
1123 mymsg <<
"POLARITY ERROR "
1128 if(error or verbose) {
1129 std::cout << mymsg.str() << std::endl;
1251 std::vector<std::vector<std::pair<polarity, polarity>>> &vertexLinkPolarity,
1252 std::vector<polarity> &toPropagateMin,
1253 std::vector<polarity> &toPropagateMax,
1254 std::vector<polarity> &toProcess,
1255 std::vector<DynamicTree> &link,
1256 std::vector<uint8_t> &vertexLink,
1258 std::vector<std::vector<SimplexId>> &saddleCCMin,
1259 std::vector<std::vector<SimplexId>> &saddleCCMax,
1260 ScalarType *fakeScalars,
1261 const offsetType *
const offsets,
1262 int *monotonyOffsets) {
1266#ifdef TTK_ENABLE_OPENMP
1267#pragma omp parallel for num_threads(threadNumber_)
1272 if(toProcess[globalId]) {
1275 vertexLink[globalId], link[globalId],
1276 vertexLinkByBoundaryType, fakeScalars, offsets,
1279 link[globalId], toPropagateMin, toPropagateMax,
1280 saddleCCMin, saddleCCMax);