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