80 vtkInformationVector **inputVector,
81 vtkInformationVector *outputVector) {
83 const auto input = vtkDataSet::GetData(inputVector[0]);
84 auto sheet0 = vtkUnstructuredGrid::GetData(outputVector, 0);
85 auto sheet1 = vtkUnstructuredGrid::GetData(outputVector, 1);
86 auto sheet2 = vtkUnstructuredGrid::GetData(outputVector, 2);
87 auto sheet3 = vtkDataSet::GetData(outputVector, 3);
90 if(triangulation ==
nullptr) {
95 const auto uComponent = this->GetInputArrayToProcess(0, inputVector);
96 const auto vComponent = this->GetInputArrayToProcess(1, inputVector);
98 input, 0, triangulation,
false, 2, ForceInputOffsetScalarField);
100 input, 1, triangulation,
false, 3, ForceInputOffsetScalarField);
104 if(uComponent ==
nullptr || vComponent ==
nullptr) {
108 this->
printMsg(
"U-component: `" + std::string{uComponent->GetName()} +
"'");
109 this->
printMsg(
"V-component: `" + std::string{vComponent->GetName()} +
"'");
116#ifndef TTK_ENABLE_DOUBLE_TEMPLATING
117 if(uComponent->GetDataType() != vComponent->GetDataType()) {
119 "Scalar fields should have same input type. Use TTKPointDataConverter or "
120 "TTKArrayEditor to convert array types.");
123 switch(uComponent->GetDataType()) {
130 switch(vtkTemplate2PackMacro(
131 uComponent->GetDataType(), vComponent->GetDataType())) {
140 this->
printMsg(
"Preparing the VTK output...");
146 int vertexNumber = 0;
147 for(
size_t i = 0; i < sheet0segmentation->size(); i++) {
148 int const sheet0Id = (*sheet0segmentation)[i];
150 const ReebSpace::Sheet0 *sheet = this->
get0sheet(sheet0Id);
151 if(sheet !=
nullptr && !sheet->pruned_) {
156 vtkNew<vtkPoints>
const sheet0Points{};
157 if(!sheet0->GetPoints())
158 sheet0->SetPoints(sheet0Points);
160 sheet0->GetPoints()->SetNumberOfPoints(vertexNumber);
162 vtkNew<vtkDoubleArray> vertexScalarsU{};
163 vtkNew<vtkDoubleArray> vertexScalarsV{};
165 vertexScalarsU->SetNumberOfTuples(vertexNumber);
166 vertexScalarsU->SetName(uComponent->GetName());
167 vertexScalarsV->SetNumberOfTuples(vertexNumber);
168 vertexScalarsV->SetName(vComponent->GetName());
170 sheet0->GetPointData()->RemoveArray(uComponent->GetName());
171 sheet0->GetPointData()->RemoveArray(vComponent->GetName());
174 vtkNew<ttkSimplexIdTypeArray> vertexIds{};
175 if(ZeroSheetVertexId) {
176 vertexIds->SetNumberOfTuples(vertexNumber);
182 vtkNew<vtkSignedCharArray> vertexTypes{};
184 vertexTypes->SetNumberOfTuples(vertexNumber);
185 vertexTypes->SetName(
"SheetType");
187 sheet0->GetPointData()->RemoveArray(
"SheetType");
190 vtkNew<ttkSimplexIdTypeArray> vertexSheetId{};
192 vertexSheetId->SetNumberOfTuples(vertexNumber);
193 vertexSheetId->SetName(
"0-SheetId");
195 sheet0->GetPointData()->RemoveArray(
"0-SheetId");
200 for(
size_t i = 0; i < sheet0segmentation->size(); i++) {
201 int const sheet0Id = (*sheet0segmentation)[i];
204 const ReebSpace::Sheet0 *sheet = this->
get0sheet(sheet0Id);
206 if(sheet !=
nullptr && !sheet->pruned_) {
207 p = input->GetPoint(i);
209 sheet0->GetPoints()->SetPoint(vertexNumber, p);
212 vertexSheetId->SetTuple1(vertexNumber, (*sheet0segmentation)[i]);
214 if(ZeroSheetVertexId) {
215 vertexIds->SetTuple1(vertexNumber, i);
220 uComponent->GetTuple(i, &u);
221 vComponent->GetTuple(i, &v);
223 vertexScalarsU->SetTuple1(vertexNumber, u);
224 vertexScalarsV->SetTuple1(vertexNumber, v);
227 const ReebSpace::Sheet0 *sht0
228 = this->
get0sheet((*sheet0segmentation)[i]);
229 vertexTypes->SetTuple1(vertexNumber, sht0->type_);
237 sheet0->GetPointData()->AddArray(vertexSheetId);
238 if(ZeroSheetVertexId)
239 sheet0->GetPointData()->AddArray(vertexIds);
241 sheet0->GetPointData()->AddArray(vertexScalarsU);
242 sheet0->GetPointData()->AddArray(vertexScalarsV);
245 sheet0->GetPointData()->AddArray(vertexTypes);
253 vtkNew<vtkPoints>
const sheet1Points{};
254 sheet1->SetPoints(sheet1Points);
256 vtkNew<vtkCellArray> sheet1Edges{};
257 vtkNew<vtkDoubleArray> edgeScalarsU{};
258 vtkNew<vtkDoubleArray> edgeScalarsV{};
261 edgeScalarsU->SetName(uComponent->GetName());
262 edgeScalarsV->SetName(vComponent->GetName());
264 sheet1->GetPointData()->RemoveArray(uComponent->GetName());
265 sheet1->GetPointData()->RemoveArray(vComponent->GetName());
268 vtkNew<ttkSimplexIdTypeArray> edgeVertexIds{};
269 if(OneSheetVertexId) {
279 sheet1->GetCellData()->RemoveArray(
"EdgeType");
282 vtkNew<ttkSimplexIdTypeArray> edgeIds{};
284 edgeIds->SetName(
"EdgeIds");
286 sheet1->GetCellData()->RemoveArray(
"EdgeIds");
289 vtkNew<ttkSimplexIdTypeArray> edgeSheetIds{};
291 edgeSheetIds->SetName(
"1-SheetId");
293 sheet1->GetCellData()->RemoveArray(
"1-SheetId");
298 vtkNew<vtkIdList> idList{};
299 idList->SetNumberOfIds(2);
302 for(
size_t i = 0; i < sheet1segmentation->size(); i++) {
304 int const sheet1Id = (*sheet1segmentation)[i];
308 const ReebSpace::Sheet1 *sheet = this->
get1sheet(sheet1Id);
310 if((sheet) && (!sheet->pruned_)) {
313 triangulation->getEdgeVertex(i, 0, vertexId0);
314 triangulation->getEdgeVertex(i, 1, vertexId1);
316 input->GetPoint(vertexId0, p0);
317 input->GetPoint(vertexId1, p1);
319 sheet1->GetPoints()->InsertNextPoint(p0);
320 sheet1->GetPoints()->InsertNextPoint(p1);
324 uComponent->GetTuple(vertexId0, &u);
325 vComponent->GetTuple(vertexId0, &v);
327 edgeScalarsU->InsertNextTuple1(u);
328 edgeScalarsV->InsertNextTuple1(v);
330 uComponent->GetTuple(vertexId1, &u);
331 vComponent->GetTuple(vertexId1, &v);
333 edgeScalarsU->InsertNextTuple1(u);
334 edgeScalarsV->InsertNextTuple1(v);
337 if(OneSheetVertexId) {
338 edgeVertexIds->InsertNextTuple1(vertexId0);
339 edgeVertexIds->InsertNextTuple1(vertexId1);
342 idList->SetId(0, vertexNumber);
343 idList->SetId(1, vertexNumber + 1);
344 sheet1Edges->InsertNextCell(idList);
348 edgeIds->InsertNextTuple1(i);
351 edgeType->InsertNextTuple1((*edgeTypes)[i]);
354 edgeSheetIds->InsertNextTuple1((*sheet1segmentation)[i]);
360 sheet1->SetCells(VTK_LINE, sheet1Edges);
363 sheet1->GetPointData()->AddArray(edgeScalarsU);
364 sheet1->GetPointData()->AddArray(edgeScalarsV);
366 if(OneSheetVertexId) {
367 sheet1->GetPointData()->AddArray(edgeVertexIds);
370 sheet1->GetCellData()->AddArray(edgeSheetIds);
373 sheet1->GetCellData()->AddArray(edgeIds);
376 sheet1->GetCellData()->AddArray(
edgeType);
383 const std::vector<ttk::FiberSurface::Vertex> *vertexList
386 vtkNew<vtkPoints> sheet2Points{};
387 sheet2Points->SetNumberOfPoints(vertexList->size());
388 sheet2->SetPoints(sheet2Points);
390 vtkNew<vtkDoubleArray> triangleScalarsU{};
391 vtkNew<vtkDoubleArray> triangleScalarsV{};
394 triangleScalarsU->SetName(uComponent->GetName());
395 triangleScalarsU->SetNumberOfTuples(vertexList->size());
396 triangleScalarsV->SetName(vComponent->GetName());
397 triangleScalarsV->SetNumberOfTuples(vertexList->size());
399 sheet2->GetPointData()->RemoveArray(uComponent->GetName());
400 sheet2->GetPointData()->RemoveArray(vComponent->GetName());
403 vtkNew<vtkDoubleArray> triangleParameterization{};
404 if(TwoSheetParameterization) {
405 triangleParameterization->SetName(
"EdgeParameterization");
406 triangleParameterization->SetNumberOfTuples(vertexList->size());
408 sheet2->GetPointData()->RemoveArray(
"EdgeParameterization");
411 int sheet2TriangleNumber = 0;
413 const ReebSpace::Sheet2 *sheet = this->
get2sheet(i);
415 if(sheet !=
nullptr && !sheet->pruned_) {
416 for(
size_t j = 0; j < sheet->triangleList_.size(); j++) {
417 sheet2TriangleNumber += sheet->triangleList_[j].size();
422 vtkNew<vtkCellArray> sheet2Triangles{};
425 vtkNew<ttkSimplexIdTypeArray> triangleSheetIds{};
427 triangleSheetIds->SetName(
"2-SheetId");
428 triangleSheetIds->SetNumberOfTuples(sheet2TriangleNumber);
430 sheet2->GetCellData()->RemoveArray(
"2-SheetId");
433 vtkNew<ttkSimplexIdTypeArray> triangleEdgeIds{};
435 triangleEdgeIds->SetName(
"EdgeIds");
436 triangleEdgeIds->SetNumberOfTuples(sheet2TriangleNumber);
438 sheet2->GetCellData()->RemoveArray(
"EdgeIds");
441 vtkNew<vtkIntArray> triangleEdgeType{};
442 if(TwoSheetEdgeType) {
443 triangleEdgeType->SetName(
"EdgeType");
444 triangleEdgeType->SetNumberOfTuples(sheet2TriangleNumber);
446 sheet2->GetCellData()->RemoveArray(
"EdgeType");
449 vtkNew<ttkSimplexIdTypeArray> triangleTetIds{};
451 triangleTetIds->SetName(
"TetIds");
452 triangleTetIds->SetNumberOfTuples(sheet2TriangleNumber);
454 sheet2->GetCellData()->RemoveArray(
"TetIds");
457 vtkNew<ttkSimplexIdTypeArray> triangleCaseIds{};
459 triangleCaseIds->SetName(
"CaseIds");
460 triangleCaseIds->SetNumberOfTuples(sheet2TriangleNumber);
462 sheet2->GetCellData()->RemoveArray(
"CaseIds");
465 for(
size_t i = 0; i < vertexList->size(); i++) {
466 sheet2->GetPoints()->SetPoint(i, (*vertexList)[i].p_[0],
467 (*vertexList)[i].p_[1],
468 (*vertexList)[i].p_[2]);
471 triangleScalarsU->SetTuple1(i, (*vertexList)[i].uv_.first);
472 triangleScalarsV->SetTuple1(i, (*vertexList)[i].uv_.second);
474 if(TwoSheetParameterization) {
475 triangleParameterization->SetTuple1(i, (*vertexList)[i].t_);
479 sheet2->GetPointData()->AddArray(triangleScalarsU);
480 sheet2->GetPointData()->AddArray(triangleScalarsV);
482 if(TwoSheetParameterization) {
483 sheet2->GetPointData()->AddArray(triangleParameterization);
486 int triangleNumber = 0;
487 idList->SetNumberOfIds(3);
489 const ReebSpace::Sheet2 *sht2 = this->
get2sheet(i);
491 if(sht2 !=
nullptr && !sht2->pruned_) {
492 for(
size_t j = 0; j < sht2->triangleList_.size(); j++) {
494 for(
size_t k = 0; k < sht2->triangleList_[j].size(); k++) {
496 for(
int l = 0; l < 3; l++) {
497 idList->SetId(l, sht2->triangleList_[j][k].vertexIds_[l]);
500 sheet2Triangles->InsertNextCell(idList);
503 triangleSheetIds->SetTuple1(triangleNumber, i);
507 const ReebSpace::Sheet1 *sht1 = this->
get1sheet(sht2->sheet1Id_);
508 triangleEdgeIds->SetTuple1(triangleNumber, sht1->edgeList_[j]);
511 if(TwoSheetEdgeType) {
512 auto polygonEdgeId = sht2->triangleList_[j][k].polygonEdgeId_;
514 triangleEdgeType->SetTuple1(triangleNumber, (*edgeTypes)[edgeId]);
518 triangleTetIds->SetTuple1(
519 triangleNumber, sht2->triangleList_[j][k].tetId_);
522 triangleCaseIds->SetTuple1(
523 triangleNumber, sht2->triangleList_[j][k].caseId_);
531 sheet2->SetCells(VTK_TRIANGLE, sheet2Triangles);
534 sheet2->GetCellData()->AddArray(triangleSheetIds);
537 sheet2->GetCellData()->AddArray(triangleEdgeIds);
539 if(TwoSheetEdgeType) {
540 sheet2->GetCellData()->AddArray(triangleEdgeType);
543 sheet2->GetCellData()->AddArray(triangleTetIds);
546 sheet2->GetCellData()->AddArray(triangleCaseIds);
577 sheet3->ShallowCopy(input);
580 vtkNew<ttkSimplexIdTypeArray> vertexNumberField{};
581 vtkNew<ttkSimplexIdTypeArray> tetNumberField{};
583 if(ThreeSheetTetNumber) {
584 tetNumberField->SetNumberOfTuples(input->GetNumberOfPoints());
585 tetNumberField->SetName(
"3-SheetTetNumber");
586 for(
int i = 0; i < input->GetNumberOfPoints(); i++) {
587 const ReebSpace::Sheet3 *sht3 = this->
get3sheet((*vertex3sheets)[i]);
588 if((sht3) && (!sht3->pruned_))
589 tetNumberField->SetTuple1(i, sht3->tetList_.size());
591 tetNumberField->SetTuple1(i, 0);
593 sheet3->GetPointData()->AddArray(tetNumberField);
595 sheet3->GetPointData()->RemoveArray(
"3-SheetTetNumber");
598 if(ThreeSheetVertexNumber) {
599 vertexNumberField->SetNumberOfTuples(input->GetNumberOfPoints());
600 vertexNumberField->SetName(
"3-SheetVertexNumber");
601 for(
int i = 0; i < input->GetNumberOfPoints(); i++) {
602 const ReebSpace::Sheet3 *sht3 = this->
get3sheet((*vertex3sheets)[i]);
603 if((sht3) && (!sht3->pruned_))
604 vertexNumberField->SetTuple1(i, sht3->vertexList_.size());
606 vertexNumberField->SetTuple1(i, 0);
608 sheet3->GetPointData()->AddArray(vertexNumberField);
610 sheet3->GetPointData()->RemoveArray(
"3-SheetTetNumber");
614 if(ThreeSheetDomainVolume) {
615 domainVolume->SetNumberOfTuples(input->GetNumberOfPoints());
618 for(
int i = 0; i < input->GetNumberOfPoints(); i++) {
619 const ReebSpace::Sheet3 *sht3 = this->
get3sheet((*vertex3sheets)[i]);
620 if((sht3) && (!sht3->pruned_)) {
629 sheet3->GetPointData()->RemoveArray(
"3-SheetDomainVolume");
633 if(ThreeSheetDomainVolume) {
634 rangeArea->SetNumberOfTuples(input->GetNumberOfPoints());
637 for(
int i = 0; i < input->GetNumberOfPoints(); i++) {
638 const ReebSpace::Sheet3 *sht3 = this->
get3sheet((*vertex3sheets)[i]);
639 if((sht3) && (!sht3->pruned_)) {
640 rangeArea->SetTuple1(i, sht3->rangeArea_);
646 sheet3->GetPointData()->AddArray(
rangeArea);
648 sheet3->GetPointData()->RemoveArray(
"3-SheetRangeArea");
652 if(ThreeSheetDomainVolume) {
653 hyperVolume->SetNumberOfTuples(input->GetNumberOfPoints());
656 for(
int i = 0; i < input->GetNumberOfPoints(); i++) {
657 const ReebSpace::Sheet3 *sht3 = this->
get3sheet((*vertex3sheets)[i]);
658 if((sht3) && (!sht3->pruned_)) {
667 sheet3->GetPointData()->RemoveArray(
"3-SheetHyperVolume");
670 vtkNew<ttkSimplexIdTypeArray> vertexSegmentation{};
671 vertexSegmentation->SetName(
"3-SheetId");
672 vertexSegmentation->SetNumberOfTuples(input->GetNumberOfPoints());
673 for(
int i = 0; i < input->GetNumberOfPoints(); i++) {
674 const ReebSpace::Sheet3 *sheet = this->
get3sheet((*vertex3sheets)[i]);
676 vertexSegmentation->SetTuple1(i, sheet->simplificationId_);
678 vertexSegmentation->SetTuple1(i, (*vertex3sheets)[i]);
681 sheet3->GetPointData()->AddArray(vertexSegmentation);
684 vtkNew<ttkSimplexIdTypeArray> tetSegmentation{};
685 tetSegmentation->SetName(
"3-SheetId");
686 tetSegmentation->SetNumberOfTuples(input->GetNumberOfCells());
687 for(
int i = 0; i < input->GetNumberOfCells(); i++) {
688 const ReebSpace::Sheet3 *sht3 = this->
get3sheet((*tet3sheets)[i]);
690 tetSegmentation->SetTuple1(i, sht3->simplificationId_);
692 tetSegmentation->SetTuple1(i, (*tet3sheets)[i]);
695 sheet3->GetCellData()->AddArray(tetSegmentation);