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);
220 + std::to_string(triangulation.getNumberOfVertices())
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)
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)