TTK
Loading...
Searching...
No Matches
ttkPointSetToSurface.cpp
Go to the documentation of this file.
2
3#include <vtkCellData.h>
4#include <vtkInformation.h>
5#include <vtkPolyData.h>
6
7#include <ttkUtils.h>
8
9#include <array>
10
12
14 this->setDebugMsgPrefix("PointSetToSurface");
15
16 this->SetNumberOfInputPorts(1);
17 this->SetNumberOfOutputPorts(1);
18}
19
21 vtkInformation *info) {
22 if(port == 0) {
23 info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkPointSet");
24 return 1;
25 }
26 return 0;
27}
28
30 vtkInformation *info) {
31 if(port == 0) {
32 info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkPolyData");
33 return 1;
34 }
35 return 0;
36}
37
38template <typename VTK_T1, typename VTK_T2>
40 std::vector<std::tuple<vtkIdType, double, double>> &storage,
41 const VTK_T1 *const values,
42 const VTK_T2 *const values2,
43 const size_t nvalues) {
44
45 for(size_t i = 0; i < nvalues; ++i) {
46 storage.emplace_back(
47 i, static_cast<double>(values[i]), static_cast<double>(values2[i]));
48 }
49}
50
51int ttkPointSetToSurface::RequestData(vtkInformation *ttkNotUsed(request),
52 vtkInformationVector **inputVector,
53 vtkInformationVector *outputVector) {
54 const auto input = vtkPointSet::GetData(inputVector[0]);
55 auto output = vtkPolyData::GetData(outputVector);
56
57 if(input == nullptr || output == nullptr) {
58 this->printErr("Null input data, aborting");
59 return 0;
60 }
61 const auto oa = this->GetInputArrayToProcess(0, inputVector);
62 const auto oa2 = this->GetInputArrayToProcess(1, inputVector);
63 if(oa == nullptr) {
64 this->printErr("Cannot find the required data X array");
65 return 0;
66 }
67 if(oa2 == nullptr) {
68 this->printErr("Cannot find the required data Y array");
69 return 0;
70 }
71
72 const auto nvalues = oa->GetNumberOfTuples();
73
74 // store point index <-> ordering value in vector
75 std::vector<std::tuple<vtkIdType, double, double>> orderedValues;
76
77#ifndef TTK_ENABLE_DOUBLE_TEMPLATING
78 switch(oa->GetDataType()) {
79 vtkTemplateMacro(dispatch(
80 orderedValues, static_cast<VTK_TT *>(ttkUtils::GetVoidPointer(oa)),
81 static_cast<VTK_TT *>(ttkUtils::GetVoidPointer(oa2)), nvalues));
82 }
83#else
84 switch(vtkTemplate2PackMacro(oa->GetDataType(), oa2->GetDataType())) {
85 vtkTemplate2Macro(dispatch(
86 orderedValues, static_cast<VTK_T1 *>(ttkUtils::GetVoidPointer(oa)),
87 static_cast<VTK_T2 *>(ttkUtils::GetVoidPointer(oa2)), nvalues));
88 }
89#endif // TTK_ENABLE_DOUBLE_TEMPLATING
90
91 // Get number of unique values of each array
92 std::vector<double> xValues(orderedValues.size()),
93 yValues(orderedValues.size());
94 for(unsigned int i = 0; i < orderedValues.size(); ++i) {
95 auto tup = orderedValues[i];
96 xValues[i] = std::get<1>(tup);
97 yValues[i] = std::get<2>(tup);
98 }
99 TTK_PSORT(this->threadNumber_, xValues.begin(), xValues.end());
100 const auto nUniqueXValues
101 = std::unique(xValues.begin(), xValues.end()) - xValues.begin();
102 TTK_PSORT(this->threadNumber_, yValues.begin(), yValues.end());
103 const auto nUniqueYValues
104 = std::unique(yValues.begin(), yValues.end()) - yValues.begin();
105
106 if(nUniqueXValues * nUniqueYValues != input->GetNumberOfPoints()) {
107 printErr(
108 "Number of unique values in first array times the number of unique "
109 "values in the second one does not equal the number of points");
110 return 0;
111 }
112
113 // Compare two pairs of index/value according to their values
114 double yRange[2] = {*std::min_element(yValues.begin(), yValues.end()),
115 *std::max_element(yValues.begin(), yValues.end())};
116 double minXInterval = std::numeric_limits<double>::max();
117 for(unsigned int i = 1; i < nUniqueXValues; ++i)
118 minXInterval = std::min(minXInterval, xValues[i] - xValues[i - 1]);
119 const auto normValue = [&](double v) {
120 return (v - yRange[0]) / (yRange[1] - yRange[0]) * minXInterval * 0.99;
121 };
122 const auto cmp = [&](const std::tuple<int, double, double> &a,
123 const std::tuple<int, double, double> &b) {
124 return std::get<1>(a) + normValue(std::get<2>(a))
125 < std::get<1>(b) + normValue(std::get<2>(b));
126 };
127
128 // sort the vector of indices/values in ascending order
129 TTK_PSORT(
130 this->threadNumber_, orderedValues.begin(), orderedValues.end(), cmp);
131
132 // Create point ids matrix
133 std::vector<std::vector<vtkIdType>> orderedIds(
134 nUniqueXValues, std::vector<vtkIdType>(nUniqueYValues));
135 for(unsigned int i = 0; i < nUniqueXValues; ++i) {
136 for(unsigned int j = 0; j < nUniqueYValues; ++j) {
137 auto index = i * nUniqueYValues + j;
138 orderedIds[i][j] = std::get<0>(orderedValues[index]);
139 }
140 }
141
142 // Create new grid
143 vtkNew<vtkPolyData> vtkOutput{};
144 vtkOutput->DeepCopy(input);
145
146 for(unsigned int i = 0; i < nUniqueXValues; ++i) {
147 for(unsigned int j = 0; j < nUniqueYValues; ++j) {
148 if(j != 0) {
149 std::array<vtkIdType, 2> linePoints{
150 orderedIds[i][j - 1], orderedIds[i][j]};
151 vtkOutput->InsertNextCell(VTK_LINE, 2, linePoints.data());
152 }
153
154 if(i != 0) {
155 std::array<vtkIdType, 2> linePoints{
156 orderedIds[i - 1][j], orderedIds[i][j]};
157 vtkOutput->InsertNextCell(VTK_LINE, 2, linePoints.data());
158 }
159
160 if(i != 0 and j != 0) {
161 std::array<vtkIdType, 4> cellPoints{
162 orderedIds[i - 1][j - 1], orderedIds[i - 1][j], orderedIds[i][j],
163 orderedIds[i][j - 1]};
164 vtkOutput->InsertNextCell(VTK_QUAD, 4, cellPoints.data());
165 }
166 }
167 }
168
169 auto noCells = vtkOutput->GetNumberOfCells();
170 vtkNew<vtkIntArray> cellTypeArray{};
171 cellTypeArray->SetName("CellType");
172 cellTypeArray->SetNumberOfTuples(noCells);
173 for(int i = 0; i < noCells; ++i) {
174 cellTypeArray->SetTuple1(i, vtkOutput->GetCellType(i));
175 }
176 vtkOutput->GetCellData()->AddArray(cellTypeArray);
177
178 output->ShallowCopy(vtkOutput);
179
180 return 1;
181}
#define ttkNotUsed(x)
Mark function/method parameters that are not used in the function body at all.
Definition: BaseClass.h:47
#define TTK_PSORT(NTHREADS,...)
Parallel sort macro.
Definition: OpenMP.h:46
TTK VTK-filter that reads a Cinema Spec D Database.
int FillOutputPortInformation(int port, vtkInformation *info) override
int FillInputPortInformation(int port, vtkInformation *info) override
int RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) override
void dispatch(std::vector< std::tuple< vtkIdType, double, double > > &storage, const VTK_T1 *const values, const VTK_T2 *const values2, const size_t nvalues)
static void * GetVoidPointer(vtkDataArray *array, vtkIdType start=0)
Definition: ttkUtils.cpp:225
int threadNumber_
Definition: BaseClass.h:95
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
vtkStandardNewMacro(ttkPointSetToSurface)