37#ifdef TTK_ENABLE_64BIT_IDS
46 constexpr unsigned long long int getHash(
const unsigned long long int a,
47 const unsigned long long int b) {
48 return (a * b + (a * a) + (b * b) + (a * a * a) * (b * b * b))
60 constexpr unsigned int getHash(
const unsigned int a,
const unsigned int b) {
61 return (a * b + (a * a) + (b * b) + (a * a * a) * (b * b * b)) % UINT_MAX;
96 template <
typename triangulationType>
97 inline int execute(OutputSegmentation &outSegmentation,
99 const triangulationType &triangulation);
117 template <
typename triangulationType>
121 const triangulationType &triangulation)
const;
140 template <
typename triangulationType>
143 const bool computeAscending,
145 const triangulationType &triangulation)
const;
152 const bool doDescending,
153 const bool doMorseSmale) {
171 template <
typename triangulationType>
175 const triangulationType &triangulation)
const;
189template <
typename triangulationType>
192 const triangulationType &triangulation) {
193 if(orderArray ==
nullptr)
194 return this->
printErr(
"Input offset field pointer is null.");
199 this->threadNumber_);
208 outSegmentation.
ascending_,
true, orderArray, triangulation);
211 outSegmentation.
descending_,
false, orderArray, triangulation);
221 +
" points) processed",
227template <
typename triangulationType>
232 const triangulationType &triangulation)
const {
236 const SimplexId nVertices = triangulation.getNumberOfVertices();
237 std::vector<SimplexId> lActiveVertices;
239#ifdef TTK_ENABLE_OPENMP
240#pragma omp parallel num_threads(threadNumber_) private(lActiveVertices)
242 lActiveVertices.reserve(std::ceil(nVertices / threadNumber_));
244#pragma omp for schedule(static)
246 lActiveVertices.reserve(nVertices);
249 for(
SimplexId i = 0; i < nVertices; i++) {
251 SimplexId const numNeighbors = triangulation.getVertexNeighborNumber(i);
253 bool hasLargerNeighbor =
false;
257 bool hasSmallerNeighbor =
false;
262 for(
SimplexId n = 0; n < numNeighbors; n++) {
263 triangulation.getVertexNeighbor(i, n, neighborId);
265 if(orderArray[neighborId] < orderArray[ami]) {
267 hasSmallerNeighbor =
true;
268 }
else if(orderArray[neighborId] > orderArray[dmi]) {
270 hasLargerNeighbor =
true;
274 if(hasLargerNeighbor || hasSmallerNeighbor) {
275 lActiveVertices.push_back(i);
279 size_t lnActiveVertices = lActiveVertices.size();
280 size_t currentIndex = 0;
283 while(lnActiveVertices > 0) {
284 for(
size_t i = 0; i < lnActiveVertices; i++) {
290#ifdef TTK_ENABLE_OPENMP
291#pragma omp atomic read
293 vDsc = dscSegmentation[vDsc];
295#ifdef TTK_ENABLE_OPENMP
296#pragma omp atomic read
298 vAsc = ascSegmentation[vAsc];
301 if(vDsc != dscSegmentation[vDsc] || vAsc != ascSegmentation[vAsc]) {
302 lActiveVertices[currentIndex++] = v;
306 lnActiveVertices = currentIndex;
309#ifdef TTK_ENABLE_OPENMP
313 this->
printMsg(
"Asc. and Desc. segmentation computed", 1.0,
320template <
typename triangulationType>
323 const bool computeAscending,
325 const triangulationType &triangulation)
const {
329 const SimplexId nVertices = triangulation.getNumberOfVertices();
330 std::vector<SimplexId> lActiveVertices;
332#ifdef TTK_ENABLE_OPENMP
333#pragma omp parallel num_threads(threadNumber_)
335 lActiveVertices.reserve(std::ceil(nVertices / threadNumber_));
337#pragma omp for schedule(static)
339 lActiveVertices.reserve(nVertices);
342 for(
SimplexId i = 0; i < nVertices; i++) {
344 SimplexId const numNeighbors = triangulation.getVertexNeighborNumber(i);
346 bool hasLargerNeighbor =
false;
351 for(
SimplexId n = 0; n < numNeighbors; n++) {
352 triangulation.getVertexNeighbor(i, n, neighborId);
354 if(computeAscending) {
355 if(orderArray[neighborId] < orderArray[mi]) {
357 hasLargerNeighbor =
true;
360 if(orderArray[neighborId] > orderArray[mi]) {
362 hasLargerNeighbor =
true;
367 if(hasLargerNeighbor) {
368 lActiveVertices.push_back(i);
372 size_t lnActiveVertices = lActiveVertices.size();
373 size_t currentIndex = 0;
376 while(lnActiveVertices > 0) {
377 for(
size_t i = 0; i < lnActiveVertices; i++) {
382#ifdef TTK_ENABLE_OPENMP
383#pragma omp atomic read
385 vMan = segmentation[vMan];
388 if(vMan != segmentation[vMan]) {
389 lActiveVertices[currentIndex++] = v;
393 lnActiveVertices = currentIndex;
396#ifdef TTK_ENABLE_OPENMP
400 if(computeAscending) {
401 this->
printMsg(
"Ascending segmentation computed", 1.0,
405 this->
printMsg(
"Descending segmentation computed", 1.0,
413template <
typename triangulationType>
418 const triangulationType &triangulation)
const {
422 const size_t nVerts = triangulation.getNumberOfVertices();
424#ifdef TTK_ENABLE_OPENMP
425#pragma omp parallel for schedule(static) num_threads(threadNumber_)
427 for(
size_t i = 0; i < nVerts; ++i) {
428 morseSmaleSegmentation[i]
432 this->
printMsg(
"Morse-Smale segmentation hash computed", 1.0,
AbstractTriangulation is an interface class that defines an interface for efficient traversal methods...
virtual int preconditionVertexNeighbors()
Minimalist debugging class.
int printErr(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
TTK processing package for the computation of Morse-Smale segmentations using Path Compression.
bool ComputeMSSegmentationHash
void preconditionTriangulation(AbstractTriangulation *const data)
bool ComputeAscendingSegmentation
int execute(OutputSegmentation &outSegmentation, const SimplexId *const orderArray, const triangulationType &triangulation)
Main function for computing the Morse-Smale complex.
int computeMSHash(SimplexId *const morseSmaleSegmentation, const SimplexId *const ascSegmentation, const SimplexId *const dscSegmentation, const triangulationType &triangulation) const
Computes a MS segmentation hash.
int computePathCompressionSingle(SimplexId *const segmentation, const bool computeAscending, const SimplexId *const orderArray, const triangulationType &triangulation) const
Compute the ascending or descending segmentation.
int computePathCompression(SimplexId *const ascSegmentation, SimplexId *const dscSegmentation, const SimplexId *const orderArray, const triangulationType &triangulation) const
Compute the ascending and descending segmentation in one run.
bool ComputeDescendingSegmentation
void setComputeSegmentation(const bool doAscending, const bool doDescending, const bool doMorseSmale)
std::string to_string(__int128)
constexpr unsigned int getHash(const unsigned int a, const unsigned int b)
Get a hash value from two keys.
int SimplexId
Identifier type for simplices of any dimension.
Pointers to pre-allocated segmentation point data arrays.
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/|__ _|"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)