TTK
Loading...
Searching...
No Matches
ttkMorseSmaleComplex.cpp
Go to the documentation of this file.
1#include <ttkMacros.h>
3#include <ttkUtils.h>
4
5#include <vtkCellData.h>
6#include <vtkDataArray.h>
7#include <vtkDataObject.h>
8#include <vtkDataSet.h>
9#include <vtkDoubleArray.h>
10#include <vtkFloatArray.h>
11#include <vtkIdTypeArray.h>
12#include <vtkInformation.h>
13#include <vtkNew.h>
14#include <vtkPointData.h>
15#include <vtkPolyData.h>
16#include <vtkSignedCharArray.h>
17#include <vtkUnsignedCharArray.h>
18
20
22 this->setDebugMsgPrefix("MorseSmaleComplex");
23 SetNumberOfInputPorts(1);
24 SetNumberOfOutputPorts(4);
25}
26
28 vtkInformation *info) {
29 if(port == 0) {
30 info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet");
31 return 1;
32 }
33 return 0;
34}
35
37 vtkInformation *info) {
38 if(port == 0 || port == 1 || port == 2) {
39 info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkPolyData");
40 return 1;
41 } else if(port == 3) {
43 return 1;
44 }
45 return 0;
46}
47
48template <typename vtkArrayType, typename vectorType>
49void setArray(vtkArrayType &vtkArray, vectorType &vector) {
50 ttkUtils::SetVoidArray(vtkArray, vector.data(), vector.size(), 1);
51}
52
53template <typename scalarType, typename triangulationType>
54int ttkMorseSmaleComplex::dispatch(vtkDataArray *const inputScalars,
55 vtkPolyData *const outputCriticalPoints,
56 vtkPolyData *const outputSeparatrices1,
57 vtkPolyData *const outputSeparatrices2,
58 const SimplexId *const inputOffsets,
59 const triangulationType &triangulation) {
60
61 const int dimensionality = triangulation.getDimensionality();
62 const auto scalars = ttkUtils::GetPointer<scalarType>(inputScalars);
63
64 const int ret = this->execute(
65 criticalPoints_, separatrices1_, separatrices2_, segmentations_, scalars,
66 inputScalars->GetMTime(), inputOffsets, triangulation);
67
68#ifndef TTK_ENABLE_KAMIKAZE
69 if(ret != 0) {
70 this->printErr("MorseSmaleComplex.execute() error");
71 return -1;
72 }
73#endif
74
75 // critical points
76 {
77 vtkNew<vtkPoints> points{};
78 vtkNew<vtkSignedCharArray> cellDimensions{};
79 vtkNew<ttkSimplexIdTypeArray> cellIds{};
80 vtkSmartPointer<vtkDataArray> cellScalars{inputScalars->NewInstance()};
81 vtkNew<vtkSignedCharArray> isOnBoundary{};
82 vtkNew<ttkSimplexIdTypeArray> PLVertexIdentifiers{};
83 vtkNew<ttkSimplexIdTypeArray> manifoldSizeScalars{};
84 const auto nPoints = criticalPoints_.points_.size();
85
86#ifndef TTK_ENABLE_KAMIKAZE
87 if(!points || !cellDimensions || !cellIds || !cellScalars || !isOnBoundary
88 || !PLVertexIdentifiers || !manifoldSizeScalars) {
89 this->printErr("Critical points vtkDataArray allocation problem.");
90 return -1;
91 }
92#endif
93
94 points->SetNumberOfPoints(nPoints);
95
96 cellDimensions->SetNumberOfComponents(1);
97 cellDimensions->SetName(ttk::MorseSmaleCellDimensionName);
98 setArray(cellDimensions, criticalPoints_.cellDimensions_);
99
100 cellIds->SetNumberOfComponents(1);
101 cellIds->SetName(ttk::MorseSmaleCellIdName);
102 setArray(cellIds, criticalPoints_.cellIds_);
103
104 cellScalars->SetNumberOfComponents(1);
105 cellScalars->SetName(inputScalars->GetName());
106 cellScalars->SetNumberOfTuples(nPoints);
107#ifdef TTK_ENABLE_OPENMP
108#pragma omp parallel for num_threads(this->threadNumber_)
109#endif // TTK_ENABLE_OPENMP
110 for(size_t i = 0; i < nPoints; ++i) {
111 points->SetPoint(i, criticalPoints_.points_[i].data());
112 cellScalars->SetTuple1(
113 i, scalars[criticalPoints_.PLVertexIdentifiers_[i]]);
114 }
115
116 isOnBoundary->SetNumberOfComponents(1);
117 isOnBoundary->SetName(ttk::MorseSmaleBoundaryName);
118 setArray(isOnBoundary, criticalPoints_.isOnBoundary_);
119
120 PLVertexIdentifiers->SetNumberOfComponents(1);
121 PLVertexIdentifiers->SetName(ttk::VertexScalarFieldName);
122 setArray(PLVertexIdentifiers, criticalPoints_.PLVertexIdentifiers_);
123
124 manifoldSizeScalars->SetNumberOfComponents(1);
125 manifoldSizeScalars->SetName(ttk::MorseSmaleManifoldSizeName);
127 criticalPoints_.manifoldSize_.resize(nPoints);
128 std::fill(criticalPoints_.manifoldSize_.begin(),
129 criticalPoints_.manifoldSize_.end(), -1);
130 }
131 setArray(manifoldSizeScalars, criticalPoints_.manifoldSize_);
132
133 ttkUtils::CellVertexFromPoints(outputCriticalPoints, points);
134
135 auto pointData = outputCriticalPoints->GetPointData();
136#ifndef TTK_ENABLE_KAMIKAZE
137 if(!pointData) {
138 this->printErr("outputCriticalPoints has no point data.");
139 return -1;
140 }
141#endif
142
143 pointData->SetScalars(cellDimensions);
144 pointData->AddArray(cellIds);
145 pointData->AddArray(cellScalars);
146 pointData->AddArray(isOnBoundary);
147 pointData->AddArray(PLVertexIdentifiers);
148 pointData->AddArray(manifoldSizeScalars);
149 }
150
151 // 1-separatrices
154
155 vtkNew<vtkFloatArray> pointsCoords{};
156 vtkNew<vtkSignedCharArray> smoothingMask{};
157 vtkNew<vtkSignedCharArray> cellDimensions{};
158 vtkNew<ttkSimplexIdTypeArray> cellIds{};
159 vtkNew<ttkSimplexIdTypeArray> sourceIds{};
160 vtkNew<ttkSimplexIdTypeArray> destinationIds{};
161 vtkNew<ttkSimplexIdTypeArray> separatrixIds{};
162 vtkNew<vtkSignedCharArray> separatrixTypes{};
163 vtkNew<vtkDoubleArray> separatrixFunctionMaxima{};
164 vtkNew<vtkDoubleArray> separatrixFunctionMinima{};
165 vtkNew<vtkDoubleArray> separatrixFunctionDiffs{};
166 vtkNew<vtkSignedCharArray> isOnBoundary{};
167
168#ifndef TTK_ENABLE_KAMIKAZE
169 if(!pointsCoords || !smoothingMask || !cellDimensions || !cellIds
170 || !sourceIds || !destinationIds || !separatrixIds || !separatrixTypes
171 || !separatrixFunctionMaxima || !separatrixFunctionMinima
172 || !separatrixFunctionDiffs || !isOnBoundary) {
173 this->printErr("1-separatrices vtkDataArray allocation problem.");
174 return -1;
175 }
176#endif
177
178 pointsCoords->SetNumberOfComponents(3);
179 setArray(pointsCoords, separatrices1_.pt.points_);
180
181 smoothingMask->SetNumberOfComponents(1);
182 smoothingMask->SetName(ttk::MaskScalarFieldName);
183 setArray(smoothingMask, separatrices1_.pt.smoothingMask_);
184
185 cellDimensions->SetNumberOfComponents(1);
186 cellDimensions->SetName(ttk::MorseSmaleCellDimensionName);
187 setArray(cellDimensions, separatrices1_.pt.cellDimensions_);
188
189 cellIds->SetNumberOfComponents(1);
190 cellIds->SetName(ttk::MorseSmaleCellIdName);
191 setArray(cellIds, separatrices1_.pt.cellIds_);
192
193 sourceIds->SetNumberOfComponents(1);
194 sourceIds->SetName(ttk::MorseSmaleSourceIdName);
195 setArray(sourceIds, separatrices1_.cl.sourceIds_);
196
197 destinationIds->SetNumberOfComponents(1);
198 destinationIds->SetName(ttk::MorseSmaleDestinationIdName);
199 setArray(destinationIds, separatrices1_.cl.destinationIds_);
200
201 separatrixIds->SetNumberOfComponents(1);
202 separatrixIds->SetName(ttk::MorseSmaleSeparatrixIdName);
203 setArray(separatrixIds, separatrices1_.cl.separatrixIds_);
204
205 separatrixTypes->SetNumberOfComponents(1);
206 separatrixTypes->SetName(ttk::MorseSmaleSeparatrixTypeName);
207 setArray(separatrixTypes, separatrices1_.cl.separatrixTypes_);
208
209 separatrixFunctionMaxima->SetNumberOfComponents(1);
210 separatrixFunctionMaxima->SetName(ttk::MorseSmaleSeparatrixMaximumName);
211 separatrixFunctionMaxima->SetNumberOfTuples(
212 separatrices1_.cl.numberOfCells_);
213
214 separatrixFunctionMinima->SetNumberOfComponents(1);
215 separatrixFunctionMinima->SetName(ttk::MorseSmaleSeparatrixMinimumName);
216 separatrixFunctionMinima->SetNumberOfTuples(
217 separatrices1_.cl.numberOfCells_);
218
219 separatrixFunctionDiffs->SetNumberOfComponents(1);
220 separatrixFunctionDiffs->SetName(ttk::MorseSmaleSeparatrixDifferenceName);
221 separatrixFunctionDiffs->SetNumberOfTuples(
222 separatrices1_.cl.numberOfCells_);
223
224#ifdef TTK_ENABLE_OPENMP
225#pragma omp parallel for num_threads(this->threadNumber_)
226#endif // TTK_ENABLE_OPENMP
227 for(SimplexId i = 0; i < separatrices1_.cl.numberOfCells_; ++i) {
228 const auto sepId = separatrices1_.cl.separatrixIds_[i];
229 // inputScalars->GetTuple1 not thread safe...
230 const auto min = scalars[separatrices1_.cl.sepFuncMinId_[sepId]];
231 const auto max = scalars[separatrices1_.cl.sepFuncMaxId_[sepId]];
232 separatrixFunctionMinima->SetTuple1(i, min);
233 separatrixFunctionMaxima->SetTuple1(i, max);
234 separatrixFunctionDiffs->SetTuple1(i, max - min);
235 }
236
237 isOnBoundary->SetNumberOfComponents(1);
238 isOnBoundary->SetName(ttk::MorseSmaleCriticalPointsOnBoundaryName);
239 setArray(isOnBoundary, separatrices1_.cl.isOnBoundary_);
240
241 vtkNew<ttkSimplexIdTypeArray> offsets{}, connectivity{};
242 offsets->SetNumberOfComponents(1);
243 offsets->SetNumberOfTuples(separatrices1_.cl.numberOfCells_ + 1);
244 connectivity->SetNumberOfComponents(1);
245 setArray(connectivity, separatrices1_.cl.connectivity_);
246
247#ifdef TTK_ENABLE_OPENMP
248#pragma omp parallel for num_threads(this->threadNumber_)
249#endif // TTK_ENABLE_OPENMP
250 for(SimplexId i = 0; i < separatrices1_.cl.numberOfCells_ + 1; ++i) {
251 offsets->SetTuple1(i, 2 * i);
252 }
253
254 vtkNew<vtkPoints> points{};
255 points->SetData(pointsCoords);
256 outputSeparatrices1->SetPoints(points);
257 vtkNew<vtkCellArray> cells{};
258#ifndef TTK_ENABLE_64BIT_IDS
259 cells->Use32BitStorage();
260#endif // TTK_ENABLE_64BIT_IDS
261 cells->SetData(offsets, connectivity);
262 outputSeparatrices1->SetLines(cells);
263
264 auto pointData = outputSeparatrices1->GetPointData();
265 auto cellData = outputSeparatrices1->GetCellData();
266
267#ifndef TTK_ENABLE_KAMIKAZE
268 if(!pointData || !cellData) {
269 this->printErr("outputSeparatrices1 has no point or no cell data.");
270 return -1;
271 }
272#endif
273
274 pointData->AddArray(smoothingMask);
275 pointData->AddArray(cellDimensions);
276 pointData->AddArray(cellIds);
277
278 cellData->AddArray(sourceIds);
279 cellData->AddArray(destinationIds);
280 cellData->AddArray(separatrixIds);
281 cellData->SetScalars(separatrixTypes);
282 cellData->AddArray(separatrixFunctionMaxima);
283 cellData->AddArray(separatrixFunctionMinima);
284 cellData->AddArray(separatrixFunctionDiffs);
285 cellData->AddArray(isOnBoundary);
286 }
287
288 // 2-separatrices
289 if(dimensionality == 3
291
292 vtkNew<vtkFloatArray> pointsCoords{};
293 vtkNew<ttkSimplexIdTypeArray> sourceIds{};
294 vtkNew<ttkSimplexIdTypeArray> separatrixIds{};
295 vtkNew<vtkSignedCharArray> separatrixTypes{};
296 vtkNew<vtkDoubleArray> separatrixFunctionMaxima{};
297 vtkNew<vtkDoubleArray> separatrixFunctionMinima{};
298 vtkNew<vtkDoubleArray> separatrixFunctionDiffs{};
299 vtkNew<vtkSignedCharArray> isOnBoundary{};
300
301#ifndef TTK_ENABLE_KAMIKAZE
302 if(!pointsCoords || !sourceIds || !separatrixIds || !separatrixTypes
303 || !separatrixFunctionMaxima || !separatrixFunctionMinima
304 || !separatrixFunctionDiffs || !isOnBoundary) {
305 this->printErr("2-separatrices vtkDataArray allocation problem.");
306 return -1;
307 }
308#endif
309
310 pointsCoords->SetNumberOfComponents(3);
311 setArray(pointsCoords, separatrices2_.pt.points_);
312
313 sourceIds->SetNumberOfComponents(1);
314 sourceIds->SetName(ttk::MorseSmaleSourceIdName);
315 setArray(sourceIds, separatrices2_.cl.sourceIds_);
316
317 separatrixIds->SetNumberOfComponents(1);
318 separatrixIds->SetName(ttk::MorseSmaleSeparatrixIdName);
319 setArray(separatrixIds, separatrices2_.cl.separatrixIds_);
320
321 separatrixTypes->SetNumberOfComponents(1);
322 separatrixTypes->SetName(ttk::MorseSmaleSeparatrixTypeName);
323 setArray(separatrixTypes, separatrices2_.cl.separatrixTypes_);
324
325 separatrixFunctionMaxima->SetNumberOfComponents(1);
326 separatrixFunctionMaxima->SetName(ttk::MorseSmaleSeparatrixMaximumName);
327 separatrixFunctionMaxima->SetNumberOfTuples(
328 separatrices2_.cl.numberOfCells_);
329
330 separatrixFunctionMinima->SetNumberOfComponents(1);
331 separatrixFunctionMinima->SetName(ttk::MorseSmaleSeparatrixMinimumName);
332 separatrixFunctionMinima->SetNumberOfTuples(
333 separatrices2_.cl.numberOfCells_);
334
335 separatrixFunctionDiffs->SetNumberOfComponents(1);
336 separatrixFunctionDiffs->SetName(ttk::MorseSmaleSeparatrixDifferenceName);
337 separatrixFunctionDiffs->SetNumberOfTuples(
338 separatrices2_.cl.numberOfCells_);
339
340#ifdef TTK_ENABLE_OPENMP
341#pragma omp parallel for num_threads(this->threadNumber_)
342#endif // TTK_ENABLE_OPENMP
343 for(SimplexId i = 0; i < separatrices2_.cl.numberOfCells_; ++i) {
344 const auto sepId = separatrices2_.cl.separatrixIds_[i];
345 // inputScalars->GetTuple1 not thread safe...
346 const auto min = scalars[separatrices2_.cl.sepFuncMinId_[sepId]];
347 const auto max = scalars[separatrices2_.cl.sepFuncMaxId_[sepId]];
348 separatrixFunctionMinima->SetTuple1(i, min);
349 separatrixFunctionMaxima->SetTuple1(i, max);
350 separatrixFunctionDiffs->SetTuple1(i, max - min);
351 }
352
353 isOnBoundary->SetNumberOfComponents(1);
354 isOnBoundary->SetName(ttk::MorseSmaleCriticalPointsOnBoundaryName);
355 setArray(isOnBoundary, separatrices2_.cl.isOnBoundary_);
356
357 vtkNew<ttkSimplexIdTypeArray> offsets{}, connectivity{};
358 offsets->SetNumberOfComponents(1);
359 setArray(offsets, separatrices2_.cl.offsets_);
360 connectivity->SetNumberOfComponents(1);
361 setArray(connectivity, separatrices2_.cl.connectivity_);
362
363 vtkNew<vtkPoints> points{};
364 points->SetData(pointsCoords);
365 outputSeparatrices2->SetPoints(points);
366 vtkNew<vtkCellArray> cells{};
367#ifndef TTK_ENABLE_64BIT_IDS
368 cells->Use32BitStorage();
369#endif // TTK_ENABLE_64BIT_IDS
370 cells->SetData(offsets, connectivity);
371 outputSeparatrices2->SetPolys(cells);
372
373 auto cellData = outputSeparatrices2->GetCellData();
374#ifndef TTK_ENABLE_KAMIKAZE
375 if(!cellData) {
376 this->printErr("outputSeparatrices2 has no cell data.");
377 return -1;
378 }
379#endif
380
381 cellData->AddArray(sourceIds);
382 cellData->AddArray(separatrixIds);
383 cellData->AddArray(separatrixTypes);
384 cellData->AddArray(separatrixFunctionMaxima);
385 cellData->AddArray(separatrixFunctionMinima);
386 cellData->AddArray(separatrixFunctionDiffs);
387 cellData->AddArray(isOnBoundary);
388 }
389
390 return ret;
391}
392
394 vtkInformationVector **inputVector,
395 vtkInformationVector *outputVector) {
396
397 const auto input = vtkDataSet::GetData(inputVector[0]);
398 auto outputCriticalPoints = vtkPolyData::GetData(outputVector, 0);
399 auto outputSeparatrices1 = vtkPolyData::GetData(outputVector, 1);
400 auto outputSeparatrices2 = vtkPolyData::GetData(outputVector, 2);
401 auto outputMorseComplexes = vtkDataSet::GetData(outputVector, 3);
402
403#ifndef TTK_ENABLE_KAMIKAZE
404 if(!input) {
405 this->printErr("Input pointer is NULL.");
406 return -1;
407 }
408 if(input->GetNumberOfPoints() == 0) {
409 this->printErr("Input has no point.");
410 return -1;
411 }
412 if(!outputCriticalPoints or !outputSeparatrices1 or !outputSeparatrices2
413 or !outputMorseComplexes) {
414 this->printErr("Output pointers are NULL.");
415 return -1;
416 }
417#endif
418
419 const auto triangulation = ttkAlgorithm::GetTriangulation(input);
420 if(triangulation == nullptr) {
421 this->printErr("Triangulation is null");
422 return 0;
423 }
424 this->preconditionTriangulation(triangulation);
425
426 const auto inputScalars = this->GetInputArrayToProcess(0, inputVector);
427
428#ifndef TTK_ENABLE_KAMIKAZE
429 if(inputScalars == nullptr) {
430 this->printErr("wrong scalars.");
431 return -1;
432 }
433#endif
434
435 auto inputOffsets = ttkAlgorithm::GetOrderArray(
436 input, 0, 1, this->ForceInputOffsetScalarField);
437
438#ifndef TTK_ENABLE_KAMIKAZE
439 if(inputOffsets == nullptr) {
440 this->printErr("wrong offsets.");
441 return -1;
442 }
443 if(inputOffsets->GetDataType() != VTK_INT
444 and inputOffsets->GetDataType() != VTK_ID_TYPE) {
445 this->printErr("input offset field type not supported.");
446 return -1;
447 }
448#endif
449
450 this->printMsg("Launching computation on field `"
451 + std::string(inputScalars->GetName()) + "'...");
452
453 // morse complexes
454 const SimplexId numberOfVertices = triangulation->getNumberOfVertices();
455#ifndef TTK_ENABLE_KAMIKAZE
456 if(!numberOfVertices) {
457 this->printErr("Input has no vertices.");
458 return -1;
459 }
460#endif
461
462 vtkNew<ttkSimplexIdTypeArray> ascendingManifold{};
463 vtkNew<ttkSimplexIdTypeArray> descendingManifold{};
464 vtkNew<ttkSimplexIdTypeArray> morseSmaleManifold{};
465#ifndef TTK_ENABLE_KAMIKAZE
466 if(!ascendingManifold || !descendingManifold || !morseSmaleManifold) {
467 this->printErr("Manifold vtkDataArray allocation problem.");
468 return -1;
469 }
470#endif
471 ascendingManifold->SetNumberOfComponents(1);
472 ascendingManifold->SetNumberOfTuples(numberOfVertices);
473 ascendingManifold->SetName(ttk::MorseSmaleAscendingName);
474
475 descendingManifold->SetNumberOfComponents(1);
476 descendingManifold->SetNumberOfTuples(numberOfVertices);
477 descendingManifold->SetName(ttk::MorseSmaleDescendingName);
478
479 morseSmaleManifold->SetNumberOfComponents(1);
480 morseSmaleManifold->SetNumberOfTuples(numberOfVertices);
481 morseSmaleManifold->SetName(ttk::MorseSmaleManifoldName);
482
483 this->segmentations_ = {ttkUtils::GetPointer<SimplexId>(ascendingManifold),
484 ttkUtils::GetPointer<SimplexId>(descendingManifold),
485 ttkUtils::GetPointer<SimplexId>(morseSmaleManifold)};
486
490
491 int ret{};
492
494 inputScalars->GetDataType(), triangulation->getType(),
495 (ret = dispatch<VTK_TT, TTK_TT>(
496 inputScalars, outputCriticalPoints, outputSeparatrices1,
497 outputSeparatrices2, ttkUtils::GetPointer<SimplexId>(inputOffsets),
498 *static_cast<TTK_TT *>(triangulation->getData()))));
499
500 if(ret != 0) {
501 return -1;
502 }
503
504 outputMorseComplexes->ShallowCopy(input);
505 // morse complexes
507 vtkPointData *pointData = outputMorseComplexes->GetPointData();
508#ifndef TTK_ENABLE_KAMIKAZE
509 if(!pointData) {
510 this->printErr("outputMorseComplexes has no point data.");
511 return -1;
512 }
513#endif
514
515 if(ComputeDescendingSegmentation)
516 pointData->AddArray(descendingManifold);
518 pointData->AddArray(ascendingManifold);
521 pointData->AddArray(morseSmaleManifold);
522 }
523
524 return !ret;
525}
#define ttkNotUsed(x)
Mark function/method parameters that are not used in the function body at all.
Definition: BaseClass.h:47
static vtkInformationIntegerKey * SAME_DATA_TYPE_AS_INPUT_PORT()
vtkDataArray * GetOrderArray(vtkDataSet *const inputData, const int scalarArrayIdx, const int orderArrayIdx=0, const bool enforceOrderArrayIdx=false)
ttk::Triangulation * GetTriangulation(vtkDataSet *dataSet)
TTK VTK-filter that wraps the morseSmaleComplex processing package.
int dispatch(vtkDataArray *const inputScalars, vtkPolyData *const outputCriticalPoints, vtkPolyData *const outputSeparatrices1, vtkPolyData *const outputSeparatrices2, const SimplexId *const inputOffsets, const triangulationType &triangulation)
int FillInputPortInformation(int port, vtkInformation *info) override
int RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) override
int FillOutputPortInformation(int port, vtkInformation *info) override
static int CellVertexFromPoints(vtkDataSet *const dataSet, vtkPoints *const points)
Definition: ttkUtils.cpp:327
static void SetVoidArray(vtkDataArray *array, void *data, vtkIdType size, int save)
Definition: ttkUtils.cpp:279
void setDebugMsgPrefix(const std::string &prefix)
Definition: Debug.h:364
int printMsg(const std::string &msg, const debug::Priority &priority=debug::Priority::INFO, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cout) const
Definition: Debug.h:118
int printErr(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
Definition: Debug.h:149
void setSaddleConnectorsPersistenceThreshold(const double threshold)
void preconditionTriangulation(AbstractTriangulation *const data)
void setReturnSaddleConnectors(const bool state)
int execute(OutputCriticalPoints &outCP, Output1Separatrices &outSeps1, Output2Separatrices &outSeps2, OutputManifold &outManifold, const dataType *const scalars, const size_t scalarsMTime, const SimplexId *const offsets, const triangulationType &triangulation)
const char MorseSmaleDestinationIdName[]
Definition: DataTypes.h:53
const char MorseSmaleSeparatrixDifferenceName[]
Definition: DataTypes.h:59
const char MorseSmaleManifoldName[]
Definition: DataTypes.h:64
const char MorseSmaleSeparatrixMaximumName[]
Definition: DataTypes.h:56
const char MorseSmaleSourceIdName[]
Definition: DataTypes.h:52
const char MorseSmaleAscendingName[]
Definition: DataTypes.h:62
const char MorseSmaleCellDimensionName[]
Definition: DataTypes.h:48
const char MorseSmaleDescendingName[]
Definition: DataTypes.h:63
const char MorseSmaleCriticalPointsOnBoundaryName[]
Definition: DataTypes.h:61
const char MorseSmaleCellIdName[]
Definition: DataTypes.h:49
const char MorseSmaleSeparatrixTypeName[]
Definition: DataTypes.h:55
const char MorseSmaleManifoldSizeName[]
Definition: DataTypes.h:51
const char MorseSmaleBoundaryName[]
Definition: DataTypes.h:50
const char VertexScalarFieldName[]
default name for vertex scalar field
Definition: DataTypes.h:35
const char MorseSmaleSeparatrixMinimumName[]
Definition: DataTypes.h:57
const char MorseSmaleSeparatrixIdName[]
Definition: DataTypes.h:54
const char MaskScalarFieldName[]
default name for mask scalar field
Definition: DataTypes.h:32
std::vector< ttk::SimplexId > destinationIds_
std::vector< ttk::SimplexId > separatrixIds_
struct ttk::MorseSmaleComplex::Output1Separatrices::@1 cl
std::vector< ttk::SimplexId > connectivity_
std::vector< ttk::SimplexId > sourceIds_
struct ttk::MorseSmaleComplex::Output1Separatrices::@0 pt
struct ttk::MorseSmaleComplex::Output2Separatrices::@2 pt
std::vector< ttk::SimplexId > sourceIds_
struct ttk::MorseSmaleComplex::Output2Separatrices::@3 cl
std::vector< ttk::SimplexId > connectivity_
std::vector< ttk::SimplexId > separatrixIds_
std::vector< std::array< float, 3 > > points_
#define ttkVtkTemplateMacro(dataType, triangulationType, call)
Definition: ttkMacros.h:69
vtkStandardNewMacro(ttkMorseSmaleComplex)
void setArray(vtkArrayType &vtkArray, vectorType &vector)