TTK
Loading...
Searching...
No Matches
ttkManifoldCheck.cpp
Go to the documentation of this file.
1#include <ttkManifoldCheck.h>
2
3#include <vtkCellData.h>
4#include <vtkDataSet.h>
5#include <vtkGenericCell.h>
6#include <vtkIdTypeArray.h>
7#include <vtkInformation.h>
8#include <vtkIntArray.h>
9#include <vtkPointData.h>
10
11#include <ttkMacros.h>
12#include <ttkUtils.h>
13
14using namespace std;
15using namespace ttk;
16
18
20 this->SetNumberOfInputPorts(1);
21 this->SetNumberOfOutputPorts(1);
22}
23
24int ttkManifoldCheck::FillInputPortInformation(int port, vtkInformation *info) {
25 if(port == 0) {
26 info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet");
27 return 1;
28 }
29 return 0;
30}
31
33 vtkInformation *info) {
34 if(port == 0) {
36 return 1;
37 }
38 return 0;
39}
40
41int ttkManifoldCheck::RequestData(vtkInformation *ttkNotUsed(request),
42 vtkInformationVector **inputVector,
43 vtkInformationVector *outputVector) {
44
45 vtkDataSet *input = vtkDataSet::GetData(inputVector[0]);
46 vtkDataSet *output = vtkDataSet::GetData(outputVector);
47
48 Triangulation *triangulation = ttkAlgorithm::GetTriangulation(input);
49
50 if(!triangulation)
51 return 0;
52
53 this->preconditionTriangulation(triangulation);
54
55 // use a pointer-base copy for the input data -- to adapt if your wrapper does
56 // not produce an output of the type of the input.
57 output->ShallowCopy(input);
58
59 this->setVertexLinkComponentNumberVector(&vertexLinkComponentNumber_);
60 this->setEdgeLinkComponentNumberVector(&edgeLinkComponentNumber_);
61 this->setTriangleLinkComponentNumberVector(&triangleLinkComponentNumber_);
62
63 int error = 0;
65 triangulation->getType(),
66 (error = this->execute<TTK_TT>((TTK_TT *)triangulation->getData())));
67 if(error)
68 return error;
69
70 printMsg("Preparing VTK output...");
71
72 vtkSmartPointer<ttkSimplexIdTypeArray> const vertexPointArray
74 vertexPointArray->SetName("VertexLinkComponentNumber");
75 vertexPointArray->SetNumberOfTuples(output->GetNumberOfPoints());
76 for(SimplexId i = 0; i < (SimplexId)vertexLinkComponentNumber_.size(); i++)
77 vertexPointArray->SetTuple1(i, vertexLinkComponentNumber_[i]);
78 output->GetPointData()->AddArray(vertexPointArray);
79
80 vtkSmartPointer<ttkSimplexIdTypeArray> const vertexCellArray
82 vertexCellArray->SetName("VertexLinkComponentNumber");
83 vertexCellArray->SetNumberOfTuples(output->GetNumberOfCells());
84
85 for(SimplexId i = 0; i < output->GetNumberOfCells(); i++) {
86 vtkCell *c = output->GetCell(i);
87 SimplexId cellMax = -1;
88 for(int j = 0; j < c->GetNumberOfPoints(); j++) {
89 SimplexId const vertexId = c->GetPointId(j);
90 if((!j) || (vertexLinkComponentNumber_[vertexId] > cellMax)) {
91 cellMax = vertexLinkComponentNumber_[vertexId];
92 }
93 }
94
95 vertexCellArray->SetTuple1(i, cellMax);
96 }
97 output->GetCellData()->AddArray(vertexCellArray);
98
99 // edges
100 vtkSmartPointer<ttkSimplexIdTypeArray> const edgePointArray
102 edgePointArray->SetName("EdgeLinkComponentNumber");
103 edgePointArray->SetNumberOfTuples(output->GetNumberOfPoints());
104 for(SimplexId i = 0; i < edgePointArray->GetNumberOfTuples(); i++) {
105 edgePointArray->SetTuple1(i, 0);
106 }
107
110 edgeCellArray->SetName("EdgeLinkComponentNumber");
111 edgeCellArray->SetNumberOfTuples(output->GetNumberOfCells());
112 for(SimplexId i = 0; i < edgeCellArray->GetNumberOfTuples(); i++) {
113 edgeCellArray->SetTuple1(i, 0);
114 }
115
116 if(edgeLinkComponentNumber_.size()) {
117
118 for(SimplexId i = 0; i < (SimplexId)edgeLinkComponentNumber_.size(); i++) {
119
120 SimplexId vertexId0 = -1, vertexId1 = -1;
121 triangulation->getEdgeVertex(i, 0, vertexId0);
122 triangulation->getEdgeVertex(i, 1, vertexId1);
123
124 SimplexId const vertexMax0 = edgePointArray->GetTuple1(vertexId0);
125 SimplexId const vertexMax1 = edgePointArray->GetTuple1(vertexId1);
126
127 if(edgeLinkComponentNumber_[i] > vertexMax0)
128 edgePointArray->SetTuple1(vertexId0, edgeLinkComponentNumber_[i]);
129 if(edgeLinkComponentNumber_[i] > vertexMax1)
130 edgePointArray->SetTuple1(vertexId1, edgeLinkComponentNumber_[i]);
131 }
132
133#ifdef TTK_ENABLE_OPENMP
134#pragma omp parallel for num_threads(threadNumber_)
135#endif
136 for(SimplexId i = 0; i < output->GetNumberOfCells(); i++) {
139 output->GetCell(i, c);
140 SimplexId cellMax = -1;
141 for(int j = 0; j < c->GetNumberOfPoints(); j++) {
142 SimplexId const vertexId0 = c->GetPointId(j);
143 SimplexId vertexId1 = -1;
144 for(int k = 0; k < c->GetNumberOfPoints(); k++) {
145 if(k != j) {
146 vertexId1 = c->GetPointId(k);
147
148 // check if (vertexId0 - vertexId1) is indeed an edge in the
149 // triangulation
150 SimplexId const edgeNumber
151 = triangulation->getVertexEdgeNumber(vertexId0);
152 for(SimplexId l = 0; l < edgeNumber; l++) {
153 SimplexId edgeId = -1;
154 triangulation->getVertexEdge(vertexId0, l, edgeId);
155
156 SimplexId vertexIdA = -1, vertexIdB = -1;
157 triangulation->getEdgeVertex(edgeId, 0, vertexIdA);
158 triangulation->getEdgeVertex(edgeId, 1, vertexIdB);
159
160 if(((vertexId0 == vertexIdA) && (vertexId1 == vertexIdB))
161 || ((vertexId1 == vertexIdA) && (vertexId0 == vertexIdB))) {
162
163 // (vertexId0 - vertexId1) is indeed an edge in the
164 // triangulation
165 if(edgeLinkComponentNumber_[edgeId] > cellMax)
166 cellMax = edgeLinkComponentNumber_[edgeId];
167 }
168 }
169 }
170 }
171 }
172 edgeCellArray->SetTuple1(i, cellMax);
173 }
174 }
175 output->GetPointData()->AddArray(edgePointArray);
176 output->GetCellData()->AddArray(edgeCellArray);
177
178 // triangles
179 vtkSmartPointer<ttkSimplexIdTypeArray> const trianglePointArray
181 trianglePointArray->SetName("TriangleLinkComponentNumber");
182 trianglePointArray->SetNumberOfTuples(output->GetNumberOfPoints());
183 for(SimplexId i = 0; i < trianglePointArray->GetNumberOfTuples(); i++) {
184 trianglePointArray->SetTuple1(i, 0);
185 }
186
187 vtkSmartPointer<ttkSimplexIdTypeArray> const triangleCellArray
189 triangleCellArray->SetName("TriangleLinkComponentNumber");
190 triangleCellArray->SetNumberOfTuples(output->GetNumberOfCells());
191 for(SimplexId i = 0; i < triangleCellArray->GetNumberOfTuples(); i++) {
192 triangleCellArray->SetTuple1(i, 0);
193 }
194
195 if(triangleLinkComponentNumber_.size()) {
196
197 for(SimplexId i = 0; i < (SimplexId)triangleLinkComponentNumber_.size();
198 i++) {
199
200 SimplexId vertexId0 = -1, vertexId1 = -1, vertexId2 = -1;
201 triangulation->getTriangleVertex(i, 0, vertexId0);
202 triangulation->getTriangleVertex(i, 1, vertexId1);
203 triangulation->getTriangleVertex(i, 2, vertexId2);
204
205 SimplexId const vertexMax0 = trianglePointArray->GetTuple1(vertexId0);
206 SimplexId const vertexMax1 = trianglePointArray->GetTuple1(vertexId1);
207 SimplexId const vertexMax2 = trianglePointArray->GetTuple1(vertexId2);
208
209 if(triangleLinkComponentNumber_[i] > vertexMax0)
210 trianglePointArray->SetTuple1(
211 vertexId0, triangleLinkComponentNumber_[i]);
212 if(triangleLinkComponentNumber_[i] > vertexMax1)
213 trianglePointArray->SetTuple1(
214 vertexId1, triangleLinkComponentNumber_[i]);
215 if(triangleLinkComponentNumber_[i] > vertexMax2)
216 trianglePointArray->SetTuple1(
217 vertexId2, triangleLinkComponentNumber_[i]);
218 }
219
220#ifdef TTK_ENABLE_OPENMP
221#pragma omp parallel for num_threads(threadNumber_)
222#endif
223 for(SimplexId i = 0; i < output->GetNumberOfCells(); i++) {
226 output->GetCell(i, c);
227
228 SimplexId cellMax = -1;
229 for(int j = 0; j < c->GetNumberOfPoints(); j++) {
230 SimplexId const vertexId0 = c->GetPointId(j);
231 SimplexId vertexId1 = -1;
232 SimplexId vertexId2 = -1;
233
234 for(int k = 0; k < c->GetNumberOfPoints(); k++) {
235 if(k != j) {
236 vertexId1 = c->GetPointId(k);
237
238 for(int l = 0; l < c->GetNumberOfPoints(); l++) {
239 if((l != j) && (l != k)) {
240 vertexId2 = c->GetPointId(l);
241
242 // check if (vertexId0, vertexId1, vertexId2) is indeed a
243 // triangle in the triangulation
244 SimplexId const triangleNumber
245 = triangulation->getVertexTriangleNumber(vertexId0);
246 for(SimplexId m = 0; m < triangleNumber; m++) {
247 SimplexId triangleId = -1;
248 triangulation->getVertexTriangle(vertexId0, m, triangleId);
249
250 SimplexId vertexIdA = -1, vertexIdB = -1, vertexIdC = -1;
251 triangulation->getTriangleVertex(triangleId, 0, vertexIdA);
252 triangulation->getTriangleVertex(triangleId, 1, vertexIdB);
253 triangulation->getTriangleVertex(triangleId, 2, vertexIdC);
254
255 if(((vertexId0 == vertexIdA) && (vertexId1 == vertexIdB)
256 && (vertexId2 == vertexIdC))
258 || ((vertexId0 == vertexIdA) && (vertexId1 == vertexIdC)
259 && (vertexId2 == vertexIdB))
260 // ACB
261 || ((vertexId0 == vertexIdB) && (vertexId1 == vertexIdA)
262 && (vertexId2 == vertexIdC))
264 || ((vertexId0 == vertexIdB) && (vertexId1 == vertexIdC)
265 && (vertexId2 == vertexIdA))
266 // BCA
267 || ((vertexId0 == vertexIdC) && (vertexId1 == vertexIdA)
268 && (vertexId2 == vertexIdB))
270 || ((vertexId0 == vertexIdC) && (vertexId1 == vertexIdB)
271 && (vertexId2 == vertexIdA))) {
272 // CBA
273
274 // (vertexId0, vertexId1, vertexId2) is indeed a
275 // triangle in the triangulation
276 if(triangleLinkComponentNumber_[triangleId] > cellMax) {
277 cellMax = triangleLinkComponentNumber_[triangleId];
278 }
279 }
280 }
281 }
282 }
283 }
284 }
285 }
286 triangleCellArray->SetTuple1(i, cellMax);
287 }
288 }
289 output->GetPointData()->AddArray(trianglePointArray);
290 output->GetCellData()->AddArray(triangleCellArray);
291
292 return 1;
293}
#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
static vtkInformationIntegerKey * SAME_DATA_TYPE_AS_INPUT_PORT()
ttk::Triangulation * GetTriangulation(vtkDataSet *dataSet)
TTK VTK-filter for manifold checks.
int FillInputPortInformation(int port, vtkInformation *info) override
int FillOutputPortInformation(int port, vtkInformation *info) override
int RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) override
int setEdgeLinkComponentNumberVector(std::vector< ttk::SimplexId > *edgeVector)
Register the output std::vector for edge link component number.
int setTriangleLinkComponentNumberVector(std::vector< ttk::SimplexId > *triangleVector)
Register the output std::vector for triangle link component number.
int setVertexLinkComponentNumberVector(std::vector< ttk::SimplexId > *vertexVector)
Register the output std::vector for vertex link component number.
int preconditionTriangulation(AbstractTriangulation *const triangulation)
Triangulation is a class that provides time and memory efficient traversal methods on triangulations ...
SimplexId getVertexEdgeNumber(const SimplexId &vertexId) const override
AbstractTriangulation * getData()
int getTriangleVertex(const SimplexId &triangleId, const int &localVertexId, SimplexId &vertexId) const override
Triangulation::Type getType() const
int getVertexTriangle(const SimplexId &vertexId, const int &localTriangleId, SimplexId &triangleId) const override
int getVertexEdge(const SimplexId &vertexId, const int &localEdgeId, SimplexId &edgeId) const override
int getEdgeVertex(const SimplexId &edgeId, const int &localVertexId, SimplexId &vertexId) const override
SimplexId getVertexTriangleNumber(const SimplexId &vertexId) const override
The Topology ToolKit.
int SimplexId
Identifier type for simplices of any dimension.
Definition DataTypes.h:22
vtkStandardNewMacro(ttkManifoldCheck)
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/|__ _|"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)