TTK
Loading...
Searching...
No Matches
ttkExtract.cpp
Go to the documentation of this file.
1#include "BaseClass.h"
2#include <ttkExtract.h>
3
4#include <vtkInformation.h>
5#include <vtkInformationVector.h>
6#include <vtkSmartPointer.h>
7#include <vtkStreamingDemandDrivenPipeline.h>
8#include <vtkVersion.h> // for VTK_VERSION_CHECK via ParaView 5.8.1
9
10#include <vtkMultiBlockDataSet.h>
11#include <vtkTable.h>
12#include <vtkUnstructuredGrid.h>
13
14#include <vtkCellArray.h>
15#include <vtkCellData.h>
16#include <vtkFieldData.h>
17#include <vtkIdTypeArray.h>
18#include <vtkPointData.h>
19#include <vtkSignedCharArray.h>
20#include <vtkThreshold.h>
21
22#include <ttkUtils.h>
23
24#include <set>
25
27
29 this->setDebugMsgPrefix("Extract");
30
31 this->SetNumberOfInputPorts(1);
32 this->SetNumberOfOutputPorts(1);
33}
34ttkExtract::~ttkExtract() = default;
35
36std::string ttkExtract::GetVtkDataTypeName(const int outputType) const {
37 switch(outputType) {
38 case -1: // in case of auto return vtkMultiBlockDataSet
39 case VTK_MULTIBLOCK_DATA_SET:
40 return "vtkMultiBlockDataSet";
41 case VTK_UNSTRUCTURED_GRID:
42 return "vtkUnstructuredGrid";
43 case VTK_POLY_DATA:
44 return "vtkPolyData";
45 case VTK_IMAGE_DATA:
46 return "vtkImageData";
47 case VTK_TABLE:
48 return "vtkTable";
49 default:
50 return "";
51 }
52}
53
54int ttkExtract::FillInputPortInformation(int port, vtkInformation *info) {
55 if(port == 0) {
56 info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkMultiBlockDataSet");
57 info->Append(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataObject");
58 } else
59 return 0;
60 return 1;
61}
62
63int ttkExtract::FillOutputPortInformation(int port, vtkInformation *info) {
64 if(port != 0)
65 return 0;
66
69
70 if(this->OutputType != -1) {
71 std::string DTName = this->GetVtkDataTypeName(this->OutputType);
72 if(DTName.length() < 1) {
73 this->printErr("Unsupported output type");
74 return 0;
75 }
76 info->Set(vtkDataObject::DATA_TYPE_NAME(), DTName.data());
77 } else
79
80 return 1;
81}
82
83// =============================================================================
84// RequestInformation
85// =============================================================================
87 vtkInformation *,
88 vtkInformationVector **ttkNotUsed(inputVector),
89 vtkInformationVector *outputVector) {
90
91 if(this->ExtractionMode == EXTRACTION_MODE::BLOCKS
92 && this->GetOutputType() == VTK_IMAGE_DATA) {
93 auto outInfo = outputVector->GetInformationObject(0);
94 outInfo->Set(
95 vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), this->ImageExtent, 6);
96 }
97
98 return 1;
99}
100
101static int doubleVectorToString(std::string &str,
102 const std::vector<double> &vec) {
103 std::stringstream ss;
104 for(auto &v : vec)
105 ss << v << ",";
106 ss.seekp(-1, ss.cur);
107 str = ss.str().substr(0, ss.str().size() - 1);
108 return 1;
109}
110
111int ttkExtract::ExtractBlocks(vtkDataObject *output,
112 vtkDataObject *input,
113 const std::vector<double> &indices,
114 const bool &extractTuples) const {
115 // print state
116 std::string indicesString = "";
117 doubleVectorToString(indicesString, indices);
118 {
119 std::string outputDataTypeName = this->GetVtkDataTypeName(this->OutputType);
120 std::string extentString = "";
121 if(this->OutputType == VTK_IMAGE_DATA) {
122 extentString = "[" + std::to_string(this->ImageExtent[0]);
123 for(int i = 1; i < 6; i++)
124 extentString += "," + std::to_string(this->ImageExtent[i]);
125 extentString += "]";
126 }
127
129 this->printMsg({{"Extraction Mode",
130 "Block" + std::string(extractTuples ? " Tuples" : "")},
131 {"Output Type", outputDataTypeName + extentString},
132 {"Indices", "[" + indicesString + "]"}});
134 }
135
136 this->printMsg("Extracting blocks [" + indicesString + "]", 0,
138
139 auto inputAsMB = vtkMultiBlockDataSet::SafeDownCast(input);
140 if(!inputAsMB) {
141 this->printErr("Block mode requires 'vtkMultiBlockDataSet' input.");
142 return 0;
143 }
144
145 if(this->OutputType != -1 && extractTuples) {
146 this->printErr("Block Tuple mode requires auto output.");
147 return 0;
148 }
149
150 if(this->OutputType == -1) {
151 // extract multiple blocks (vtkMultiBlockDataSet input/output only)
152 auto outputAsMB = vtkMultiBlockDataSet::SafeDownCast(output);
153
154 if(extractTuples) {
155 int nComponents = inputAsMB->GetNumberOfBlocks();
156
157 for(size_t i = 0; i < indices.size(); i++) {
159 outputAsMB->SetBlock(i, tuple);
160
161 size_t tupleIndex = (size_t)indices[i];
162 for(int c = 0; c < nComponents; c++) {
163 auto blockAsMB
164 = vtkMultiBlockDataSet::SafeDownCast(inputAsMB->GetBlock(c));
165 if(!blockAsMB) {
166 this->printErr("Block Tuple Mode requires a vtkMultiBlockDataSet "
167 "that contains vtkMultiBlockDataSets as input.");
168 return 0;
169 }
170 if(tupleIndex >= blockAsMB->GetNumberOfBlocks()) {
171 this->printErr(
172 "Index out of range (" + std::to_string(tupleIndex) + "/"
173 + std::to_string(blockAsMB->GetNumberOfBlocks()) + ").");
174 return 0;
175 }
176
177 auto block = blockAsMB->GetBlock(tupleIndex);
178 auto copy
179 = vtkSmartPointer<vtkDataObject>::Take(block->NewInstance());
180 copy->ShallowCopy(block);
181 tuple->SetBlock(c, copy);
182 }
183 }
184 } else {
185 for(size_t i = 0; i < indices.size(); i++) {
186 size_t blockIndex = (size_t)indices[i];
187 if(blockIndex >= inputAsMB->GetNumberOfBlocks()) {
188 this->printErr("Index out of range (" + std::to_string(blockIndex)
189 + "/" + std::to_string(inputAsMB->GetNumberOfBlocks())
190 + ").");
191 return 0;
192 }
193
194 auto block = inputAsMB->GetBlock(blockIndex);
195 auto copy = vtkSmartPointer<vtkDataObject>::Take(block->NewInstance());
196 copy->ShallowCopy(block);
197 outputAsMB->SetBlock(i, copy);
198 }
199 }
200 } else {
201 // extract a single block of specified output type
202 if(indices.size() != 1) {
203 this->printErr(
204 "If OutputType is specified then only one block can be extracted.");
205 return 0;
206 }
207
208 size_t blockIndex = (size_t)indices[0];
209 if(blockIndex < inputAsMB->GetNumberOfBlocks()) {
210 auto block = inputAsMB->GetBlock(blockIndex);
211 if(output->GetDataObjectType() != block->GetDataObjectType()) {
212 this->printErr("BlockType does not match OutputType");
213 return 0;
214 }
215 output->ShallowCopy(block);
216
217 } else {
218 this->printErr("Index out of range (" + std::to_string(blockIndex) + "/"
219 + std::to_string(inputAsMB->GetNumberOfBlocks()) + ").");
220 return 0;
221 }
222 }
223
224 // pass field data
225 auto inFD = input->GetFieldData();
226 auto outFD = output->GetFieldData();
227 for(int i = 0; i < inFD->GetNumberOfArrays(); i++)
228 outFD->AddArray(inFD->GetArray(i));
229
230 this->printMsg("Extracting blocks [" + indicesString + "]", 1);
231
232 return 1;
233}
234
235int ttkExtract::ExtractRows(vtkDataObject *output,
236 vtkDataObject *input,
237 const std::vector<double> &indices) const {
238 // print state
239 std::string indicesString = "";
240 doubleVectorToString(indicesString, indices);
241 {
243 this->printMsg(
244 {{"Extraction Mode", "Rows"}, {"Indices", "[" + indicesString + "]"}});
246 }
247
248 ttk::Timer t;
249 this->printMsg("Extracting rows [" + indicesString + "]", 0,
251
252 size_t nValues = indices.size();
253 auto inputAsT = vtkTable::SafeDownCast(input);
254 auto outputAsT = vtkTable::SafeDownCast(output);
255 if(!inputAsT || !outputAsT) {
256 this->printErr("Row mode requires 'vtkTable' input/output.");
257 return 0;
258 }
259
260 size_t nRows = inputAsT->GetNumberOfRows();
261 size_t nCols = inputAsT->GetNumberOfColumns();
262
263 for(size_t j = 0; j < nValues; j++)
264 if(((size_t)indices[j]) >= nRows || indices[j] < 0) {
265 this->printErr("Index out of range (" + std::to_string((size_t)indices[j])
266 + "/" + std::to_string(nRows) + ").");
267 return 0;
268 }
269
270 // Extract row at index
271 for(size_t i = 0; i < nCols; i++) {
272 auto iColumn = inputAsT->GetColumn(i);
273
274 auto oColumn
275 = vtkSmartPointer<vtkAbstractArray>::Take(iColumn->NewInstance());
276 oColumn->SetName(iColumn->GetName());
277 oColumn->SetNumberOfComponents(iColumn->GetNumberOfComponents());
278 oColumn->SetNumberOfTuples(nValues);
279 for(size_t j = 0; j < nValues; j++)
280 oColumn->SetTuple(j, indices[j], iColumn);
281
282 outputAsT->AddColumn(oColumn);
283 }
284
285 outputAsT->GetFieldData()->ShallowCopy(inputAsT->GetFieldData());
286
287 this->printMsg(
288 "Extracting rows [" + indicesString + "]", 1, t.getElapsedTime());
289
290 return 1;
291}
292
293template <typename DT>
294int computeMask_(signed char *mask,
295
296 const size_t &nValues,
297 const DT *values,
298 const std::vector<DT> &min,
299 const std::vector<DT> &max,
300 const size_t &threadNumber) {
301 const size_t nPivotValues = min.size();
302
303#ifdef TTK_ENABLE_OPENMP
304#pragma omp parallel for num_threads(threadNumber)
305#endif // TTK_ENABLE_OPENMP
306 for(size_t i = 0; i < nValues; i++) {
307 const DT &v = values[i];
308
309 bool hasToBeMarked = false;
310 for(size_t j = 0; j < nPivotValues; j++) {
311 if(min[j] <= v && v <= max[j]) {
312 hasToBeMarked = true;
313 break;
314 }
315 }
316
317 mask[i] = hasToBeMarked ? 1 : 0;
318 }
319
320 TTK_FORCE_USE(threadNumber);
321 return 1;
322}
323
324template <typename DT>
325int computeMask(signed char *mask,
326
327 const std::vector<double> &pivotValues,
328 const size_t &nValues,
329 const DT *values,
330 const ttkExtract::VALIDATION_MODE &validationMode,
331 const size_t &threadNumber) {
332
333 const size_t nPivotValues = pivotValues.size();
334 std::vector<DT> pivotValuesMin(nPivotValues);
335 std::vector<DT> pivotValuesMax(nPivotValues);
336
337 const DT delta = std::numeric_limits<DT>::is_integer
338 ? 1
339 : std::numeric_limits<DT>::epsilon();
340
341 for(size_t i = 0; i < nPivotValues; i++) {
342
343 switch(validationMode) {
345 pivotValuesMin[i] = std::numeric_limits<DT>::lowest();
346 pivotValuesMax[i] = ((DT)pivotValues[i]) - delta;
347 break;
348 }
349
351 pivotValuesMin[i] = std::numeric_limits<DT>::lowest();
352 pivotValuesMax[i] = ((DT)pivotValues[i]);
353 break;
354 }
355
358 pivotValuesMin[i] = ((DT)pivotValues[i]);
359 pivotValuesMax[i] = ((DT)pivotValues[i]);
360 break;
361 }
362
364 pivotValuesMin[i] = ((DT)pivotValues[i]);
365 pivotValuesMax[i] = std::numeric_limits<DT>::max();
366 break;
367 }
368
370 pivotValuesMin[i] = ((DT)pivotValues[i]) + delta;
371 pivotValuesMax[i] = std::numeric_limits<DT>::max();
372 break;
373 }
374 }
375 }
376
377 int status = computeMask_<DT>(
378 mask, nValues, values, pivotValuesMin, pivotValuesMax, threadNumber);
379
380 if(validationMode == ttkExtract::VALIDATION_MODE::UNEQUAL)
381 for(size_t i = 0; i < nValues; i++)
382 mask[i] = mask[i] == 0 ? 1 : 0;
383
384 return status;
385}
386
387int ttkExtract::AddMaskArray(vtkDataObject *output,
388 vtkDataObject *input,
389 const std::vector<double> &expressionValues) {
390 ttk::Timer timer;
391
392 this->printMsg(
393 "Computing Mask", 0, 0, this->threadNumber_, ttk::debug::LineMode::REPLACE);
394
395 // check if input/output are of correct type
396 auto inputAsDS = vtkDataSet::SafeDownCast(input);
397 auto outputAsDS = vtkDataSet::SafeDownCast(output);
398 if(!inputAsDS || !outputAsDS) {
399 this->printErr("Masks can only be computed on vtkDataSet inputs.");
400 return 0;
401 }
402
403 // retrieve input array
404 auto inputArray = this->GetInputArrayToProcess(0, input);
405 if(!inputArray || inputArray->GetNumberOfComponents() != 1) {
406 this->printErr("Unable to retrieve input scalar array.");
407 return 0;
408 }
409 std::string inputArrayName = inputArray->GetName();
410 const int inputArrayAssociation = this->GetInputArrayAssociation(0, input);
411 if(inputArrayAssociation != 0 && inputArrayAssociation != 1) {
412 this->printErr("Geometry extraction requires point or cell data.");
413 return 0;
414 }
415 const bool isPointDataArray = this->GetInputArrayAssociation(0, input) == 0;
416
417 // print updated status
418 std::string expressionValuesString = "";
419 doubleVectorToString(expressionValuesString, expressionValues);
420 const std::string ValidationModeS[6] = {"<", "<=", "==", "!=", ">=", ">"};
421 std::string msg = "Computing Mask: '" + inputArrayName + "' "
422 + ValidationModeS[static_cast<int>(this->ValidationMode)]
423 + " [" + expressionValuesString + "]";
424 ;
426
427 // initialize mask array
428 const size_t nInPoints = inputAsDS->GetNumberOfPoints();
429 const size_t nInCells = inputAsDS->GetNumberOfCells();
430 const size_t nOutValues = isPointDataArray ? nInPoints : nInCells;
431
433 maskArray->SetName("Mask");
434 maskArray->SetNumberOfTuples(nOutValues);
435 auto maskArrayData = ttkUtils::GetPointer<signed char>(maskArray);
436
437 // compute mask
438 int status = 0;
439 switch(inputArray->GetDataType()) {
440 vtkTemplateMacro((
441 status = computeMask<VTK_TT>(maskArrayData, expressionValues, nOutValues,
442 ttkUtils::GetPointer<VTK_TT>(inputArray),
443 this->ValidationMode, this->threadNumber_)));
444 }
445 if(!status) {
446 this->printErr("Unable to compute mask");
447 return 0;
448 }
449
450 // add to output
451 outputAsDS->ShallowCopy(inputAsDS);
452 if(isPointDataArray)
453 outputAsDS->GetPointData()->AddArray(maskArray);
454 else
455 outputAsDS->GetCellData()->AddArray(maskArray);
456
457 this->printMsg(msg, 1, timer.getElapsedTime(), this->threadNumber_);
458
459 return 1;
460}
461
462int ttkExtract::ExtractGeometry(vtkDataObject *output,
463 vtkDataObject *input,
464 const std::vector<double> &expressionValues) {
465
466 auto inputAsDS = vtkDataSet::SafeDownCast(input);
467 auto outputAsDS = vtkDataSet::SafeDownCast(output);
468 if(!inputAsDS || !outputAsDS) {
469 this->printErr("Geometry mode requires vtkDataSet input.");
470 return 0;
471 }
472
473 auto maskOutput = vtkSmartPointer<vtkDataSet>::Take(inputAsDS->NewInstance());
474
475 if(!this->AddMaskArray(maskOutput, inputAsDS, expressionValues))
476 return 0;
477
478 if(this->MaskOnly) {
479 outputAsDS->ShallowCopy(maskOutput);
480 } else {
481 ttk::Timer timer;
482 this->printMsg(
483 "Extracting Geometry based on Mask", 0, 0, ttk::debug::LineMode::REPLACE);
484
485 auto outputAsUG = vtkUnstructuredGrid::SafeDownCast(output);
486 if(!outputAsUG) {
487 this->printErr(
488 "Geometry Extraction requires vtkUnstructuredGrid input/output");
489 return 0;
490 }
491
492 const bool isPointDataArray = this->GetInputArrayAssociation(0, input) == 0;
493
494 auto threshold = vtkSmartPointer<vtkThreshold>::New();
495 threshold->SetInputDataObject(maskOutput);
496 threshold->SetInputArrayToProcess(
497 0, 0, 0, isPointDataArray ? 0 : 1, "Mask");
498#if VTK_VERSION_NUMBER < VTK_VERSION_CHECK(9, 2, 0)
499 threshold->ThresholdByUpper(0.5);
500#else
501 threshold->SetThresholdFunction(vtkThreshold::THRESHOLD_UPPER);
502 threshold->SetUpperThreshold(0.5);
503#endif
504 threshold->SetAllScalars(this->CellMode == CELL_MODE::ALL);
505 threshold->Update();
506
507 outputAsDS->ShallowCopy(threshold->GetOutput());
508
509 if(isPointDataArray)
510 outputAsDS->GetPointData()->RemoveArray("Mask");
511 else
512 outputAsDS->GetCellData()->RemoveArray("Mask");
513
514 this->printMsg(
515 "Extracting Geometry based on Mask", 1, timer.getElapsedTime());
516 }
517
518 return 1;
519}
520
521template <class DT>
522int createUniqueValueArray(vtkDataArray *uniqueValueArray,
523 vtkDataArray *valueArray) {
524 std::set<DT> uniqueValues;
525
526 if(uniqueValueArray->GetDataType() != valueArray->GetDataType())
527 return 0;
528
529 size_t nValues
530 = valueArray->GetNumberOfTuples() * valueArray->GetNumberOfComponents();
531 auto valueArrayData = ttkUtils::GetPointer<DT>(valueArray);
532 for(size_t i = 0; i < nValues; i++)
533 uniqueValues.insert(valueArrayData[i]);
534
535 size_t nUniqueValues = uniqueValues.size();
536
537 uniqueValueArray->SetNumberOfComponents(1);
538 uniqueValueArray->SetNumberOfTuples(nUniqueValues);
539
540 auto uniqueValueArrayData = ttkUtils::GetPointer<DT>(uniqueValueArray);
541 auto it = uniqueValues.begin();
542 for(size_t i = 0; i < nUniqueValues; i++) {
543 uniqueValueArrayData[i] = *it;
544 it++;
545 }
546
547 return 1;
548}
549
550int ttkExtract::ExtractArrayValues(vtkDataObject *output,
551 vtkDataObject *input,
552 const std::vector<double> &indices) {
553 size_t nValues = indices.size();
554
555 auto inputArray = this->GetInputArrayToProcess(0, input);
556 if(!inputArray) {
557 this->printErr("Unable to retrieve input array.");
558 return 0;
559 }
560 std::string inputArrayName = inputArray->GetName();
561
562 output->ShallowCopy(input);
563
564 if(this->ExtractUniqueValues) {
565 ttk::Timer t;
566 this->printMsg("Extracting unique values from '" + inputArrayName + "'", 0,
568
569 auto uniqueValueArray
570 = vtkSmartPointer<vtkDataArray>::Take(inputArray->NewInstance());
571 uniqueValueArray->SetName(
572 ("Unique" + std::string(inputArrayName.data())).data());
573
574 int status = 0;
575 switch(inputArray->GetDataType()) {
576 vtkTemplateMacro(
577 status = createUniqueValueArray<VTK_TT>(uniqueValueArray, inputArray));
578 }
579 if(!status) {
580 this->printErr("Unable to compute unique values.");
581 return 0;
582 }
583
584 output->GetFieldData()->AddArray(uniqueValueArray);
585
586 this->printMsg("Extracting unique values from '" + inputArrayName + "'", 1,
587 t.getElapsedTime());
588 } else {
589 ttk::Timer t;
590 std::string indicesString = "";
591 doubleVectorToString(indicesString, indices);
592
593 this->printMsg("Extracting values at [" + indicesString + "] from '"
594 + inputArrayName + "'",
596
597 auto outputArray
598 = vtkSmartPointer<vtkDataArray>::Take(inputArray->NewInstance());
599 outputArray->SetName(
600 ("Extracted" + std::string(inputArray->GetName())).data());
601 outputArray->SetNumberOfComponents(inputArray->GetNumberOfComponents());
602 outputArray->SetNumberOfTuples(indices.size());
603
604 for(size_t i = 0; i < nValues; i++) {
605 size_t index = (size_t)indices[i];
606 size_t inputArraySize = inputArray->GetNumberOfTuples();
607 if(index < inputArraySize) {
608 outputArray->SetTuple(i, index, inputArray);
609 } else {
610 this->printErr("Index out of range (" + std::to_string(i) + "/"
611 + std::to_string(inputArraySize) + ").");
612 return 0;
613 }
614 }
615
616 output->GetFieldData()->AddArray(outputArray);
617
618 this->printMsg("Extracting values at [" + indicesString + "] from '"
619 + inputArrayName + "'",
620 1, t.getElapsedTime());
621 }
622
623 return 1;
624}
625
626int ttkExtract::ExtractArray(vtkDataObject *output,
627 vtkDataObject *input,
628 const std::vector<double> &indices) {
629
630 ttk::Timer t;
631 std::string indicesString;
632 doubleVectorToString(indicesString, indices);
633 this->printMsg("Extracting array with idx [" + indicesString + "] from "
634 + std::string(this->ArrayAttributeType == 0 ? "point"
635 : this->ArrayAttributeType == 1 ? "cell"
636 : "field")
637 + " data",
639
640 output->ShallowCopy(input);
641
642 auto outputAsDS = vtkDataSet::SafeDownCast(output);
643 if(!outputAsDS) {
644 this->printErr("Array extraction requires vtkDataSet input.");
645 return 0;
646 }
647
648 vtkFieldData *inputAttribute
649 = this->ArrayAttributeType == 0 ? outputAsDS->GetPointData()
650 : this->ArrayAttributeType == 1 ? outputAsDS->GetCellData()
651 : outputAsDS->GetFieldData();
652
653 if(indices.size() != 1) {
654 this->printErr("Array extraction can only extract exactly one array.");
655 return 0;
656 }
657
658 if(indices[0] < 0 || indices[0] >= inputAttribute->GetNumberOfArrays()) {
659 this->printErr("Index out of bounds.");
660 return 0;
661 }
662
663 auto inputArray = inputAttribute->GetArray(indices[0]);
664 auto copy = vtkSmartPointer<vtkDataArray>::Take(inputArray->NewInstance());
665 copy->ShallowCopy(inputArray);
666 copy->SetName(this->OutputArrayName.data());
667
668 auto outputAttribute = vtkSmartPointer<vtkFieldData>::New();
669 outputAttribute->AddArray(copy);
670
671 this->ArrayAttributeType == 0
672 ? outputAsDS->GetPointData()->ShallowCopy(outputAttribute)
673 : this->ArrayAttributeType == 1
674 ? outputAsDS->GetCellData()->ShallowCopy(outputAttribute)
675 : outputAsDS->GetFieldData()->ShallowCopy(outputAttribute);
676
677 this->printMsg("Extracting array with indices [" + indicesString + "] from "
678 + std::string(this->ArrayAttributeType == 0 ? "point"
679 : this->ArrayAttributeType == 1 ? "cell"
680 : "field")
681 + " data",
682 1, t.getElapsedTime());
683
684 return 1;
685}
686
687// =============================================================================
688// RequestData
689// =============================================================================
690int ttkExtract::RequestData(vtkInformation *ttkNotUsed(request),
691 vtkInformationVector **inputVector,
692 vtkInformationVector *outputVector) {
693 // Get Input to Output
694 auto input = vtkDataObject::GetData(inputVector[0]);
695 auto output = vtkDataObject::GetData(outputVector);
696
697 // -------------------------------------------------------------------------
698 // Replace Variables in ExpressionString (e.g. {time[2]})
699 // -------------------------------------------------------------------------
700 std::string finalExpressionString;
701 {
702 std::string errorMsg;
704 input->GetFieldData(), finalExpressionString,
705 errorMsg)) {
706 this->printErr(errorMsg);
707 return 0;
708 }
709 }
710
711 std::vector<double> values;
712 ttkUtils::stringListToDoubleVector(finalExpressionString, values);
713
714 auto mode = this->ExtractionMode;
715 if(mode == EXTRACTION_MODE::AUTO) {
716 if(input->IsA("vtkMultiBlockDataSet"))
718 else if(input->IsA("vtkTable"))
720 else {
721 this->printErr("Unable to automatically determine extraction mode.");
722 return 0;
723 }
724 }
725
726 // in case of array or geometry extraction iterate over vtkMultiBlockDataSet
729 size_t nBlocks;
731 && input->IsA("vtkMultiBlockDataSet")) {
732 inputAsMB->ShallowCopy(input);
733 nBlocks = inputAsMB->GetNumberOfBlocks();
734
735 for(size_t b = 0; b < nBlocks; b++) {
736 auto inputBlock = inputAsMB->GetBlock(b);
737
739 if(mode == EXTRACTION_MODE::BLOCKS && !this->MaskOnly)
741 else
742 outputBlock
743 = vtkSmartPointer<vtkDataObject>::Take(inputBlock->NewInstance());
744
745 outputAsMB->SetBlock(b, outputBlock);
746 }
747 output->ShallowCopy(outputAsMB);
748 } else {
749 inputAsMB->SetBlock(0, input);
750 outputAsMB->SetBlock(0, output);
751 nBlocks = 1;
752 }
753
754 switch(mode) {
756 if(!this->ExtractBlocks(output, input, values, false))
757 return 0;
758 break;
759 }
761 if(!this->ExtractBlocks(output, input, values, true))
762 return 0;
763 break;
764 }
766 if(!this->ExtractRows(output, input, values))
767 return 0;
768 break;
769 }
771 for(size_t b = 0; b < nBlocks; b++)
772 if(!this->ExtractGeometry(
773 outputAsMB->GetBlock(b), inputAsMB->GetBlock(b), values))
774 return 0;
775 break;
776 }
778 for(size_t b = 0; b < nBlocks; b++)
779 if(!this->ExtractArrayValues(
780 outputAsMB->GetBlock(b), inputAsMB->GetBlock(b), values))
781 return 0;
782 break;
783 }
785 for(size_t b = 0; b < nBlocks; b++)
786 if(!this->ExtractArray(
787 outputAsMB->GetBlock(b), inputAsMB->GetBlock(b), values))
788 return 0;
789 break;
790 }
791 default: {
792 this->printErr("Unsupported Extraction Mode");
793 return 0;
794 }
795 }
796
798
799 return 1;
800}
#define TTK_FORCE_USE(x)
Force the compiler to use the function/method parameter.
Definition: BaseClass.h:57
#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 VTK-filter that provides multiple methods to extract subsets of an input data object based on a l...
Definition: ttkExtract.h:55
int ExtractGeometry(vtkDataObject *output, vtkDataObject *input, const std::vector< double > &labels)
Definition: ttkExtract.cpp:462
int RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) override
Definition: ttkExtract.cpp:690
int ExtractBlocks(vtkDataObject *output, vtkDataObject *input, const std::vector< double > &indices, const bool &extractTuples) const
Definition: ttkExtract.cpp:111
~ttkExtract() override
virtual std::string GetExpressionString()
int ExtractArray(vtkDataObject *output, vtkDataObject *input, const std::vector< double > &indices)
Definition: ttkExtract.cpp:626
std::string GetVtkDataTypeName(const int outputType) const
Definition: ttkExtract.cpp:36
int ExtractArrayValues(vtkDataObject *output, vtkDataObject *input, const std::vector< double > &indices)
Definition: ttkExtract.cpp:550
int RequestInformation(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) override
Definition: ttkExtract.cpp:86
int FillInputPortInformation(int port, vtkInformation *info) override
Definition: ttkExtract.cpp:54
int ExtractRows(vtkDataObject *output, vtkDataObject *input, const std::vector< double > &indices) const
Definition: ttkExtract.cpp:235
int AddMaskArray(vtkDataObject *output, vtkDataObject *input, const std::vector< double > &labels)
Definition: ttkExtract.cpp:387
virtual int GetOutputType()
int FillOutputPortInformation(int port, vtkInformation *info) override
Definition: ttkExtract.cpp:63
static int replaceVariables(const std::string &iString, vtkFieldData *fieldData, std::string &oString, std::string &errorMsg)
Definition: ttkUtils.cpp:73
static int stringListToDoubleVector(const std::string &iString, std::vector< double > &v)
Definition: ttkUtils.cpp:133
int threadNumber_
Definition: BaseClass.h:95
void setDebugMsgPrefix(const std::string &prefix)
Definition: Debug.h:364
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
double getElapsedTime()
Definition: Timer.h:15
int createUniqueValueArray(vtkDataArray *uniqueValueArray, vtkDataArray *valueArray)
Definition: ttkExtract.cpp:522
vtkStandardNewMacro(ttkExtract)
int computeMask(signed char *mask, const std::vector< double > &pivotValues, const size_t &nValues, const DT *values, const ttkExtract::VALIDATION_MODE &validationMode, const size_t &threadNumber)
Definition: ttkExtract.cpp:325
int computeMask_(signed char *mask, const size_t &nValues, const DT *values, const std::vector< DT > &min, const std::vector< DT > &max, const size_t &threadNumber)
Definition: ttkExtract.cpp:294