1#include <vtkAppendPolyData.h>
2#include <vtkCellArray.h>
3#include <vtkCellData.h>
5#include <vtkDoubleArray.h>
6#include <vtkGenericCell.h>
7#include <vtkInformation.h>
8#include <vtkIntArray.h>
10#include <vtkLineSource.h>
12#include <vtkObjectFactory.h>
13#include <vtkPointData.h>
28 this->SetNumberOfInputPorts(1);
29 this->SetNumberOfOutputPorts(3);
32 "Contour Forests is deprecated, please use FTM Tree instead.");
39 skeletonNodes_->Delete();
40 skeletonNodes_ = vtkPolyData::New();
41 skeletonArcs_->Delete();
42 skeletonArcs_ = vtkPolyData::New();
46 segmentation_->Delete();
54 vtkInformation *info) {
56 info->Set(vtkDataObject::DATA_TYPE_NAME(),
"vtkDataSet");
63 vtkInformation *info) {
64 if(port == 0 || port == 1) {
65 info->Set(vtkDataObject::DATA_TYPE_NAME(),
"vtkPolyData");
67 }
else if(port == 2) {
75 toComputeSkeleton_ =
true;
76 toComputeContourTree_ =
true;
77 ttkAlgorithm::Modified();
81 toUpdateVertexSoSoffsets_ =
true;
82 toComputeContourTree_ =
true;
84 toComputeSkeleton_ =
true;
85 toComputeSegmentation_ =
true;
87 ForceInputOffsetScalarField = onOff;
92 if(treeType >= 0 && treeType <= 2) {
94 if(treeType_ == TreeType::Contour
95 ||
static_cast<TreeType>(treeType) == TreeType::Contour) {
96 toComputeContourTree_ =
true;
99 toComputeSkeleton_ =
true;
100 toComputeSegmentation_ =
true;
102 treeType_ =
static_cast<TreeType>(treeType);
109 toComputeSkeleton_ =
true;
116 toComputeSkeleton_ =
true;
123 toComputeSkeleton_ =
true;
125 showSaddle1_ = state;
130 toComputeSkeleton_ =
true;
132 showSaddle2_ = state;
137 toComputeSkeleton_ =
true;
144 if(arcResolution >= 0) {
145 toComputeSkeleton_ =
true;
147 arcResolution_ = arcResolution;
153 partitionNum_ = partitionNum;
155 toComputeContourTree_ =
true;
156 toComputeSkeleton_ =
true;
157 toUpdateTree_ =
true;
167 if(skeletonSmoothing >= 0) {
168 toComputeSkeleton_ =
true;
170 skeletonSmoothing_ = skeletonSmoothing;
176 simplificationType_ = type;
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;
196 for(
unsigned int k = 0; k < 3; k++) {
197 sPrev[k] = p2[k] - p1[k];
201 return (vtkMath::Normalize(sNext) == 0.0);
207 for(
unsigned int k = 0; k < 3; k++) {
208 sPrev[k] = p2[k] - p1[k];
212 return (vtkMath::Normalize(sNext) == 0.0);
216 vtkNew<vtkAppendPolyData> app{};
218 vtkDoubleArray *scalars{};
220 vtkIntArray *typeScalars{};
222 vtkDoubleArray *spanScalars{};
223 int type =
static_cast<int>(TreeComponent::Arc);
226 vector<double> point2(3);
228 vector<vector<double>> skeletonScalars{};
246 upVertex, coordUp[0], coordUp[1], coordUp[2]);
252 downVertex, coordDown[0], coordDown[1], coordDown[2]);
256 regionId = currentZone++;
259 if(barycenters_[
static_cast<int>(treeType_)][i].size()) {
262 if(treeType_ == TreeType::Split)
268 downNodeVId, point1[0], point1[1], point1[2]);
271 line->SetPoint1(point1);
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());
281 vtkPolyData *lineData = line->GetOutput();
285 inputScalar = skeletonScalars[i][j];
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);
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();
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();
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();
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();
325 app->AddInputData(lineData);
329 line->SetPoint1(point2.data());
334 if(treeType_ == TreeType::Split)
339 std::array<float, 3> pt{};
344 line->SetPoint2(point2.data());
348 vtkPolyData *lineData = line->GetOutput();
353 = skeletonScalars[i][barycenters_[
static_cast<int>(treeType_)][i]
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);
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();
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();
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();
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();
394 app->AddInputData(lineData);
397 vtkNew<vtkLineSource> line{};
402 downNodeVId, point1[0], point1[1], point1[2]);
403 line->SetPoint1(point1);
406 std::array<float, 3> pt{};
411 line->SetPoint2(point2.data());
415 vtkPolyData *lineData = line->GetOutput();
419 inputScalar = skeletonScalars[i][0];
421 scalars = vtkDoubleArray::New();
422 scalars->SetName(vtkInputScalars_->GetName());
423 for(
unsigned int k = 0; k < 2; ++k)
424 scalars->InsertTuple1(k, inputScalar);
425 lineData->GetPointData()->AddArray(scalars);
431 identifierScalars = ttkSimplexIdTypeArray::New();
432 identifierScalars->SetName(
"SegmentationId");
433 for(
int k = 0; k < 2; ++k)
434 identifierScalars->InsertTuple1(k, regionId);
435 lineData->GetCellData()->AddArray(identifierScalars);
436 identifierScalars->Delete();
438 typeScalars = vtkIntArray::New();
439 typeScalars->SetName(
"Type");
440 for(
unsigned int k = 0; k < 2; ++k)
441 typeScalars->InsertTuple1(k, type);
442 lineData->GetCellData()->AddArray(typeScalars);
443 typeScalars->Delete();
445 sizeScalars = ttkSimplexIdTypeArray::New();
446 sizeScalars->SetName(
"RegionSize");
447 for(
unsigned int k = 0; k < 2; ++k)
448 sizeScalars->InsertTuple1(k, regionSize);
449 lineData->GetCellData()->AddArray(sizeScalars);
450 sizeScalars->Delete();
452 spanScalars = vtkDoubleArray::New();
453 spanScalars->SetName(
"RegionSpan");
454 for(
unsigned int k = 0; k < 2; ++k)
455 spanScalars->InsertTuple1(k, regionSpan);
456 lineData->GetCellData()->AddArray(spanScalars);
457 spanScalars->Delete();
459 app->AddInputData(lineData);
470 skeletonArcs_->ShallowCopy(app->GetOutput());
474 const vector<double> &scalars,
475 vector<vector<double>> &skeletonScalars)
const {
476 skeletonScalars.clear();
496 if(treeType_ == TreeType::Split) {
507 fmax = scalars[nodeMaxVId];
508 fmin = scalars[nodeMinVId];
515 j < (SimplexId)samples_[static_cast<int>(treeType_)][i].size(); ++j) {
516 const vector<SimplexId> &
sample
517 = samples_[
static_cast<int>(treeType_)][i][j];
523 f += scalars[vertexId];
530 skeletonScalars[i].push_back((f0 + f1) / 2);
539 skeletonScalars[i].push_back((f0 + f1) / 2);
547 vtkNew<vtkPoints> points{};
551 vtkNew<vtkDoubleArray> scalars{};
552 scalars->SetName(vtkInputScalars_->GetName());
554 vtkNew<ttkSimplexIdTypeArray> nodeIdentifierScalars{};
555 nodeIdentifierScalars->SetName(
"NodeIdentifier");
557 vtkNew<ttkSimplexIdTypeArray> vertexIdentifierScalars{};
561 vtkNew<vtkIntArray> nodeTypeScalars{};
562 nodeTypeScalars->SetName(
"CriticalType");
564 vtkNew<ttkSimplexIdTypeArray> regionSizeScalars{};
565 regionSizeScalars->SetName(
"RegionSize");
568 for(
unsigned i = 0; i < criticalPoints_.size(); ++i) {
575 if((nodeType == CriticalType::Local_minimum and showMin_)
576 or (nodeType == CriticalType::Local_maximum and showMax_)
577 or (nodeType == CriticalType::Saddle1 and showSaddle1_)
578 or (nodeType == CriticalType::Saddle2 and showSaddle2_)
579 or ((showSaddle1_ and showSaddle2_)
580 and (nodeType == CriticalType::Regular
581 or nodeType == CriticalType::Degenerate))) {
583 triangulation_->
getVertexPoint(vertexId, point[0], point[1], point[2]);
584 points->InsertPoint(identifier, point);
587 scalar = vertexScalars_[vertexId];
588 scalars->InsertTuple1(identifier, scalar);
591 nodeIdentifierScalars->InsertTuple1(identifier, nodeId);
594 vertexIdentifierScalars->InsertTuple1(identifier, vertexId);
597 type =
static_cast<int>(nodeType);
598 nodeTypeScalars->InsertTuple1(identifier, type);
602 if(nodeType == CriticalType::Local_maximum) {
604 regionSize = tree_->
getSuperArc(arcId)->getNumberOfRegularNodes() + 1;
605 }
else if(nodeType == CriticalType::Local_minimum) {
607 regionSize = tree_->
getSuperArc(arcId)->getNumberOfRegularNodes() + 1;
609 regionSizeScalars->InsertTuple1(identifier, regionSize);
614 skeletonNodes_->SetPoints(points);
615 skeletonNodes_->GetPointData()->AddArray(scalars);
616 skeletonNodes_->GetPointData()->AddArray(nodeIdentifierScalars);
617 skeletonNodes_->GetPointData()->AddArray(vertexIdentifierScalars);
618 skeletonNodes_->GetPointData()->AddArray(nodeTypeScalars);
619 skeletonNodes_->GetPointData()->AddArray(regionSizeScalars);
630 if(type == TreeType::Join || type == TreeType::Contour) {
637 int degree = upDegree + downDegree;
641 if(upDegree == 2 && downDegree == 1)
642 return CriticalType::Saddle2;
643 else if(upDegree == 1 && downDegree == 2)
644 return CriticalType::Saddle1;
645 else if(upDegree == 1 && downDegree == 1)
646 return CriticalType::Regular;
648 return CriticalType::Degenerate;
653 return CriticalType::Local_minimum;
655 return CriticalType::Local_maximum;
660 vector<bool> isCriticalPoint(numberOfVertices_);
662 criticalPoints_.clear();
663 for(
SimplexId i = 0; i < numberOfVertices_; ++i)
664 isCriticalPoint[i] =
false;
675 if(!isCriticalPoint[up_vId]) {
676 isCriticalPoint[up_vId] =
true;
677 criticalPoints_.push_back(upId);
682 if(!isCriticalPoint[down_vId]) {
683 isCriticalPoint[down_vId] =
true;
684 criticalPoints_.push_back(downId);
701 vector<vector<SimplexId>> sampleList(samplingLevel);
708 for(
unsigned int j = 0; j < samplingLevel; ++j) {
709 sampleList[j].clear();
717 if(treeType_ == TreeType::Split) {
728 fmax = vertexScalars_[nodeMaxVId];
729 fmin = vertexScalars_[nodeMinVId];
731 delta = (fmax - fmin) / samplingLevel;
741 f = vertexScalars_[vertexId];
743 for(
unsigned int k = 0; k < samplingLevel; ++k) {
744 if(f <= (k + 1) * delta + fmin) {
745 sampleList[k].push_back(nodeId);
753 samples_[
static_cast<int>(treeType_)][i].push_back(sampleList[j]);
762 barycenters_.resize(3);
763 barycenters_[
static_cast<int>(treeType_)].resize(
765 vector<float> barycenter(3);
773 j < (SimplexId)samples_[static_cast<int>(treeType_)][i].size(); ++j) {
774 vector<SimplexId> &
sample = samples_[
static_cast<int>(treeType_)][i][j];
776 for(
unsigned int k = 0; k < 3; ++k)
784 barycenter[0] += pt[0];
785 barycenter[1] += pt[1];
786 barycenter[2] += pt[2];
789 for(
unsigned int k = 0; k < 3; ++k)
790 barycenter[k] /=
sample.size();
794 = barycenters_[
static_cast<int>(treeType_)][i].size();
795 barycenters_[
static_cast<int>(treeType_)][i].resize(nbBar + 1);
796 barycenters_[
static_cast<int>(treeType_)][i][nbBar].resize(3);
798 for(
unsigned int k = 0; k < 3; ++k)
799 barycenters_[
static_cast<int>(treeType_)][i][nbBar][k]
815 for(
unsigned int i = 0; i < skeletonSmoothing; i++) {
818 smooth(j, !(treeType_ == TreeType::Split));
825 int N = barycenters_[
static_cast<int>(treeType_)][idArc].size();
828 vector<vector<double>> barycenterList(N);
829 for(
unsigned int i = 0; i < barycenterList.size(); ++i)
830 barycenterList[i].resize(3);
846 std::array<float, 3> p0{};
847 std::array<float, 3> p1{};
854 for(
unsigned int k = 0; k < 3; ++k)
856 = (p0[k] + barycenters_[
static_cast<int>(treeType_)][idArc][1][k])
860 for(
int i = 1; i < N - 1; ++i) {
861 for(
unsigned int k = 0; k < 3; ++k)
863 = (barycenters_[
static_cast<int>(treeType_)][idArc][i - 1][k]
864 + barycenters_[
static_cast<int>(treeType_)][idArc][i + 1][k])
868 for(
unsigned int k = 0; k < 3; ++k)
869 barycenterList[N - 1][k]
870 = (p1[k] + barycenters_[
static_cast<int>(treeType_)][idArc][N - 1][k])
873 for(
unsigned int k = 0; k < 3; ++k)
874 barycenterList[0][k] = (p0[k] + p1[k]) * 0.5;
878 for(
int i = 0; i < N; ++i) {
879 for(
unsigned int k = 0; k < 3; ++k)
880 barycenters_[
static_cast<int>(treeType_)][idArc][i][k]
881 = barycenterList[i][k];
892 if(showMin_ || showMax_ || showSaddle1_ || showSaddle2_)
895 skeletonNodes_->ShallowCopy(voidUnstructuredGrid_);
901 skeletonArcs_->ShallowCopy(voidPolyData_);
904 toComputeSkeleton_ =
false;
907 "Topological skeleton built", 1.0, t.
getElapsedTime(), this->threadNumber_);
908 this->
printMsg(std::vector<std::vector<std::string>>{
909 {
"Arc resolution", std::to_string(arcResolution_)},
910 {
"Smoothing", std::to_string(skeletonSmoothing_)}});
918 vtkNew<ttkSimplexIdTypeArray> scalarsRegionId{};
919 scalarsRegionId->SetName(
"SegmentationId");
920 scalarsRegionId->SetNumberOfTuples(vertexScalars_.size());
923 vtkNew<vtkIntArray> scalarsRegionType{};
924 scalarsRegionType->SetName(
"RegionType");
925 scalarsRegionType->SetNumberOfTuples(vertexScalars_.size());
928 vtkNew<ttkSimplexIdTypeArray> scalarsRegionSize{};
929 scalarsRegionSize->SetName(
"RegionSize");
930 scalarsRegionSize->SetNumberOfTuples(vertexScalars_.size());
933 vtkNew<vtkDoubleArray> scalarsRegionSpan{};
934 scalarsRegionSpan->SetName(
"RegionSpan");
935 scalarsRegionSpan->SetNumberOfTuples(vertexScalars_.size());
940 segmentation_ = input->NewInstance();
941 segmentation_->ShallowCopy(input);
944 for(
SimplexId i = 0; i < numberOfVertices_; i++) {
945 scalarsRegionId->SetTuple1(i, -1);
955 scalarsRegionType->SetTuple1(vertexId, regionType);
967 upVertex, coordUp[0], coordUp[1], coordUp[2]);
974 downVertex, coordDown[0], coordDown[1], coordDown[2]);
978 regionId = currentZone++;
991 scalarsRegionId->SetTuple1(
993 scalarsRegionId->SetTuple1(
996 scalarsRegionSize->SetTuple1(
998 scalarsRegionSize->SetTuple1(
1001 scalarsRegionSpan->SetTuple1(
1003 scalarsRegionSpan->SetTuple1(
1017 scalarsRegionId->SetTuple1(vertexId, regionId);
1018 scalarsRegionSize->SetTuple1(vertexId, regionSize);
1019 scalarsRegionSpan->SetTuple1(vertexId, regionSpan);
1024 if((upNodeType == CriticalType::Local_minimum
1025 && downNodeType == CriticalType::Local_maximum)
1026 || (upNodeType == CriticalType::Local_minimum
1027 || downNodeType == CriticalType::Local_minimum))
1028 regionType =
static_cast<int>(ArcType::Min_arc);
1029 else if(upNodeType == CriticalType::Local_maximum
1030 || downNodeType == CriticalType::Local_maximum)
1031 regionType =
static_cast<int>(ArcType::Max_arc);
1032 else if(upNodeType == CriticalType::Saddle1
1033 && downNodeType == CriticalType::Saddle1)
1034 regionType =
static_cast<int>(ArcType::Saddle1_arc);
1035 else if(upNodeType == CriticalType::Saddle2
1036 && downNodeType == CriticalType::Saddle2)
1037 regionType =
static_cast<int>(ArcType::Saddle2_arc);
1039 regionType =
static_cast<int>(ArcType::Saddle1_saddle2_arc);
1049 scalarsRegionType->SetTuple1(vertexId, regionType);
1055 segmentation_->GetPointData()->AddArray(scalarsRegionId);
1056 segmentation_->GetPointData()->AddArray(scalarsRegionType);
1057 segmentation_->GetPointData()->AddArray(scalarsRegionSize);
1058 segmentation_->GetPointData()->AddArray(scalarsRegionSpan);
1061 this->threadNumber_);
1062 this->
printMsg(std::vector<std::vector<std::string>>{
1063 {
"Region type", std::to_string(scalarsRegionType->GetNumberOfTuples())},
1064 {
"Segmentation Id", std::to_string(scalarsRegionId->GetNumberOfTuples())}});
1066 toComputeSegmentation_ =
false;
1086 (this->build<VTK_TT, TTK_TT *>(
1087 static_cast<TTK_TT *
>(triangulation_->
getData()))));
1090 toComputeContourTree_ =
false;
1096 case TreeType::Join:
1099 case TreeType::Split:
1102 case TreeType::JoinAndSplit:
1106 case TreeType::Contour:
1113 toUpdateTree_ =
false;
1117 vtkInformationVector **inputVector,
1118 vtkInformationVector *outputVector) {
1120 "DEPRECATED This plugin will be removed in a future release, please use "
1121 "FTM instead for contour trees and FTR for Reeb graphs.");
1123 const auto input = vtkDataSet::GetData(inputVector[0]);
1124 auto outputSkeletonNodes = vtkPolyData::GetData(outputVector, 0);
1125 auto outputSkeletonArcs = vtkPolyData::GetData(outputVector, 1);
1126 auto outputSegmentation = vtkDataSet::GetData(outputVector, 2);
1128#ifndef TTK_ENABLE_KAMIKAZE
1130 this->
printErr(
"Input pointer is NULL.");
1134 if(!outputSkeletonNodes || !outputSkeletonArcs || !outputSegmentation) {
1135 this->
printErr(
"Output pointer is NULL.");
1139 if(!input->GetNumberOfPoints()) {
1140 this->
printErr(
"Input has no point.");
1147#ifndef TTK_ENABLE_KAMIKAZE
1148 if(!triangulation_) {
1149 this->
printErr(
"Input triangulation is NULL.");
1154 varyingMesh_ =
false;
1156 varyingMesh_ =
true;
1159 if(varyingMesh_ || !numberOfVertices_) {
1160 numberOfVertices_ = input->GetNumberOfPoints();
1164 segmentation_ = input->NewInstance();
1165 if(segmentation_ !=
nullptr) {
1166 segmentation_->ShallowCopy(input);
1170#ifndef TTK_ENABLE_KAMIKAZE
1171 if(!input->GetPointData()) {
1172 this->
printErr(
"Input has no point data.");
1178 vtkInputScalars_ = this->GetInputArrayToProcess(0, input);
1180#ifndef TTK_ENABLE_KAMIKAZE
1181 if(!vtkInputScalars_) {
1182 this->
printErr(
"Input scalar is NULL.");
1187 varyingDataValues_ = (vtkInputScalars_->GetMTime() > GetMTime());
1188 if(input->GetPointData()) {
1190 vertexScalars_.resize(numberOfVertices_);
1191 for(
SimplexId j = 0; j < numberOfVertices_; ++j) {
1192 vertexScalars_[j] = vtkInputScalars_->GetTuple1(j);
1197 = std::minmax_element(vertexScalars_.begin(), vertexScalars_.end());
1198 double scalarMin = *result.first;
1199 double scalarMax = *result.second;
1200 deltaScalar_ = (scalarMax - scalarMin);
1203 if(varyingMesh_ || varyingDataValues_ || vertexSoSoffsets_ ==
nullptr) {
1206 = this->
GetOrderArray(input, 0, 1, ForceInputOffsetScalarField);
1208 if(offsets !=
nullptr) {
1213 toUpdateVertexSoSoffsets_ =
false;
1216 if(varyingMesh_ || varyingDataValues_ || !isLoaded_) {
1217 this->
printMsg(
"Convenient data storage loaded", debug::Priority::DETAIL);
1219 std::vector<std::vector<std::string>>{
1220 {
"#Tuples", std::to_string(vertexScalars_.size())},
1221 {
"#Vertices", std::to_string(numberOfVertices_)},
1222 {
"Min", std::to_string(scalarMin)},
1223 {
"Max", std::to_string(scalarMax)},
1225 debug::Priority::DETAIL);
1228 this->
printMsg(
"Launching computation for field `"
1229 + std::string{vtkInputScalars_->GetName()} +
"'...");
1233 if(simplificationType_ == 0) {
1234 simplificationThreshold_ = simplificationThresholdBuffer_ * deltaScalar_;
1235 }
else if(simplificationType_ == 1) {
1236 double coord0[3], coord1[3], spanTotal;
1237 double *bounds = input->GetBounds();
1238 coord0[0] = bounds[0];
1239 coord1[0] = bounds[1];
1240 coord0[1] = bounds[2];
1241 coord1[1] = bounds[3];
1242 coord0[2] = bounds[4];
1243 coord1[2] = bounds[5];
1245 simplificationThreshold_ = simplificationThresholdBuffer_ * spanTotal;
1246 }
else if(simplificationType_ == 2) {
1247 simplificationThreshold_
1252 if(varyingMesh_ || varyingDataValues_ || toComputeContourTree_) {
1259 if(varyingMesh_ || varyingDataValues_ || toComputeSkeleton_) {
1260#ifndef TTK_ENABLE_KAMIKAZE
1261 if(tree_ ==
nullptr) {
1262 this->
printErr(
"MergeTree pointer is NULL.");
1271 if(varyingMesh_ || varyingDataValues_ || toComputeSegmentation_)
1277 outputSkeletonNodes->ShallowCopy(skeletonNodes_);
1278 outputSkeletonArcs->ShallowCopy(skeletonArcs_);
1280 outputSegmentation->ShallowCopy(segmentation_);
#define ttkNotUsed(x)
Mark function/method parameters that are not used in the function body at all.
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 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 smoothSkeleton(unsigned int skeletonSmoothing)
int getSkeletonScalars(const std::vector< double > &scalars, std::vector< std::vector< double > > &skeletonScalars) const
void SetSkeletonSmoothing(double skeletonSmooth)
void getSegmentation(vtkDataSet *input)
void SetPartitionNumber(int partitionNum)
bool isCoincident(float p1[], double p2[])
void SetForceInputOffsetScalarField(bool onOff)
void SetSimplificationThreshold(double simplificationThreshold)
void ShowSaddle1(bool state)
void SetSimplificationType(int type)
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)
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
int printErr(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
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
MergeTree * getJoinTree()
MergeTree * getSplitTree()
void setPartitionNum(int p)
void setLessPartition(bool l)
int setThreadNumber(const int nbThread) override
void setTreeType(const int &local_treeType)
void preconditionTriangulation(AbstractTriangulation *const m, const bool preproc=true)
void setSimplificationMethod(const int &local_simplifyMethod)
idSuperArc getNumberOfSuperArcs() const
void setSimplificationThreshold(const double &local_simplificationThreshold)
SimplexId getNumberOfVisibleRegularNode(const idSuperArc &sa)
void setVertexScalars(scalarType *vals)
const std::vector< SuperArc > & getSuperArc() const
void setVertexSoSoffsets(const SimplexId *const offsets)
Node * getNode(const idNode &nodeId)
SimplexId getVertexId() const
idSuperArc getDownSuperArcId(const idSuperArc &neighborId) const
idSuperArc getDownValence() 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)
CriticalType
default value for critical index
const char VertexScalarFieldName[]
default name for vertex scalar field
int SimplexId
Identifier type for simplices of any dimension.
vtkStandardNewMacro(ttkContourForests)
vtkIntArray ttkSimplexIdTypeArray
#define ttkVtkTemplateMacro(dataType, triangulationType, call)