TTK
Loading...
Searching...
No Matches
ttkContourForests.cpp
Go to the documentation of this file.
1#include <vtkAppendPolyData.h>
2#include <vtkCellArray.h>
3#include <vtkCellData.h>
4#include <vtkDataSet.h>
5#include <vtkDoubleArray.h>
6#include <vtkGenericCell.h>
7#include <vtkInformation.h>
8#include <vtkIntArray.h>
9#include <vtkLine.h>
10#include <vtkLineSource.h>
11#include <vtkNew.h>
12#include <vtkObjectFactory.h>
13#include <vtkPointData.h>
14
15#include "ttkContourForests.h"
16
17#include <ttkMacros.h>
18#include <ttkUtils.h>
19
20using namespace std;
21using namespace ttk;
22using namespace cf;
23
25
27 // VTK Interface //
28 this->SetNumberOfInputPorts(1);
29 this->SetNumberOfOutputPorts(3);
30
31 vtkWarningMacro(
32 "Contour Forests is deprecated, please use FTM Tree instead.");
33}
34
36 samples_.clear();
37 barycenters_.clear();
38
39 skeletonNodes_->Delete();
40 skeletonNodes_ = vtkPolyData::New();
41 skeletonArcs_->Delete();
42 skeletonArcs_ = vtkPolyData::New();
43}
44
46 segmentation_->Delete();
47}
48
50 tree_ = nullptr;
51}
52
54 vtkInformation *info) {
55 if(port == 0) {
56 info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkDataSet");
57 return 1;
58 }
59 return 0;
60}
61
63 vtkInformation *info) {
64 if(port == 0 || port == 1) {
65 info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkPolyData");
66 return 1;
67 } else if(port == 2) {
69 return 1;
70 }
71 return 0;
72}
73
75 toComputeSkeleton_ = true;
76 toComputeContourTree_ = true;
77 ttkAlgorithm::Modified();
78}
79
81 toUpdateVertexSoSoffsets_ = true;
82 toComputeContourTree_ = true;
83 toUpdateTree_ = true;
84 toComputeSkeleton_ = true;
85 toComputeSegmentation_ = true;
86
87 ForceInputOffsetScalarField = onOff;
88 Modified();
89}
90
92 if(treeType >= 0 && treeType <= 2) {
93 toUpdateTree_ = true;
94 if(treeType_ == TreeType::Contour
95 || static_cast<TreeType>(treeType) == TreeType::Contour) {
96 toComputeContourTree_ = true;
97 }
98
99 toComputeSkeleton_ = true;
100 toComputeSegmentation_ = true;
101
102 treeType_ = static_cast<TreeType>(treeType);
103
104 Modified();
105 }
106}
107
109 toComputeSkeleton_ = true;
110
111 showMin_ = state;
112 Modified();
113}
114
116 toComputeSkeleton_ = true;
117
118 showMax_ = state;
119 Modified();
120}
121
123 toComputeSkeleton_ = true;
124
125 showSaddle1_ = state;
126 Modified();
127}
128
130 toComputeSkeleton_ = true;
131
132 showSaddle2_ = state;
133 Modified();
134}
135
137 toComputeSkeleton_ = true;
138
139 showArc_ = state;
140 Modified();
141}
142
143void ttkContourForests::SetArcResolution(int arcResolution) {
144 if(arcResolution >= 0) {
145 toComputeSkeleton_ = true;
146
147 arcResolution_ = arcResolution;
148 Modified();
149 }
150}
151
153 partitionNum_ = partitionNum;
154
155 toComputeContourTree_ = true;
156 toComputeSkeleton_ = true;
157 toUpdateTree_ = true;
158 Modified();
159}
160
162 lessPartition_ = l;
163 Modified();
164}
165
166void ttkContourForests::SetSkeletonSmoothing(double skeletonSmoothing) {
167 if(skeletonSmoothing >= 0) {
168 toComputeSkeleton_ = true;
169
170 skeletonSmoothing_ = skeletonSmoothing;
171 Modified();
172 }
173}
174
176 simplificationType_ = type;
177 Modified();
178}
179
181 double simplificationThreshold) {
182 if(simplificationThreshold >= 0.0 && simplificationThreshold <= 1.0) {
183 simplificationThresholdBuffer_ = simplificationThreshold;
184 toComputeContourTree_ = true;
185 toUpdateTree_ = true;
186 toComputeSkeleton_ = true;
187 toComputeSegmentation_ = true;
188
189 Modified();
190 }
191}
192
193bool ttkContourForests::isCoincident(float p1[], double p2[]) {
194 double sPrev[3];
195 double sNext[3];
196 for(unsigned int k = 0; k < 3; k++) {
197 sPrev[k] = p2[k] - p1[k];
198 sNext[k] = sPrev[k];
199 }
200
201 return (vtkMath::Normalize(sNext) == 0.0);
202}
203
204bool ttkContourForests::isCoincident(double p1[], double p2[]) {
205 double sPrev[3];
206 double sNext[3];
207 for(unsigned int k = 0; k < 3; k++) {
208 sPrev[k] = p2[k] - p1[k];
209 sNext[k] = sPrev[k];
210 }
211
212 return (vtkMath::Normalize(sNext) == 0.0);
213}
214
216 vtkNew<vtkAppendPolyData> app{};
217
218 vtkDoubleArray *scalars{};
219 ttkSimplexIdTypeArray *identifierScalars{};
220 vtkIntArray *typeScalars{};
221 ttkSimplexIdTypeArray *sizeScalars{};
222 vtkDoubleArray *spanScalars{};
223 int const type = static_cast<int>(TreeComponent::Arc);
224
225 float point1[3];
226 vector<double> point2(3);
227 // get skeleton scalars
228 vector<vector<double>> skeletonScalars{};
229 getSkeletonScalars(vertexScalars_, skeletonScalars);
230
231 double inputScalar;
232 SuperArc *a;
233 SimplexId regionSize;
234 double regionSpan;
235 SimplexId currentZone = 0;
236 SimplexId regionId;
237
238 for(SimplexId i = 0; i < (SimplexId)tree_->getNumberOfSuperArcs(); ++i) {
239 a = tree_->getSuperArc(i);
240
241 if(a->isVisible()) {
242 SimplexId const upNodeId = tree_->getSuperArc(i)->getUpNodeId();
243 SimplexId const upVertex = tree_->getNode(upNodeId)->getVertexId();
244 float coordUp[3];
245 triangulation_->getVertexPoint(
246 upVertex, coordUp[0], coordUp[1], coordUp[2]);
247
248 SimplexId const downNodeId = tree_->getSuperArc(i)->getDownNodeId();
249 SimplexId const downVertex = tree_->getNode(downNodeId)->getVertexId();
250 float coordDown[3];
251 triangulation_->getVertexPoint(
252 downVertex, coordDown[0], coordDown[1], coordDown[2]);
253
254 regionSize = tree_->getNumberOfVisibleRegularNode(i);
255 regionSpan = Geometry::distance(coordUp, coordDown, 3);
256 regionId = currentZone++;
257
258 // Line //
259 if(barycenters_[static_cast<int>(treeType_)][i].size()) {
260 // init: min
261 SimplexId downNodeVId;
262 if(treeType_ == TreeType::Split)
263 downNodeVId = tree_->getNode(a->getUpNodeId())->getVertexId();
264 else
265 downNodeVId = tree_->getNode(a->getDownNodeId())->getVertexId();
266
267 triangulation_->getVertexPoint(
268 downNodeVId, point1[0], point1[1], point1[2]);
271 line->SetPoint1(point1);
272
273 const auto nbBarycenter
274 = barycenters_[static_cast<int>(treeType_)][i].size();
275 for(unsigned int j = 0; j < nbBarycenter; ++j) {
276 point2 = barycenters_[static_cast<int>(treeType_)][i][j];
277 line->SetPoint2(point2.data());
278
279 if(!isCoincident(point1, point2.data())) {
280 line->Update();
281 vtkPolyData *lineData = line->GetOutput();
282
283 // Point data //
284 {
285 inputScalar = skeletonScalars[i][j];
286
287 scalars = vtkDoubleArray::New();
288 scalars->SetName(vtkInputScalars_->GetName());
289 for(unsigned int k = 0; k < 2; ++k)
290 scalars->InsertTuple1(k, inputScalar);
291 lineData->GetPointData()->AddArray(scalars);
292 scalars->Delete();
293 }
294
295 // Cell data //
296 // Identifier
297 identifierScalars = ttkSimplexIdTypeArray::New();
298 identifierScalars->SetName("SegmentationId");
299 for(unsigned int k = 0; k < 2; ++k)
300 identifierScalars->InsertTuple1(k, regionId);
301 lineData->GetCellData()->AddArray(identifierScalars);
302 identifierScalars->Delete();
303 // Type
304 typeScalars = vtkIntArray::New();
305 typeScalars->SetName("Type");
306 for(unsigned int k = 0; k < 2; ++k)
307 typeScalars->InsertTuple1(k, type);
308 lineData->GetCellData()->AddArray(typeScalars);
309 typeScalars->Delete();
310 // Size
311 sizeScalars = ttkSimplexIdTypeArray::New();
312 sizeScalars->SetName("RegionSize");
313 for(unsigned int k = 0; k < 2; ++k)
314 sizeScalars->InsertTuple1(k, regionSize);
315 lineData->GetCellData()->AddArray(sizeScalars);
316 sizeScalars->Delete();
317 // Span
318 spanScalars = vtkDoubleArray::New();
319 spanScalars->SetName("RegionSpan");
320 for(unsigned int k = 0; k < 2; ++k)
321 spanScalars->InsertTuple1(k, regionSpan);
322 lineData->GetCellData()->AddArray(spanScalars);
323 spanScalars->Delete();
324
325 app->AddInputData(lineData);
326 }
327
329 line->SetPoint1(point2.data());
330 }
331
332 // end: max
333 SimplexId upNodeVId;
334 if(treeType_ == TreeType::Split)
335 upNodeVId = tree_->getNode(a->getDownNodeId())->getVertexId();
336 else
337 upNodeVId = tree_->getNode(a->getUpNodeId())->getVertexId();
338
339 std::array<float, 3> pt{};
340 triangulation_->getVertexPoint(upNodeVId, pt[0], pt[1], pt[2]);
341 point2[0] = pt[0];
342 point2[1] = pt[1];
343 point2[2] = pt[2];
344 line->SetPoint2(point2.data());
345
346 if(!isCoincident(point1, point2.data())) {
347 line->Update();
348 vtkPolyData *lineData = line->GetOutput();
349
350 // Point data //
351 {
352 inputScalar
353 = skeletonScalars[i][barycenters_[static_cast<int>(treeType_)][i]
354 .size()];
355
356 scalars = vtkDoubleArray::New();
357 scalars->SetName(vtkInputScalars_->GetName());
358 for(unsigned int k = 0; k < 2; ++k)
359 scalars->InsertTuple1(k, inputScalar);
360 lineData->GetPointData()->AddArray(scalars);
361 scalars->Delete();
362 }
363
364 // Cell data //
365 // Identifier
366 identifierScalars = ttkSimplexIdTypeArray::New();
367 identifierScalars->SetName("SegmentationId");
368 for(unsigned int k = 0; k < 2; ++k)
369 identifierScalars->InsertTuple1(k, regionId);
370 lineData->GetCellData()->AddArray(identifierScalars);
371 identifierScalars->Delete();
372 // Type
373 typeScalars = vtkIntArray::New();
374 typeScalars->SetName("Type");
375 for(unsigned int k = 0; k < 2; ++k)
376 typeScalars->InsertTuple1(k, type);
377 lineData->GetCellData()->AddArray(typeScalars);
378 typeScalars->Delete();
379 // Size
380 sizeScalars = ttkSimplexIdTypeArray::New();
381 sizeScalars->SetName("RegionSize");
382 for(unsigned int k = 0; k < 2; ++k)
383 sizeScalars->InsertTuple1(k, regionSize);
384 lineData->GetCellData()->AddArray(sizeScalars);
385 sizeScalars->Delete();
386 // Span
387 spanScalars = vtkDoubleArray::New();
388 spanScalars->SetName("RegionSpan");
389 for(unsigned int k = 0; k < 2; ++k)
390 spanScalars->InsertTuple1(k, regionSpan);
391 lineData->GetCellData()->AddArray(spanScalars);
392 spanScalars->Delete();
393
394 app->AddInputData(lineData);
395 }
396 } else {
397 vtkNew<vtkLineSource> line{};
398
399 SimplexId const downNodeVId
400 = tree_->getNode(a->getDownNodeId())->getVertexId();
401 triangulation_->getVertexPoint(
402 downNodeVId, point1[0], point1[1], point1[2]);
403 line->SetPoint1(point1);
404
405 SimplexId const upNodeVId
406 = tree_->getNode(a->getUpNodeId())->getVertexId();
407 std::array<float, 3> pt{};
408 triangulation_->getVertexPoint(upNodeVId, pt[0], pt[1], pt[2]);
409 point2[0] = pt[0];
410 point2[1] = pt[1];
411 point2[2] = pt[2];
412 line->SetPoint2(point2.data());
413
414 if(!isCoincident(point1, point2.data())) {
415 line->Update();
416 vtkPolyData *lineData = line->GetOutput();
417
418 // Point data //
419 {
420 inputScalar = skeletonScalars[i][0];
421
422 scalars = vtkDoubleArray::New();
423 scalars->SetName(vtkInputScalars_->GetName());
424 for(unsigned int k = 0; k < 2; ++k)
425 scalars->InsertTuple1(k, inputScalar);
426 lineData->GetPointData()->AddArray(scalars);
427 scalars->Delete();
428 }
429
430 // Cell data //
431 // Identifier
432 identifierScalars = ttkSimplexIdTypeArray::New();
433 identifierScalars->SetName("SegmentationId");
434 for(int k = 0; k < 2; ++k)
435 identifierScalars->InsertTuple1(k, regionId);
436 lineData->GetCellData()->AddArray(identifierScalars);
437 identifierScalars->Delete();
438 // Type
439 typeScalars = vtkIntArray::New();
440 typeScalars->SetName("Type");
441 for(unsigned int k = 0; k < 2; ++k)
442 typeScalars->InsertTuple1(k, type);
443 lineData->GetCellData()->AddArray(typeScalars);
444 typeScalars->Delete();
445 // Size
446 sizeScalars = ttkSimplexIdTypeArray::New();
447 sizeScalars->SetName("RegionSize");
448 for(unsigned int k = 0; k < 2; ++k)
449 sizeScalars->InsertTuple1(k, regionSize);
450 lineData->GetCellData()->AddArray(sizeScalars);
451 sizeScalars->Delete();
452 // Span
453 spanScalars = vtkDoubleArray::New();
454 spanScalars->SetName("RegionSpan");
455 for(unsigned int k = 0; k < 2; ++k)
456 spanScalars->InsertTuple1(k, regionSpan);
457 lineData->GetCellData()->AddArray(spanScalars);
458 spanScalars->Delete();
459
460 app->AddInputData(lineData);
461 }
462 }
463 } else {
464 // cout << " pruned _ :" <<
465 // tree_->getNode(a->getDownNodeId())->getVertexId() << " - "
466 //<< tree_->getNode(a->getUpNodeId())->getVertexId() << endl;
467 }
468 }
469
470 app->Update();
471 skeletonArcs_->ShallowCopy(app->GetOutput());
472}
473
475 const vector<double> &scalars,
476 vector<vector<double>> &skeletonScalars) const {
477 skeletonScalars.clear();
478 skeletonScalars.resize(tree_->getNumberOfSuperArcs());
479
480 SimplexId nodeId;
481 SimplexId vertexId;
482
483 double f;
484 double f0;
485 double f1;
486 double fmin;
487 double fmax;
488 SimplexId nodeMinId;
489 SimplexId nodeMaxId;
490 SimplexId nodeMinVId;
491 SimplexId nodeMaxVId;
492 const SuperArc *a;
493 for(SimplexId i = 0; i < (SimplexId)tree_->getNumberOfSuperArcs(); ++i) {
494 a = tree_->getSuperArc(i);
495
496 if(!a->isPruned()) {
497 if(treeType_ == TreeType::Split) {
498 nodeMinId = a->getUpNodeId();
499 nodeMaxId = a->getDownNodeId();
500 } else {
501 nodeMaxId = a->getUpNodeId();
502 nodeMinId = a->getDownNodeId();
503 }
504
505 nodeMaxVId = tree_->getNode(nodeMaxId)->getVertexId();
506 nodeMinVId = tree_->getNode(nodeMinId)->getVertexId();
507
508 fmax = scalars[nodeMaxVId];
509 fmin = scalars[nodeMinVId];
510
511 // init: min
512 f0 = fmin;
513
514 // iteration
515 for(SimplexId j = 0;
516 j < (SimplexId)samples_[static_cast<int>(treeType_)][i].size(); ++j) {
517 const vector<SimplexId> &sample
518 = samples_[static_cast<int>(treeType_)][i][j];
519
520 f = 0;
521 for(SimplexId k = 0; k < (SimplexId)sample.size(); ++k) {
522 nodeId = sample[k];
523 vertexId = nodeId;
524 f += scalars[vertexId];
525 }
526 if(sample.size()) {
527 f /= sample.size();
528
529 f1 = f;
530 // update the arc
531 skeletonScalars[i].push_back((f0 + f1) / 2);
532 f0 = f1;
533 }
534 }
535
536 // end: max
537 f1 = fmax;
538
539 // update the arc
540 skeletonScalars[i].push_back((f0 + f1) / 2);
541 }
542 }
543
544 return 0;
545}
546
548 vtkNew<vtkPoints> points{};
549 float point[3];
550
551 double scalar{};
552 vtkNew<vtkDoubleArray> scalars{};
553 scalars->SetName(vtkInputScalars_->GetName());
554
555 vtkNew<ttkSimplexIdTypeArray> nodeIdentifierScalars{};
556 nodeIdentifierScalars->SetName("NodeIdentifier");
557
558 vtkNew<ttkSimplexIdTypeArray> vertexIdentifierScalars{};
559 vertexIdentifierScalars->SetName(ttk::VertexScalarFieldName);
560
561 int type{};
562 vtkNew<vtkIntArray> nodeTypeScalars{};
563 nodeTypeScalars->SetName("CriticalType");
564
565 vtkNew<ttkSimplexIdTypeArray> regionSizeScalars{};
566 regionSizeScalars->SetName("RegionSize");
567
568 SimplexId identifier{};
569 for(unsigned i = 0; i < criticalPoints_.size(); ++i) {
570 SimplexId const nodeId = criticalPoints_[i];
571 if(tree_->getNode(nodeId)->isHidden())
572 continue;
573 SimplexId const vertexId = tree_->getNode(nodeId)->getVertexId();
574 CriticalType const nodeType = getNodeType(nodeId);
575
576 if((nodeType == CriticalType::Local_minimum and showMin_)
577 or (nodeType == CriticalType::Local_maximum and showMax_)
578 or (nodeType == CriticalType::Saddle1 and showSaddle1_)
579 or (nodeType == CriticalType::Saddle2 and showSaddle2_)
580 or ((showSaddle1_ and showSaddle2_)
581 and (nodeType == CriticalType::Regular
582 or nodeType == CriticalType::Degenerate))) {
583 // Positions
584 triangulation_->getVertexPoint(vertexId, point[0], point[1], point[2]);
585 points->InsertPoint(identifier, point);
586
587 // Scalars
588 scalar = vertexScalars_[vertexId];
589 scalars->InsertTuple1(identifier, scalar);
590
591 // NodeIdentifier
592 nodeIdentifierScalars->InsertTuple1(identifier, nodeId);
593
594 // VertexIdentifier
595 vertexIdentifierScalars->InsertTuple1(identifier, vertexId);
596
597 // Type
598 type = static_cast<int>(nodeType);
599 nodeTypeScalars->InsertTuple1(identifier, type);
600
601 // RegionSize
602 SimplexId regionSize = 0;
603 if(nodeType == CriticalType::Local_maximum) {
604 const SimplexId arcId = tree_->getNode(nodeId)->getDownSuperArcId(0);
605 regionSize = tree_->getSuperArc(arcId)->getNumberOfRegularNodes() + 1;
606 } else if(nodeType == CriticalType::Local_minimum) {
607 const SimplexId arcId = tree_->getNode(nodeId)->getUpSuperArcId(0);
608 regionSize = tree_->getSuperArc(arcId)->getNumberOfRegularNodes() + 1;
609 }
610 regionSizeScalars->InsertTuple1(identifier, regionSize);
611
612 ++identifier;
613 }
614 }
615 skeletonNodes_->SetPoints(points);
616 skeletonNodes_->GetPointData()->AddArray(scalars);
617 skeletonNodes_->GetPointData()->AddArray(nodeIdentifierScalars);
618 skeletonNodes_->GetPointData()->AddArray(vertexIdentifierScalars);
619 skeletonNodes_->GetPointData()->AddArray(nodeTypeScalars);
620 skeletonNodes_->GetPointData()->AddArray(regionSizeScalars);
621}
622
624 return getNodeType(id, treeType_, tree_);
625}
626
629 int upDegree{};
630 int downDegree{};
631 if(type == TreeType::Join || type == TreeType::Contour) {
632 upDegree = tree->getNode(id)->getUpValence();
633 downDegree = tree->getNode(id)->getDownValence();
634 } else {
635 downDegree = tree->getNode(id)->getUpValence();
636 upDegree = tree->getNode(id)->getDownValence();
637 }
638 int const degree = upDegree + downDegree;
639
640 // saddle point
641 if(degree > 1) {
642 if(upDegree == 2 && downDegree == 1)
643 return CriticalType::Saddle2;
644 else if(upDegree == 1 && downDegree == 2)
645 return CriticalType::Saddle1;
646 else if(upDegree == 1 && downDegree == 1)
647 return CriticalType::Regular;
648 else
649 return CriticalType::Degenerate;
650 }
651 // local extremum
652 else {
653 if(upDegree)
654 return CriticalType::Local_minimum;
655 else
656 return CriticalType::Local_maximum;
657 }
658}
659
661 vector<bool> isCriticalPoint(numberOfVertices_);
662
663 criticalPoints_.clear();
664 for(SimplexId i = 0; i < numberOfVertices_; ++i)
665 isCriticalPoint[i] = false;
666
667 // const int nbVert = triangulation_->getNumberOfOriginalVertices();
668
669 // looking for critical points
670 for(SimplexId i = 0; i < (SimplexId)tree_->getNumberOfSuperArcs(); ++i) {
671 auto a = tree_->getSuperArc(i);
672
673 if(!a->isPruned()) {
674 SimplexId const upId = a->getUpNodeId();
675 SimplexId const up_vId = tree_->getNode(upId)->getVertexId();
676 if(!isCriticalPoint[up_vId]) {
677 isCriticalPoint[up_vId] = true;
678 criticalPoints_.push_back(upId);
679 }
680
681 SimplexId const downId = a->getDownNodeId();
682 SimplexId const down_vId = tree_->getNode(downId)->getVertexId();
683 if(!isCriticalPoint[down_vId]) {
684 isCriticalPoint[down_vId] = true;
685 criticalPoints_.push_back(downId);
686 }
687 }
688 }
689 //{
690 // stringstream msg;
691 // msg << "[ttkContourForests] List of critical points :" << endl;
692 // for (unsigned int it = 0; it < criticalPoints_->size(); ++it)
693 // msg << "[ttkContourForests] NodeId:" << (*criticalPoints_)[it]
694 //<< ", VertexId:" << tree_->getNode(it)->getVertexId() << endl;
695 // dMsg(cout, msg.str(), advancedInfoMsg);
696 //}
697}
698
699int ttkContourForests::sample(unsigned int samplingLevel) {
700 samples_.resize(3);
701 samples_[static_cast<int>(treeType_)].resize(tree_->getNumberOfSuperArcs());
702 vector<vector<SimplexId>> sampleList(samplingLevel);
703
704 SuperArc *a;
705 for(SimplexId i = 0; i < (SimplexId)tree_->getNumberOfSuperArcs(); ++i) {
706 a = tree_->getSuperArc(i);
707
708 if(!a->isPruned()) {
709 for(unsigned int j = 0; j < samplingLevel; ++j) {
710 sampleList[j].clear();
711 }
712
713 double fmax, fmin;
714 SimplexId nodeMaxId, nodeMinId;
715 SimplexId nodeMaxVId, nodeMinVId;
716 double delta;
717 if(a->getNumberOfRegularNodes()) {
718 if(treeType_ == TreeType::Split) {
719 nodeMaxId = a->getDownNodeId();
720 nodeMinId = a->getUpNodeId();
721 } else {
722 nodeMaxId = a->getUpNodeId();
723 nodeMinId = a->getDownNodeId();
724 }
725
726 nodeMaxVId = tree_->getNode(nodeMaxId)->getVertexId();
727 nodeMinVId = tree_->getNode(nodeMinId)->getVertexId();
728
729 fmax = vertexScalars_[nodeMaxVId];
730 fmin = vertexScalars_[nodeMinVId];
731
732 delta = (fmax - fmin) / samplingLevel;
733
734 double f;
735 SimplexId nodeId;
736 SimplexId vertexId;
737 for(SimplexId j = 0; j < a->getNumberOfRegularNodes(); ++j) {
738 nodeId = a->getRegularNodeId(j);
739 if(a->isMasqued(j))
740 continue;
741 vertexId = nodeId;
742 f = vertexScalars_[vertexId];
743
744 for(unsigned int k = 0; k < samplingLevel; ++k) {
745 if(f <= (k + 1) * delta + fmin) {
746 sampleList[k].push_back(nodeId);
747 break;
748 }
749 }
750 }
751
752 // update the arc
753 for(SimplexId j = 0; j < (SimplexId)sampleList.size(); ++j)
754 samples_[static_cast<int>(treeType_)][i].push_back(sampleList[j]);
755 }
756 }
757 }
758
759 return 0;
760}
761
763 barycenters_.resize(3);
764 barycenters_[static_cast<int>(treeType_)].resize(
765 tree_->getNumberOfSuperArcs());
766 vector<float> barycenter(3);
767 SimplexId vertexId;
768
769 const SuperArc *a;
770 for(SimplexId i = 0; i < (SimplexId)tree_->getNumberOfSuperArcs(); ++i) {
771 a = tree_->getSuperArc(i);
772 if(!a->isPruned()) {
773 for(SimplexId j = 0;
774 j < (SimplexId)samples_[static_cast<int>(treeType_)][i].size(); ++j) {
775 vector<SimplexId> &sample = samples_[static_cast<int>(treeType_)][i][j];
776
777 for(unsigned int k = 0; k < 3; ++k)
778 barycenter[k] = 0;
779
780 for(SimplexId k = 0; k < (SimplexId)sample.size(); ++k) {
781 vertexId = sample[k];
782
783 float pt[3];
784 triangulation_->getVertexPoint(vertexId, pt[0], pt[1], pt[2]);
785 barycenter[0] += pt[0];
786 barycenter[1] += pt[1];
787 barycenter[2] += pt[2];
788 }
789 if(sample.size()) {
790 for(unsigned int k = 0; k < 3; ++k)
791 barycenter[k] /= sample.size();
792
793 // update the arc
794 unsigned int const nbBar
795 = barycenters_[static_cast<int>(treeType_)][i].size();
796 barycenters_[static_cast<int>(treeType_)][i].resize(nbBar + 1);
797 barycenters_[static_cast<int>(treeType_)][i][nbBar].resize(3);
798
799 for(unsigned int k = 0; k < 3; ++k)
800 barycenters_[static_cast<int>(treeType_)][i][nbBar][k]
801 = barycenter[k];
802 }
803 }
804 }
805 }
806
807 return 0;
808}
809
810void ttkContourForests::computeSkeleton(unsigned int arcRes) {
811 sample(arcRes);
813}
814
815void ttkContourForests::smoothSkeleton(unsigned int skeletonSmoothing) {
816 for(unsigned int i = 0; i < skeletonSmoothing; i++) {
817 for(SimplexId j = 0; j < (SimplexId)tree_->getNumberOfSuperArcs(); j++) {
818 if(!tree_->getSuperArc(j)->isPruned()) {
819 smooth(j, !(treeType_ == TreeType::Split));
820 }
821 }
822 }
823}
824
825void ttkContourForests::smooth(const SimplexId idArc, bool order) {
826 int const N = barycenters_[static_cast<int>(treeType_)][idArc].size();
827 if(N) {
828 // init //
829 vector<vector<double>> barycenterList(N);
830 for(unsigned int i = 0; i < barycenterList.size(); ++i)
831 barycenterList[i].resize(3);
832
833 SimplexId up_vId;
834 SimplexId down_vId;
835 if(order) {
836 up_vId = tree_->getNode(tree_->getSuperArc(idArc)->getUpNodeId())
837 ->getVertexId();
838 down_vId = tree_->getNode(tree_->getSuperArc(idArc)->getDownNodeId())
839 ->getVertexId();
840 } else {
841 down_vId = tree_->getNode(tree_->getSuperArc(idArc)->getUpNodeId())
842 ->getVertexId();
843 up_vId = tree_->getNode(tree_->getSuperArc(idArc)->getDownNodeId())
844 ->getVertexId();
845 }
846
847 std::array<float, 3> p0{};
848 std::array<float, 3> p1{};
849 triangulation_->getVertexPoint(down_vId, p0[0], p0[1], p0[2]);
850 triangulation_->getVertexPoint(up_vId, p1[0], p1[1], p1[2]);
851
852 // filtering //
853 if(N > 1) {
854 // first
855 for(unsigned int k = 0; k < 3; ++k)
856 barycenterList[0][k]
857 = (p0[k] + barycenters_[static_cast<int>(treeType_)][idArc][1][k])
858 * 0.5;
859
860 // main
861 for(int i = 1; i < N - 1; ++i) {
862 for(unsigned int k = 0; k < 3; ++k)
863 barycenterList[i][k]
864 = (barycenters_[static_cast<int>(treeType_)][idArc][i - 1][k]
865 + barycenters_[static_cast<int>(treeType_)][idArc][i + 1][k])
866 * 0.5;
867 }
868 // last
869 for(unsigned int k = 0; k < 3; ++k)
870 barycenterList[N - 1][k]
871 = (p1[k] + barycenters_[static_cast<int>(treeType_)][idArc][N - 1][k])
872 * 0.5;
873 } else {
874 for(unsigned int k = 0; k < 3; ++k)
875 barycenterList[0][k] = (p0[k] + p1[k]) * 0.5;
876 }
877
878 // copy //
879 for(int i = 0; i < N; ++i) {
880 for(unsigned int k = 0; k < 3; ++k)
881 barycenters_[static_cast<int>(treeType_)][idArc][i][k]
882 = barycenterList[i][k];
883 }
884 }
885}
886
888 Timer t;
889 computeSkeleton(arcResolution_);
890 smoothSkeleton(skeletonSmoothing_);
891
892 // nodes
893 if(showMin_ || showMax_ || showSaddle1_ || showSaddle2_)
895 else
896 skeletonNodes_->ShallowCopy(voidUnstructuredGrid_);
897
898 // arcs
899 if(showArc_)
901 else
902 skeletonArcs_->ShallowCopy(voidPolyData_);
903
904 // what is done is no longer to be done
905 toComputeSkeleton_ = false;
906
907 this->printMsg(
908 "Topological skeleton built", 1.0, t.getElapsedTime(), this->threadNumber_);
909 this->printMsg(std::vector<std::vector<std::string>>{
910 {"Arc resolution", std::to_string(arcResolution_)},
911 {"Smoothing", std::to_string(skeletonSmoothing_)}});
912}
913
914void ttkContourForests::getSegmentation(vtkDataSet *input) {
915 Timer t;
916
917 // field
918 SimplexId regionId{};
919 vtkNew<ttkSimplexIdTypeArray> scalarsRegionId{};
920 scalarsRegionId->SetName("SegmentationId");
921 scalarsRegionId->SetNumberOfTuples(vertexScalars_.size());
922
923 int regionType{};
924 vtkNew<vtkIntArray> scalarsRegionType{};
925 scalarsRegionType->SetName("RegionType");
926 scalarsRegionType->SetNumberOfTuples(vertexScalars_.size());
927
928 SimplexId regionSize{};
929 vtkNew<ttkSimplexIdTypeArray> scalarsRegionSize{};
930 scalarsRegionSize->SetName("RegionSize");
931 scalarsRegionSize->SetNumberOfTuples(vertexScalars_.size());
932
933 double regionSpan{};
934 vtkNew<vtkDoubleArray> scalarsRegionSpan{};
935 scalarsRegionSpan->SetName("RegionSpan");
936 scalarsRegionSpan->SetNumberOfTuples(vertexScalars_.size());
937
938 SimplexId currentZone{};
939
940 if(!segmentation_) {
941 segmentation_ = input->NewInstance();
942 segmentation_->ShallowCopy(input);
943 }
944
945 for(SimplexId i = 0; i < numberOfVertices_; i++) {
946 scalarsRegionId->SetTuple1(i, -1);
947 }
948
949 // nodes
950 for(SimplexId it = 0; it < (SimplexId)criticalPoints_.size(); ++it) {
951 SimplexId const nodeId = criticalPoints_[it];
952 SimplexId const vertexId = tree_->getNode(nodeId)->getVertexId();
953
954 // RegionType
955 regionType = -1;
956 scalarsRegionType->SetTuple1(vertexId, regionType);
957 }
958
959 // arcs
960 for(SimplexId i = 0; i < (SimplexId)tree_->getNumberOfSuperArcs(); ++i) {
961 auto a = tree_->getSuperArc(i);
962 if(a->isVisible()) {
963 SimplexId const upNodeId = tree_->getSuperArc(i)->getUpNodeId();
964 CriticalType const upNodeType = getNodeType(upNodeId);
965 SimplexId const upVertex = tree_->getNode(upNodeId)->getVertexId();
966 float coordUp[3];
967 triangulation_->getVertexPoint(
968 upVertex, coordUp[0], coordUp[1], coordUp[2]);
969
970 SimplexId const downNodeId = tree_->getSuperArc(i)->getDownNodeId();
971 CriticalType const downNodeType = getNodeType(downNodeId);
972 SimplexId const downVertex = tree_->getNode(downNodeId)->getVertexId();
973 float coordDown[3];
974 triangulation_->getVertexPoint(
975 downVertex, coordDown[0], coordDown[1], coordDown[2]);
976
977 regionSize = tree_->getNumberOfVisibleRegularNode(i);
978 regionSpan = Geometry::distance(coordUp, coordDown);
979 regionId = currentZone++;
980 // regionId = i;
981
982 // cout << "arc : " << tree_->printArc(i);
983 // cout << " span : " << regionSpan;
984 // cout << " coords : ";
985 // cout << coordDown[0] << ",";
986 // cout << coordDown[1] << ",";
987 // cout << coordDown[2] << " || ";
988 // cout << coordUp[0] << ",";
989 // cout << coordUp[1] << ",";
990 // cout << coordUp[2] << endl;
991
992 scalarsRegionId->SetTuple1(
993 tree_->getNode(downNodeId)->getVertexId(), regionId);
994 scalarsRegionId->SetTuple1(
995 tree_->getNode(upNodeId)->getVertexId(), regionId);
996
997 scalarsRegionSize->SetTuple1(
998 tree_->getNode(downNodeId)->getVertexId(), regionSize);
999 scalarsRegionSize->SetTuple1(
1000 tree_->getNode(upNodeId)->getVertexId(), regionSize);
1001
1002 scalarsRegionSpan->SetTuple1(
1003 tree_->getNode(downNodeId)->getVertexId(), regionSpan);
1004 scalarsRegionSpan->SetTuple1(
1005 tree_->getNode(upNodeId)->getVertexId(), regionSpan);
1006
1007 for(SimplexId j = 0; j < tree_->getSuperArc(i)->getNumberOfRegularNodes();
1008 ++j) {
1009 SimplexId const nodeId = tree_->getSuperArc(i)->getRegularNodeId(j);
1010 SimplexId const vertexId = nodeId;
1011 // cout << vertexId << ", ";
1012 if(tree_->getSuperArc(i)->isMasqued(j)) {
1013 // cout << vertexId << ", ";
1014 continue;
1015 }
1016
1017 // cout << vertexId << ", ";
1018 scalarsRegionId->SetTuple1(vertexId, regionId);
1019 scalarsRegionSize->SetTuple1(vertexId, regionSize);
1020 scalarsRegionSpan->SetTuple1(vertexId, regionSpan);
1021 }
1022 // cout << endl;
1023
1024 // RegionType
1025 if((upNodeType == CriticalType::Local_minimum
1026 && downNodeType == CriticalType::Local_maximum)
1027 || (upNodeType == CriticalType::Local_minimum
1028 || downNodeType == CriticalType::Local_minimum))
1029 regionType = static_cast<int>(ArcType::Min_arc);
1030 else if(upNodeType == CriticalType::Local_maximum
1031 || downNodeType == CriticalType::Local_maximum)
1032 regionType = static_cast<int>(ArcType::Max_arc);
1033 else if(upNodeType == CriticalType::Saddle1
1034 && downNodeType == CriticalType::Saddle1)
1035 regionType = static_cast<int>(ArcType::Saddle1_arc);
1036 else if(upNodeType == CriticalType::Saddle2
1037 && downNodeType == CriticalType::Saddle2)
1038 regionType = static_cast<int>(ArcType::Saddle2_arc);
1039 else
1040 regionType = static_cast<int>(ArcType::Saddle1_saddle2_arc);
1041
1042 for(SimplexId j = 0; j < tree_->getSuperArc(i)->getNumberOfRegularNodes();
1043 ++j) {
1044 SimplexId const nodeId = tree_->getSuperArc(i)->getRegularNodeId(j);
1045 if(tree_->getSuperArc(i)->isMasqued(j)) {
1046 // Ignore masqued ones
1047 continue;
1048 }
1049 SimplexId const vertexId = nodeId;
1050 scalarsRegionType->SetTuple1(vertexId, regionType);
1051 }
1052 }
1053 }
1054
1055 // output
1056 segmentation_->GetPointData()->AddArray(scalarsRegionId);
1057 segmentation_->GetPointData()->AddArray(scalarsRegionType);
1058 segmentation_->GetPointData()->AddArray(scalarsRegionSize);
1059 segmentation_->GetPointData()->AddArray(scalarsRegionSpan);
1060
1061 this->printMsg("Topological segmentation built", 1.0, t.getElapsedTime(),
1062 this->threadNumber_);
1063 this->printMsg(std::vector<std::vector<std::string>>{
1064 {"Region type", std::to_string(scalarsRegionType->GetNumberOfTuples())},
1065 {"Segmentation Id", std::to_string(scalarsRegionId->GetNumberOfTuples())}});
1066
1067 toComputeSegmentation_ = false;
1068}
1069
1071 // sequential params
1072 this->preconditionTriangulation(triangulation_);
1073 this->setVertexScalars(ttkUtils::GetVoidPointer(vtkInputScalars_));
1074 this->setVertexSoSoffsets(vertexSoSoffsets_);
1075
1076 this->setTreeType(treeType_);
1077 // parallel params
1078 this->setLessPartition(lessPartition_);
1080 this->setPartitionNum(partitionNum_);
1081 // simplification params
1082 this->setSimplificationMethod(simplificationType_);
1083 this->setSimplificationThreshold(simplificationThreshold_);
1084 // build
1085 ttkVtkTemplateMacro(vtkInputScalars_->GetDataType(),
1086 triangulation_->getType(),
1087 (this->build<VTK_TT, TTK_TT *>(
1088 static_cast<TTK_TT *>(triangulation_->getData()))));
1089
1090 // what is done is no longer to be done
1091 toComputeContourTree_ = false;
1092}
1093
1095 // polymorphic tree
1096 switch(treeType_) {
1097 case TreeType::Join:
1098 tree_ = this->getJoinTree();
1099 break;
1100 case TreeType::Split:
1101 tree_ = this->getSplitTree();
1102 break;
1103 case TreeType::JoinAndSplit:
1104 tree_ = this->getJoinTree();
1105 tree_ = this->getSplitTree();
1106 break;
1107 case TreeType::Contour:
1108 tree_ = this;
1109 break;
1110 }
1111
1113
1114 toUpdateTree_ = false;
1115}
1116
1117int ttkContourForests::RequestData(vtkInformation *ttkNotUsed(request),
1118 vtkInformationVector **inputVector,
1119 vtkInformationVector *outputVector) {
1120 vtkWarningMacro(
1121 "DEPRECATED This plugin will be removed in a future release, please use "
1122 "FTM instead for contour trees and FTR for Reeb graphs.");
1123
1124 const auto input = vtkDataSet::GetData(inputVector[0]);
1125 auto outputSkeletonNodes = vtkPolyData::GetData(outputVector, 0);
1126 auto outputSkeletonArcs = vtkPolyData::GetData(outputVector, 1);
1127 auto outputSegmentation = vtkDataSet::GetData(outputVector, 2);
1128
1129#ifndef TTK_ENABLE_KAMIKAZE
1130 if(!input) {
1131 this->printErr("Input pointer is NULL.");
1132 return -1;
1133 }
1134
1135 if(!outputSkeletonNodes || !outputSkeletonArcs || !outputSegmentation) {
1136 this->printErr("Output pointer is NULL.");
1137 return -1;
1138 }
1139
1140 if(!input->GetNumberOfPoints()) {
1141 this->printErr("Input has no point.");
1142 return -1;
1143 }
1144#endif
1145
1146 triangulation_ = ttkAlgorithm::GetTriangulation(input);
1147
1148#ifndef TTK_ENABLE_KAMIKAZE
1149 if(!triangulation_) {
1150 this->printErr("Input triangulation is NULL.");
1151 return -1;
1152 }
1153#endif
1154
1155 varyingMesh_ = false;
1156 if(triangulation_->isEmpty())
1157 varyingMesh_ = true;
1158
1159 // init
1160 if(varyingMesh_ || !numberOfVertices_) {
1161 numberOfVertices_ = input->GetNumberOfPoints();
1162 }
1163
1164 if(varyingMesh_) {
1165 segmentation_ = input->NewInstance();
1166 if(segmentation_ != nullptr) {
1167 segmentation_->ShallowCopy(input);
1168 }
1169 }
1170
1171#ifndef TTK_ENABLE_KAMIKAZE
1172 if(!input->GetPointData()) {
1173 this->printErr("Input has no point data.");
1174 return -2;
1175 }
1176#endif
1177
1178 // scalars
1179 vtkInputScalars_ = this->GetInputArrayToProcess(0, input);
1180
1181#ifndef TTK_ENABLE_KAMIKAZE
1182 if(!vtkInputScalars_) {
1183 this->printErr("Input scalar is NULL.");
1184 return -2;
1185 }
1186#endif
1187
1188 varyingDataValues_ = (vtkInputScalars_->GetMTime() > GetMTime());
1189 if(input->GetPointData()) {
1190
1191 vertexScalars_.resize(numberOfVertices_);
1192 for(SimplexId j = 0; j < numberOfVertices_; ++j) {
1193 vertexScalars_[j] = vtkInputScalars_->GetTuple1(j);
1194 }
1195 }
1196
1197 auto result
1198 = std::minmax_element(vertexScalars_.begin(), vertexScalars_.end());
1199 double const scalarMin = *result.first;
1200 double const scalarMax = *result.second;
1201 deltaScalar_ = (scalarMax - scalarMin);
1202
1203 // offsets
1204 if(varyingMesh_ || varyingDataValues_ || vertexSoSoffsets_ == nullptr) {
1205
1206 const auto offsets = this->GetOrderArray(
1207 input, 0, triangulation_, false, 1, ForceInputOffsetScalarField);
1208
1209 if(offsets != nullptr) {
1210 vertexSoSoffsets_
1211 = static_cast<SimplexId *>(ttkUtils::GetVoidPointer(offsets));
1212 }
1213
1214 toUpdateVertexSoSoffsets_ = false;
1215 }
1216
1217 if(varyingMesh_ || varyingDataValues_ || !isLoaded_) {
1218 this->printMsg("Convenient data storage loaded", debug::Priority::DETAIL);
1219 this->printMsg(
1220 std::vector<std::vector<std::string>>{
1221 {"#Tuples", std::to_string(vertexScalars_.size())},
1222 {"#Vertices", std::to_string(numberOfVertices_)},
1223 {"Min", std::to_string(scalarMin)},
1224 {"Max", std::to_string(scalarMax)},
1225 },
1226 debug::Priority::DETAIL);
1227 }
1228
1229 this->printMsg("Launching computation for field `"
1230 + std::string{vtkInputScalars_->GetName()} + "'...");
1231
1232 isLoaded_ = true;
1233
1234 if(simplificationType_ == 0) {
1235 simplificationThreshold_ = simplificationThresholdBuffer_ * deltaScalar_;
1236 } else if(simplificationType_ == 1) {
1237 double coord0[3], coord1[3], spanTotal;
1238 double *bounds = input->GetBounds();
1239 coord0[0] = bounds[0];
1240 coord1[0] = bounds[1];
1241 coord0[1] = bounds[2];
1242 coord1[1] = bounds[3];
1243 coord0[2] = bounds[4];
1244 coord1[2] = bounds[5];
1245 spanTotal = Geometry::distance(coord0, coord1);
1246 simplificationThreshold_ = simplificationThresholdBuffer_ * spanTotal;
1247 } else if(simplificationType_ == 2) {
1248 simplificationThreshold_
1249 = simplificationThresholdBuffer_ * triangulation_->getNumberOfVertices();
1250 }
1251
1252 // ContourForestsTree //
1253 if(varyingMesh_ || varyingDataValues_ || toComputeContourTree_) {
1254 clearTree();
1255 getTree();
1256 updateTree();
1257 }
1258
1259 // Skeleton //
1260 if(varyingMesh_ || varyingDataValues_ || toComputeSkeleton_) {
1261#ifndef TTK_ENABLE_KAMIKAZE
1262 if(tree_ == nullptr) {
1263 this->printErr("MergeTree pointer is NULL.");
1264 return -2;
1265 }
1266#endif // TTK_ENABLE_KAMIKAZE
1267 clearSkeleton();
1268 getSkeleton();
1269 }
1270
1271 // Segmentation //
1272 if(varyingMesh_ || varyingDataValues_ || toComputeSegmentation_)
1273 getSegmentation(input);
1274
1275 // Output //
1276
1277 // skeleton
1278 outputSkeletonNodes->ShallowCopy(skeletonNodes_);
1279 outputSkeletonArcs->ShallowCopy(skeletonArcs_);
1280 // segmentation
1281 outputSegmentation->ShallowCopy(segmentation_);
1282
1283 return 1;
1284}
#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()
ttk::Triangulation * GetTriangulation(vtkDataSet *dataSet)
vtkDataArray * GetOrderArray(vtkDataSet *const inputData, const int scalarArrayIdx, ttk::Triangulation *triangulation, const bool getGlobalOrder=false, const int orderArrayIdx=0, const bool enforceOrderArrayIdx=false)
TTK VTK-filter that efficiently computes the contour tree of scalar data and more (data segmentation,...
int FillInputPortInformation(int port, vtkInformation *info) override
void SetTreeType(int tree)
int FillOutputPortInformation(int port, vtkInformation *info) override
void ShowSaddle2(bool state)
void ShowArc(bool state)
void smoothSkeleton(unsigned int skeletonSmoothing)
int getSkeletonScalars(const std::vector< double > &scalars, std::vector< std::vector< double > > &skeletonScalars) const
void SetSkeletonSmoothing(double skeletonSmooth)
void Modified() override
void getSegmentation(vtkDataSet *input)
void SetPartitionNumber(int partitionNum)
bool isCoincident(float p1[], double p2[])
void SetForceInputOffsetScalarField(bool onOff)
void ShowMin(bool state)
void SetSimplificationThreshold(double simplificationThreshold)
void ShowSaddle1(bool state)
void SetSimplificationType(int type)
void ShowMax(bool state)
void SetArcResolution(int arcResolution)
int sample(unsigned int samplingLevel)
int RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) override
void smooth(const ttk::SimplexId idArc, bool order)
void computeSkeleton(unsigned int arcRes)
void SetLessPartition(bool l)
ttk::CriticalType getNodeType(ttk::SimplexId id)
static void * GetVoidPointer(vtkDataArray *array, vtkIdType start=0)
Definition ttkUtils.cpp:226
int printErr(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
Definition Debug.h:149
double getElapsedTime()
Definition Timer.h:15
AbstractTriangulation * getData()
Triangulation::Type getType() const
int getVertexPoint(const SimplexId &vertexId, float &x, float &y, float &z) const override
bool isEmpty() const override
SimplexId getNumberOfVertices() const override
int setThreadNumber(const int nbThread) override
void setTreeType(const int &local_treeType)
Definition MergeTree.h:115
void preconditionTriangulation(AbstractTriangulation *const m, const bool preproc=true)
Definition MergeTree.h:133
void setSimplificationMethod(const int &local_simplifyMethod)
Definition MergeTree.h:119
idSuperArc getNumberOfSuperArcs() const
Definition MergeTree.h:183
void setSimplificationThreshold(const double &local_simplificationThreshold)
Definition MergeTree.h:124
SimplexId getNumberOfVisibleRegularNode(const idSuperArc &sa)
Definition MergeTree.h:212
void setVertexScalars(scalarType *vals)
Definition MergeTree.h:159
const std::vector< SuperArc > & getSuperArc() const
Definition MergeTree.h:197
void setVertexSoSoffsets(const SimplexId *const offsets)
Definition MergeTree.h:175
Node * getNode(const idNode &nodeId)
Definition MergeTree.h:244
SimplexId getVertexId() const
idSuperArc getDownSuperArcId(const idSuperArc &neighborId) const
idSuperArc getDownValence() const
bool isHidden() const
idSuperArc getUpSuperArcId(const idSuperArc &neighborId) const
idSuperArc getUpValence() const
bool isMasqued(const SimplexId &v) const
const idNode & getUpNodeId() const
SimplexId getNumberOfRegularNodes()
const SimplexId & getRegularNodeId(const SimplexId &idx)
const idNode & getDownNodeId() const
T distance(const T *p0, const T *p1, const int &dimension=3)
Definition Geometry.cpp:362
The Topology ToolKit.
CriticalType
default value for critical index
Definition DataTypes.h:80
const char VertexScalarFieldName[]
default name for vertex scalar field
Definition DataTypes.h:35
int SimplexId
Identifier type for simplices of any dimension.
Definition DataTypes.h:22
vtkStandardNewMacro(ttkContourForests)
vtkIntArray ttkSimplexIdTypeArray
Definition ttkMacros.h:11
#define ttkVtkTemplateMacro(dataType, triangulationType, call)
Definition ttkMacros.h:69
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/|__ _|"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)