59 vtkInformationVector **inputVector,
60 vtkInformationVector *outputVector) {
65 const auto input = vtkDataSet::GetData(inputVector[0]);
66 const auto polygon = vtkUnstructuredGrid::GetData(inputVector[1]);
67 auto output = vtkPolyData::GetData(outputVector);
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);
74 if(dataUfield ==
nullptr || dataVfield ==
nullptr || polygonUfield ==
nullptr
75 || polygonVfield ==
nullptr) {
76 this->
printErr(
"Could not find data array");
80 if(!(input->GetDataObjectType() == VTK_UNSTRUCTURED_GRID
81 || input->GetDataObjectType() == VTK_IMAGE_DATA)) {
82 this->
printErr(
"Unsupported VTK data structure");
87 if(triangulation ==
nullptr) {
92 outputVertexList_.clear();
97 threadedTriangleList_.resize(polygon->GetNumberOfCells());
98 threadedVertexList_.resize(polygon->GetNumberOfCells());
104#ifdef TTK_ENABLE_FIBER_SURFACE_WITH_RANGE_OCTREE
105 if((!RangeOctree) || (dataUfield->GetMTime() > GetMTime())
106 || (dataVfield->GetMTime() > GetMTime())) {
108 this->
printMsg(
"Resetting octree...");
115 inputPolygon_.clear();
117 SimplexId
const cellNumber = polygon->GetNumberOfCells();
118 vtkCellArray *connectivity = polygon->GetCells();
120 if(connectivity->GetData()->GetNumberOfTuples() < 3 * cellNumber) {
121 this->
printErr(
"Error: ill-defined range polygon.");
125#if !defined(_WIN32) || defined(_WIN32) && defined(VTK_USE_64BIT_IDS)
126 const long long int *cellArray = connectivity->GetData()->GetPointer(0);
128 int *pt = connectivity->GetPointer();
129 long long extra_pt = *pt;
130 const long long int *cellArray = &extra_pt;
133 SimplexId vertexId0, vertexId1;
134 std::pair<std::pair<double, double>, std::pair<double, double>> rangeEdge;
136 for(SimplexId i = 0; i < cellNumber; i++) {
138 vertexId0 = cellArray[3 * i + 1];
139 vertexId1 = cellArray[3 * i + 2];
141 rangeEdge.first.first = polygonUfield->GetTuple1(vertexId0);
142 rangeEdge.first.second = polygonVfield->GetTuple1(vertexId0);
144 rangeEdge.second.first = polygonUfield->GetTuple1(vertexId1);
145 rangeEdge.second.second = polygonVfield->GetTuple1(vertexId1);
147 inputPolygon_.push_back(rangeEdge);
150 for(
size_t i = 0; i < threadedTriangleList_.size(); i++) {
151 threadedTriangleList_[i].clear();
153 threadedVertexList_[i].clear();
157#ifndef TTK_ENABLE_DOUBLE_TEMPLATING
158 if(dataUfield->GetDataType() != dataVfield->GetDataType()) {
160 "Scalar fields should have same input type. Use TTKPointDataConverter or "
161 "TTKArrayEditor to convert array types.");
164 switch(dataUfield->GetDataType()) {
165 vtkTemplateMacro((dispatch<VTK_TT, VTK_TT>(triangulation)));
168 switch(vtkTemplate2PackMacro(
169 dataUfield->GetDataType(), dataVfield->GetDataType())) {
170 vtkTemplate2Macro((dispatch<VTK_T1, VTK_T2>(triangulation)));
178 size_t triangleNumber = 0;
180 for(
size_t i = 0; i < threadedTriangleList_.size(); i++) {
181 triangleNumber += threadedTriangleList_[i].size();
184 vtkNew<vtkPoints> outputVertexList{};
185 vtkNew<vtkDoubleArray> outputU{};
186 vtkNew<vtkDoubleArray> outputV{};
187 vtkNew<vtkDoubleArray> outputParameterization{};
188 vtkNew<vtkCellArray> outputTriangleList{};
189 vtkNew<ttkSimplexIdTypeArray> outputEdgeIds{};
190 vtkNew<ttkSimplexIdTypeArray> outputTetIds{};
191 vtkNew<ttkSimplexIdTypeArray> outputCaseIds{};
193 if(RangeCoordinates) {
194 outputU->SetName(dataUfield->GetName());
195 outputU->SetNumberOfTuples(outputVertexList_.size());
197 outputV->SetName(dataVfield->GetName());
198 outputV->SetNumberOfTuples(outputVertexList_.size());
201 if(EdgeParameterization) {
202 outputParameterization->SetName(
"EdgeParameterization");
203 outputParameterization->SetNumberOfTuples(outputVertexList_.size());
206 outputVertexList->SetNumberOfPoints(outputVertexList_.size());
207 output->SetPoints(outputVertexList);
209#ifdef TTK_ENABLE_OPENMP
210#pragma omp parallel for num_threads(threadNumber_)
212 for(
size_t i = 0; i < outputVertexList_.size(); i++) {
213 outputVertexList->SetPoint(i, outputVertexList_[i].p_[0],
214 outputVertexList_[i].p_[1],
215 outputVertexList_[i].p_[2]);
216 if(RangeCoordinates) {
217 outputU->SetTuple1(i, outputVertexList_[i].uv_.first);
218 outputV->SetTuple1(i, outputVertexList_[i].uv_.second);
220 if(EdgeParameterization) {
221 outputParameterization->SetTuple1(i, outputVertexList_[i].t_);
224 if(RangeCoordinates) {
225 output->GetPointData()->AddArray(outputU);
226 output->GetPointData()->AddArray(outputV);
228 output->GetPointData()->RemoveArray(dataUfield->GetName());
229 output->GetPointData()->RemoveArray(dataVfield->GetName());
231 if(EdgeParameterization) {
232 output->GetPointData()->AddArray(outputParameterization);
234 output->GetPointData()->RemoveArray(
"EdgeParameterization");
238 outputEdgeIds->SetName(
"EdgeIds");
239 outputEdgeIds->SetNumberOfTuples(triangleNumber);
243 outputTetIds->SetName(
"TetIds");
244 outputTetIds->SetNumberOfTuples(triangleNumber);
248 outputCaseIds->SetName(
"CaseIds");
249 outputCaseIds->SetNumberOfTuples(triangleNumber);
252 vtkNew<vtkIdList> idList{};
253 idList->SetNumberOfIds(3);
256 for(
size_t i = 0; i < threadedTriangleList_.size(); i++) {
257 for(
size_t j = 0; j < threadedTriangleList_[i].size(); j++) {
258 for(
int k = 0; k < 3; k++) {
259 idList->SetId(k, threadedTriangleList_[i][j].vertexIds_[k]);
261 outputTriangleList->InsertNextCell(idList);
263 outputEdgeIds->SetTuple1(triangleNumber, i);
266 outputTetIds->SetTuple1(
267 triangleNumber, threadedTriangleList_[i][j].tetId_);
270 outputCaseIds->SetTuple1(
271 triangleNumber, threadedTriangleList_[i][j].caseId_);
276 output->SetPolys(outputTriangleList);
278 output->GetCellData()->AddArray(outputEdgeIds);
280 output->GetCellData()->RemoveArray(
"EdgeIds");
283 output->GetCellData()->AddArray(outputTetIds);
285 output->GetCellData()->RemoveArray(
"TetIds");
288 output->GetCellData()->AddArray(outputCaseIds);
290 output->GetCellData()->RemoveArray(
"CaseIds");