TTK
Loading...
Searching...
No Matches
ttkFiberSurface.cpp
Go to the documentation of this file.
1#include <vtkCellArray.h>
2#include <vtkCellData.h>
3#include <vtkDoubleArray.h>
4#include <vtkInformation.h>
5#include <vtkNew.h>
6#include <vtkObjectFactory.h>
7#include <vtkPointData.h>
8#include <vtkPolyData.h>
9#include <vtkUnstructuredGrid.h>
10
11#include <ttkFiberSurface.h>
12#include <ttkMacros.h>
13#include <ttkUtils.h>
14
16
18 this->SetNumberOfInputPorts(2);
19 this->SetNumberOfOutputPorts(1);
20}
21
22int ttkFiberSurface::FillInputPortInformation(int port, vtkInformation *info) {
23 if(port == 0) {
24 info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet");
25 return 1;
26 } else if(port == 1) {
27 info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkUnstructuredGrid");
28 return 1;
29 }
30 return 0;
31}
32
33int ttkFiberSurface::FillOutputPortInformation(int port, vtkInformation *info) {
34 if(port == 0) {
35 info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkPolyData");
36 return 1;
37 }
38 return 0;
39}
40
41template <typename VTK_T1, typename VTK_T2>
43
44#ifdef TTK_ENABLE_FIBER_SURFACE_WITH_RANGE_OCTREE
45 if(RangeOctree) {
46 ttkTemplateMacro(triangulation->getType(),
47 (this->buildOctree<VTK_T1, VTK_T2>(
48 static_cast<TTK_TT *>(triangulation->getData()))));
49 }
50#endif // TTK_ENABLE_FIBER_SURFACE_WITH_RANGE_OCTREE
51
52 ttkTemplateMacro(triangulation->getType(),
53 (this->computeSurface<VTK_T1, VTK_T2>(
54 static_cast<TTK_TT *>(triangulation->getData()))));
55 return 0;
56}
57
58int ttkFiberSurface::RequestData(vtkInformation *ttkNotUsed(request),
59 vtkInformationVector **inputVector,
60 vtkInformationVector *outputVector) {
61
62 using ttk::SimplexId;
63 ttk::Timer t;
64
65 const auto input = vtkDataSet::GetData(inputVector[0]);
66 const auto polygon = vtkUnstructuredGrid::GetData(inputVector[1]);
67 auto output = vtkPolyData::GetData(outputVector);
68
69 const auto dataUfield = this->GetInputArrayToProcess(0, input);
70 const auto dataVfield = this->GetInputArrayToProcess(1, input);
71 const auto polygonUfield = this->GetInputArrayToProcess(2, polygon);
72 const auto polygonVfield = this->GetInputArrayToProcess(3, polygon);
73
74 if(dataUfield == nullptr || dataVfield == nullptr || polygonUfield == nullptr
75 || polygonVfield == nullptr) {
76 this->printErr("Could not find data array");
77 return -1;
78 }
79
80 if(!(input->GetDataObjectType() == VTK_UNSTRUCTURED_GRID
81 || input->GetDataObjectType() == VTK_IMAGE_DATA)) {
82 this->printErr("Unsupported VTK data structure");
83 return -5;
84 }
85
86 auto triangulation = ttkAlgorithm::GetTriangulation(input);
87 if(triangulation == nullptr) {
88 return -1;
89 }
90
91 this->preconditionTriangulation(triangulation);
92 outputVertexList_.clear();
93 this->setGlobalVertexList(&outputVertexList_);
94 this->setInputField(
95 ttkUtils::GetVoidPointer(dataUfield), ttkUtils::GetVoidPointer(dataVfield));
96 this->setPolygonEdgeNumber(polygon->GetNumberOfCells());
97 threadedTriangleList_.resize(polygon->GetNumberOfCells());
98 threadedVertexList_.resize(polygon->GetNumberOfCells());
99 this->setPolygon(&inputPolygon_);
100
101 this->setPointMerging(PointMerge);
102 this->setPointMergingThreshold(PointMergeDistanceThreshold);
103
104#ifdef TTK_ENABLE_FIBER_SURFACE_WITH_RANGE_OCTREE
105 if((!RangeOctree) || (dataUfield->GetMTime() > GetMTime())
106 || (dataVfield->GetMTime() > GetMTime())) {
107
108 this->printMsg("Resetting octree...");
109
110 this->flushOctree();
111 Modified();
112 }
113#endif
114
115 inputPolygon_.clear();
116
117#if !defined(_WIN32) || defined(_WIN32) && defined(VTK_USE_64BIT_IDS)
118 const long long int *cellArray
119 = polygon->GetCells()->GetData()->GetPointer(0);
120#else
121 int *pt = polygon->GetCells()->GetPointer();
122 long long extra_pt = *pt;
123 const long long int *cellArray = &extra_pt;
124#endif
125 SimplexId cellNumber = polygon->GetNumberOfCells();
126
127 SimplexId vertexId0, vertexId1;
128 std::pair<std::pair<double, double>, std::pair<double, double>> rangeEdge;
129
130 for(SimplexId i = 0; i < cellNumber; i++) {
131
132 vertexId0 = cellArray[3 * i + 1];
133 vertexId1 = cellArray[3 * i + 2];
134
135 rangeEdge.first.first = polygonUfield->GetTuple1(vertexId0);
136 rangeEdge.first.second = polygonVfield->GetTuple1(vertexId0);
137
138 rangeEdge.second.first = polygonUfield->GetTuple1(vertexId1);
139 rangeEdge.second.second = polygonVfield->GetTuple1(vertexId1);
140
141 inputPolygon_.push_back(rangeEdge);
142 }
143
144 for(size_t i = 0; i < threadedTriangleList_.size(); i++) {
145 threadedTriangleList_[i].clear();
146 this->setTriangleList(i, &(threadedTriangleList_[i]));
147 threadedVertexList_[i].clear();
148 this->setVertexList(i, &(threadedVertexList_[i]));
149 }
150
151#ifndef TTK_ENABLE_DOUBLE_TEMPLATING
152 if(dataUfield->GetDataType() != dataVfield->GetDataType()) {
153 this->printErr(
154 "Scalar fields should have same input type. Use TTKPointDataConverter or "
155 "TTKArrayEditor to convert array types.");
156 return 0;
157 }
158 switch(dataUfield->GetDataType()) {
159 vtkTemplateMacro((dispatch<VTK_TT, VTK_TT>(triangulation)));
160 }
161#else
162 switch(vtkTemplate2PackMacro(
163 dataUfield->GetDataType(), dataVfield->GetDataType())) {
164 vtkTemplate2Macro((dispatch<VTK_T1, VTK_T2>(triangulation)));
165 }
166#endif // TTK_ENABLE_DOUBLE_TEMPLATING
167
168 // prepare the VTK output
169 // NOTE: right now, there is a copy of the output data. this is no good.
170 // to fix.
171
172 size_t triangleNumber = 0;
173
174 for(size_t i = 0; i < threadedTriangleList_.size(); i++) {
175 triangleNumber += threadedTriangleList_[i].size();
176 }
177
178 vtkNew<vtkPoints> outputVertexList{};
179 vtkNew<vtkDoubleArray> outputU{};
180 vtkNew<vtkDoubleArray> outputV{};
181 vtkNew<vtkDoubleArray> outputParameterization{};
182 vtkNew<vtkCellArray> outputTriangleList{};
183 vtkNew<ttkSimplexIdTypeArray> outputEdgeIds{};
184 vtkNew<ttkSimplexIdTypeArray> outputTetIds{};
185 vtkNew<ttkSimplexIdTypeArray> outputCaseIds{};
186
187 if(RangeCoordinates) {
188 outputU->SetName(dataUfield->GetName());
189 outputU->SetNumberOfTuples(outputVertexList_.size());
190
191 outputV->SetName(dataVfield->GetName());
192 outputV->SetNumberOfTuples(outputVertexList_.size());
193 }
194
195 if(EdgeParameterization) {
196 outputParameterization->SetName("EdgeParameterization");
197 outputParameterization->SetNumberOfTuples(outputVertexList_.size());
198 }
199
200 outputVertexList->SetNumberOfPoints(outputVertexList_.size());
201 output->SetPoints(outputVertexList);
202
203#ifdef TTK_ENABLE_OPENMP
204#pragma omp parallel for num_threads(threadNumber_)
205#endif
206 for(size_t i = 0; i < outputVertexList_.size(); i++) {
207 outputVertexList->SetPoint(i, outputVertexList_[i].p_[0],
208 outputVertexList_[i].p_[1],
209 outputVertexList_[i].p_[2]);
210 if(RangeCoordinates) {
211 outputU->SetTuple1(i, outputVertexList_[i].uv_.first);
212 outputV->SetTuple1(i, outputVertexList_[i].uv_.second);
213 }
214 if(EdgeParameterization) {
215 outputParameterization->SetTuple1(i, outputVertexList_[i].t_);
216 }
217 }
218 if(RangeCoordinates) {
219 output->GetPointData()->AddArray(outputU);
220 output->GetPointData()->AddArray(outputV);
221 } else {
222 output->GetPointData()->RemoveArray(dataUfield->GetName());
223 output->GetPointData()->RemoveArray(dataVfield->GetName());
224 }
225 if(EdgeParameterization) {
226 output->GetPointData()->AddArray(outputParameterization);
227 } else {
228 output->GetPointData()->RemoveArray("EdgeParameterization");
229 }
230
231 if(EdgeIds) {
232 outputEdgeIds->SetName("EdgeIds");
233 outputEdgeIds->SetNumberOfTuples(triangleNumber);
234 }
235
236 if(TetIds) {
237 outputTetIds->SetName("TetIds");
238 outputTetIds->SetNumberOfTuples(triangleNumber);
239 }
240
241 if(CaseIds) {
242 outputCaseIds->SetName("CaseIds");
243 outputCaseIds->SetNumberOfTuples(triangleNumber);
244 }
245
246 vtkNew<vtkIdList> idList{};
247 idList->SetNumberOfIds(3);
248
249 triangleNumber = 0;
250 for(size_t i = 0; i < threadedTriangleList_.size(); i++) {
251 for(size_t j = 0; j < threadedTriangleList_[i].size(); j++) {
252 for(int k = 0; k < 3; k++) {
253 idList->SetId(k, threadedTriangleList_[i][j].vertexIds_[k]);
254 }
255 outputTriangleList->InsertNextCell(idList);
256 if(EdgeIds) {
257 outputEdgeIds->SetTuple1(triangleNumber, i);
258 }
259 if(TetIds) {
260 outputTetIds->SetTuple1(
261 triangleNumber, threadedTriangleList_[i][j].tetId_);
262 }
263 if(CaseIds) {
264 outputCaseIds->SetTuple1(
265 triangleNumber, threadedTriangleList_[i][j].caseId_);
266 }
267 triangleNumber++;
268 }
269 }
270 output->SetPolys(outputTriangleList);
271 if(EdgeIds) {
272 output->GetCellData()->AddArray(outputEdgeIds);
273 } else {
274 output->GetCellData()->RemoveArray("EdgeIds");
275 }
276 if(TetIds) {
277 output->GetCellData()->AddArray(outputTetIds);
278 } else {
279 output->GetCellData()->RemoveArray("TetIds");
280 }
281 if(CaseIds) {
282 output->GetCellData()->AddArray(outputCaseIds);
283 } else {
284 output->GetCellData()->RemoveArray("CaseIds");
285 }
286
287 return 1;
288}
#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)
TTK VTK-filter that computes fiber surfaces.
int RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) override
int FillInputPortInformation(int port, vtkInformation *info) override
int FillOutputPortInformation(int port, vtkInformation *info) override
int dispatch(ttk::Triangulation *const triangulation)
static void * GetVoidPointer(vtkDataArray *array, vtkIdType start=0)
Definition: ttkUtils.cpp:225
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
int setGlobalVertexList(std::vector< Vertex > *globalList)
Definition: FiberSurface.h:126
int setInputField(const void *uField, const void *vField)
Definition: FiberSurface.h:131
int setPolygonEdgeNumber(const SimplexId &polygonEdgeNumber)
Definition: FiberSurface.h:166
int setPointMerging(const bool &onOff)
Definition: FiberSurface.h:139
int setPointMergingThreshold(const double &threshold)
Definition: FiberSurface.h:144
int setPolygon(const std::vector< std::pair< std::pair< double, double >, std::pair< double, double > > > *polygon)
Definition: FiberSurface.h:159
int setVertexList(const SimplexId &polygonEdgeId, std::vector< Vertex > *vertexList)
Definition: FiberSurface.h:209
int setTriangleList(const SimplexId &polygonEdgeId, std::vector< Triangle > *triangleList)
Definition: FiberSurface.h:189
void preconditionTriangulation(AbstractTriangulation *triangulation)
Definition: FiberSurface.h:202
Triangulation is a class that provides time and memory efficient traversal methods on triangulations ...
Definition: Triangulation.h:48
AbstractTriangulation * getData()
Triangulation::Type getType() const
int SimplexId
Identifier type for simplices of any dimension.
Definition: DataTypes.h:22
vtkStandardNewMacro(ttkFiberSurface)