TTK
Loading...
Searching...
No Matches
ttkPersistentGenerators.cpp
Go to the documentation of this file.
1#include <vtkCellData.h>
2#include <vtkDataSet.h>
3#include <vtkDoubleArray.h>
4#include <vtkFloatArray.h>
5#include <vtkIdTypeArray.h>
6#include <vtkInformation.h>
7#include <vtkNew.h>
8#include <vtkPointData.h>
9#include <vtkPolyData.h>
10#include <vtkSignedCharArray.h>
11#include <vtkSmartPointer.h>
12#include <vtkUnsignedCharArray.h>
13
15#include <ttkUtils.h>
16
18
20 this->setDebugMsgPrefix("PersistentGenerators");
21 SetNumberOfInputPorts(1);
22 SetNumberOfOutputPorts(1);
23}
24
26 vtkInformation *info) {
27 if(port == 0) {
28 info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet");
29 return 1;
30 }
31 return 0;
32}
33
35 vtkInformation *info) {
36 if(port == 0) {
37 info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkPolyData");
38 return 1;
39 }
40 return 0;
41}
42
43template <typename triangulationType>
44int ttkPersistentGenerators::dispatch(vtkPolyData *output,
45 vtkDataArray *const inputScalarsArray,
46 const SimplexId *const inputOrder,
47 const triangulationType &triangulation) {
48
49 this->buildGradient(ttkUtils::GetVoidPointer(inputScalarsArray),
50 inputScalarsArray->GetMTime(), inputOrder, triangulation);
51 std::vector<GeneratorType> cycles{};
52 std::vector<std::vector<SimplexId>> connComps{};
54 cycles, connComps, inputOrder, triangulation);
55
56 const SimplexId numberOfVertices = triangulation.getNumberOfVertices();
57 std::vector<SimplexId> isVisited(numberOfVertices, -1);
58 std::vector<SimplexId> visitedIds{};
59
60 vtkNew<vtkPoints> points{};
61 vtkNew<vtkCellArray> cells{};
62
63 vtkNew<ttkSimplexIdTypeArray> cycleId{};
64 cycleId->SetName("CycleId");
65 vtkNew<ttkSimplexIdTypeArray> edgeId{};
66 edgeId->SetName("EdgeId");
67 vtkNew<ttkSimplexIdTypeArray> birthId{};
68 birthId->SetName("BirthId");
69 vtkNew<ttkSimplexIdTypeArray> deathId{};
70 deathId->SetName("DeathId");
71 vtkNew<ttkSimplexIdTypeArray> ccId{};
72 ccId->SetName("ComponentId");
73 vtkNew<vtkUnsignedCharArray> iFin{};
74 iFin->SetName(ttk::PersistenceIsFinite);
75 vtkSmartPointer<vtkDataArray> const pers{inputScalarsArray->NewInstance()};
76 pers->SetName(ttk::PersistenceName);
77 vtkNew<vtkSignedCharArray> mask{};
78 mask->SetName(ttk::MaskScalarFieldName);
79 vtkNew<ttkSimplexIdTypeArray> vertsId{};
80 vertsId->SetName(ttk::VertexScalarFieldName);
81 vtkSmartPointer<vtkDataArray> const sf{inputScalarsArray->NewInstance()};
82 sf->SetName(inputScalarsArray->GetName());
83 vtkNew<vtkSignedCharArray> nbOnBoundary{};
84 nbOnBoundary->SetNumberOfComponents(1);
86
87 const auto addVertex = [&](const SimplexId v) {
88 if(v == -1) {
89 return vtkIdType(-1);
90 }
91 std::array<float, 3> p{};
92 triangulation.getVertexPoint(v, p[0], p[1], p[2]);
93 return points->InsertNextPoint(p.data());
94 };
95
96 const auto addEdge = [&](const SimplexId e) {
97 std::array<vtkIdType, 2> pts{};
98 for(int i = 0; i < 2; ++i) {
99 SimplexId v{};
100 triangulation.getEdgeVertex(e, i, v);
101 if(isVisited[v] == -1) {
102 pts[i] = addVertex(v);
103 isVisited[v] = pts[i];
104 visitedIds.emplace_back(v);
105 } else {
106 pts[i] = isVisited[v];
107 }
108 }
109 cells->InsertNextCell(2, pts.data());
110 };
111
112 for(size_t i = 0; i < cycles.size(); ++i) {
113 if(cycles[i].boundary.empty()) {
114 continue;
115 }
116
117 const auto &cycle{cycles[i]};
118 const auto cbirth{cycle.boundary[0]};
119 const auto cdeath{cycle.critTriangleId};
120 const auto cpers{inputScalarsArray->GetTuple1(cycle.critVertsIds[0])
121 - inputScalarsArray->GetTuple1(cycle.critVertsIds[1])};
122
123 for(const auto e : cycle.boundary) {
124 addEdge(e);
125 cycleId->InsertNextTuple1(i);
126 edgeId->InsertNextTuple1(e);
127 birthId->InsertNextTuple1(cbirth);
128 deathId->InsertNextTuple1(cdeath);
129 pers->InsertNextTuple1(cpers);
130 iFin->InsertNextTuple1(cdeath != -1);
131 nbOnBoundary->InsertNextTuple1(
132 triangulation.isEdgeOnBoundary(cbirth)
133 + (cdeath != -1 && triangulation.getDimensionality() == 3
134 ? triangulation.isTriangleOnBoundary(cdeath)
135 : 0));
136 }
137 for(const auto cc : connComps[i]) {
138 ccId->InsertNextTuple1(cc);
139 }
140
141 // copy input scalar field
142 for(const auto v : visitedIds) {
143 vertsId->InsertNextTuple1(v);
144 sf->InsertNextTuple1(inputScalarsArray->GetTuple1(v));
145 mask->InsertNextTuple1(1);
146 }
147
148 // fill mask (0 on critical edge greater vertex, 1 on other vertices)
149 SimplexId v0{}, v1{};
150 triangulation.getEdgeVertex(cbirth, 0, v0);
151 triangulation.getEdgeVertex(cbirth, 1, v1);
152 mask->SetTuple1(isVisited[v0], 0);
153 mask->SetTuple1(isVisited[v1], 0);
154
155 // ensure cycles don't share points
156 for(const auto v : visitedIds) {
157 isVisited[v] = -1;
158 }
159 visitedIds.clear();
160 }
161
162 output->SetPoints(points);
163 output->GetPointData()->AddArray(sf);
164 output->GetPointData()->AddArray(mask);
165 output->GetPointData()->AddArray(vertsId);
166 output->SetLines(cells);
167 output->GetCellData()->AddArray(cycleId);
168 output->GetCellData()->AddArray(edgeId);
169 output->GetCellData()->AddArray(birthId);
170 output->GetCellData()->AddArray(deathId);
171 output->GetCellData()->AddArray(ccId);
172 output->GetCellData()->AddArray(iFin);
173 output->GetCellData()->AddArray(pers);
174 output->GetCellData()->AddArray(nbOnBoundary);
175
176 return 1;
177}
178
180 vtkInformationVector **inputVector,
181 vtkInformationVector *outputVector) {
182
183 auto *input = vtkDataSet::GetData(inputVector[0]);
184 auto *output = vtkPolyData::GetData(outputVector, 0);
185
187 if(triangulation == nullptr) {
188 this->printErr("Wrong triangulation");
189 return 0;
190 }
191 this->preconditionTriangulation(triangulation);
192
193 vtkDataArray *inputScalars = this->GetInputArrayToProcess(0, inputVector);
194 if(inputScalars == nullptr) {
195 this->printErr("Wrong input scalars");
196 return 0;
197 }
198
199 vtkDataArray *offsetField = this->GetOrderArray(
200 input, 0, triangulation, false, 1, ForceInputOffsetScalarField);
201 if(offsetField == nullptr) {
202 this->printErr("Wrong input offsets");
203 return 0;
204 }
205
207 triangulation->getType(),
208 this->dispatch(output, inputScalars,
209 ttkUtils::GetPointer<SimplexId>(offsetField),
210 *static_cast<TTK_TT *>(triangulation->getData())));
211
212 return 1;
213}
#define ttkTemplateMacro(triangulationType, call)
#define ttkNotUsed(x)
Mark function/method parameters that are not used in the function body at all.
Definition BaseClass.h:47
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 for the computation of persistent generators.
int FillInputPortInformation(int port, vtkInformation *info) override
int FillOutputPortInformation(int port, vtkInformation *info) override
int RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) override
static void * GetVoidPointer(vtkDataArray *array, vtkIdType start=0)
Definition ttkUtils.cpp:226
void setDebugMsgPrefix(const std::string &prefix)
Definition Debug.h:364
int printErr(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
Definition Debug.h:149
int buildGradient(const void *const scalars, const size_t scalarsMTime, const SimplexId *const offsets, const triangulationType &triangulation)
void preconditionTriangulation(AbstractTriangulation *const data)
int computePersistentGenerators(std::vector< GeneratorType > &generators, std::vector< std::vector< SimplexId > > &connComps, const SimplexId *const offsets, const triangulationType &triangulation)
Compute the persistence generators from the discrete gradient.
Triangulation is a class that provides time and memory efficient traversal methods on triangulations ...
AbstractTriangulation * getData()
Triangulation::Type getType() const
const char PersistenceName[]
Definition DataTypes.h:72
const char MorseSmaleCriticalPointsOnBoundaryName[]
Definition DataTypes.h:61
const char PersistenceIsFinite[]
Definition DataTypes.h:74
const char VertexScalarFieldName[]
default name for vertex scalar field
Definition DataTypes.h:35
const char MaskScalarFieldName[]
default name for mask scalar field
Definition DataTypes.h:32
int SimplexId
Identifier type for simplices of any dimension.
Definition DataTypes.h:22
vtkStandardNewMacro(ttkPersistentGenerators)