113 vtkDataObject *input,
114 const std::vector<double> &indices,
115 const bool &extractTuples)
const {
117 std::string indicesString =
"";
118 doubleVectorToString(indicesString, indices);
120 std::string
const outputDataTypeName
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]);
132 "Block" + std::string(extractTuples ?
" Tuples" :
"")},
133 {
"Output Type", outputDataTypeName + extentString},
134 {
"Indices",
"[" + indicesString +
"]"}});
138 this->
printMsg(
"Extracting blocks [" + indicesString +
"]", 0,
141 auto inputAsMB = vtkMultiBlockDataSet::SafeDownCast(input);
143 this->
printErr(
"Block mode requires 'vtkMultiBlockDataSet' input.");
147 if(this->OutputType != -1 && extractTuples) {
148 this->
printErr(
"Block Tuple mode requires auto output.");
152 if(this->OutputType == -1) {
154 auto outputAsMB = vtkMultiBlockDataSet::SafeDownCast(output);
157 int const nComponents = inputAsMB->GetNumberOfBlocks();
159 for(
size_t i = 0; i < indices.size(); i++) {
161 outputAsMB->SetBlock(i, tuple);
163 size_t const tupleIndex = (size_t)indices[i];
164 for(
int c = 0; c < nComponents; c++) {
166 = vtkMultiBlockDataSet::SafeDownCast(inputAsMB->GetBlock(c));
168 this->
printErr(
"Block Tuple Mode requires a vtkMultiBlockDataSet "
169 "that contains vtkMultiBlockDataSets as input.");
172 if(tupleIndex >= blockAsMB->GetNumberOfBlocks()) {
174 "Index out of range (" + std::to_string(tupleIndex) +
"/"
175 + std::to_string(blockAsMB->GetNumberOfBlocks()) +
").");
179 auto block = blockAsMB->GetBlock(tupleIndex);
182 copy->ShallowCopy(block);
183 tuple->SetBlock(c, copy);
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())
196 auto block = inputAsMB->GetBlock(blockIndex);
198 copy->ShallowCopy(block);
199 outputAsMB->SetBlock(i, copy);
204 if(indices.size() != 1) {
206 "If OutputType is specified then only one block can be extracted.");
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");
217 output->ShallowCopy(block);
220 this->
printErr(
"Index out of range (" + std::to_string(blockIndex) +
"/"
221 + std::to_string(inputAsMB->GetNumberOfBlocks()) +
").");
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));
232 this->
printMsg(
"Extracting blocks [" + indicesString +
"]", 1);
238 vtkDataObject *input,
239 const std::vector<double> &indices)
const {
241 std::string indicesString =
"";
242 doubleVectorToString(indicesString, indices);
246 {{
"Extraction Mode",
"Rows"}, {
"Indices",
"[" + indicesString +
"]"}});
251 this->
printMsg(
"Extracting rows [" + indicesString +
"]", 0,
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.");
262 size_t const nRows = inputAsT->GetNumberOfRows();
263 size_t const nCols = inputAsT->GetNumberOfColumns();
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) +
").");
273 for(
size_t i = 0; i < nCols; i++) {
274 auto iColumn = inputAsT->GetColumn(i);
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);
284 outputAsT->AddColumn(oColumn);
287 outputAsT->GetFieldData()->ShallowCopy(inputAsT->GetFieldData());
290 "Extracting rows [" + indicesString +
"]", 1, t.
getElapsedTime());
329 const std::vector<double> &pivotValues,
330 const size_t &nValues,
333 const size_t &threadNumber) {
335 const size_t nPivotValues = pivotValues.size();
336 std::vector<DT> pivotValuesMin(nPivotValues);
337 std::vector<DT> pivotValuesMax(nPivotValues);
339 const DT delta = std::numeric_limits<DT>::is_integer
341 : std::numeric_limits<DT>::epsilon();
343 for(
size_t i = 0; i < nPivotValues; i++) {
345 switch(validationMode) {
347 pivotValuesMin[i] = std::numeric_limits<DT>::lowest();
348 pivotValuesMax[i] = ((DT)pivotValues[i]) - delta;
353 pivotValuesMin[i] = std::numeric_limits<DT>::lowest();
354 pivotValuesMax[i] = ((DT)pivotValues[i]);
360 pivotValuesMin[i] = ((DT)pivotValues[i]);
361 pivotValuesMax[i] = ((DT)pivotValues[i]);
366 pivotValuesMin[i] = ((DT)pivotValues[i]);
367 pivotValuesMax[i] = std::numeric_limits<DT>::max();
372 pivotValuesMin[i] = ((DT)pivotValues[i]) + delta;
373 pivotValuesMax[i] = std::numeric_limits<DT>::max();
379 int const status = computeMask_<DT>(
380 mask, nValues, values, pivotValuesMin, pivotValuesMax, threadNumber);
383 for(
size_t i = 0; i < nValues; i++)
384 mask[i] = mask[i] == 0 ? 1 : 0;
390 vtkDataObject *input,
391 const std::vector<double> &expressionValues) {
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.");
406 auto inputArray = this->GetInputArrayToProcess(0, input);
407 if(!inputArray || inputArray->GetNumberOfComponents() != 1) {
408 this->
printErr(
"Unable to retrieve input scalar array.");
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.");
417 const bool isPointDataArray = this->GetInputArrayAssociation(0, input) == 0;
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 +
"]";
431 const size_t nInPoints = inputAsDS->GetNumberOfPoints();
432 const size_t nInCells = inputAsDS->GetNumberOfCells();
433 const size_t nOutValues = isPointDataArray ? nInPoints : nInCells;
436 maskArray->SetName(
"Mask");
437 maskArray->SetNumberOfTuples(nOutValues);
438 auto maskArrayData = ttkUtils::GetPointer<signed char>(maskArray);
442 switch(inputArray->GetDataType()) {
444 status = computeMask<VTK_TT>(maskArrayData, expressionValues, nOutValues,
445 ttkUtils::GetPointer<VTK_TT>(inputArray),
449 this->
printErr(
"Unable to compute mask");
454 outputAsDS->ShallowCopy(inputAsDS);
456 outputAsDS->GetPointData()->AddArray(maskArray);
458 outputAsDS->GetCellData()->AddArray(maskArray);
466 vtkDataObject *input,
467 const std::vector<double> &expressionValues) {
469 auto inputAsDS = vtkDataSet::SafeDownCast(input);
470 auto outputAsDS = vtkDataSet::SafeDownCast(output);
471 if(!inputAsDS || !outputAsDS) {
472 this->
printErr(
"Geometry mode requires vtkDataSet input.");
478 if(!this->
AddMaskArray(maskOutput, inputAsDS, expressionValues))
482 outputAsDS->ShallowCopy(maskOutput);
488 auto outputAsUG = vtkUnstructuredGrid::SafeDownCast(output);
491 "Geometry Extraction requires vtkUnstructuredGrid input/output");
495 const bool isPointDataArray = this->GetInputArrayAssociation(0, input) == 0;
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);
504 threshold->SetThresholdFunction(vtkThreshold::THRESHOLD_UPPER);
505 threshold->SetUpperThreshold(0.5);
510 outputAsDS->ShallowCopy(threshold->GetOutput());
513 outputAsDS->GetPointData()->RemoveArray(
"Mask");
515 outputAsDS->GetCellData()->RemoveArray(
"Mask");
526 vtkDataArray *valueArray) {
527 std::set<DT> uniqueValues;
529 if(uniqueValueArray->GetDataType() != valueArray->GetDataType())
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]);
538 size_t const nUniqueValues = uniqueValues.size();
540 uniqueValueArray->SetNumberOfComponents(1);
541 uniqueValueArray->SetNumberOfTuples(nUniqueValues);
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;
554 vtkDataObject *input,
555 const std::vector<double> &indices) {
556 size_t const nValues = indices.size();
558 auto inputArray = this->GetInputArrayToProcess(0, input);
560 this->
printErr(
"Unable to retrieve input array.");
563 std::string
const inputArrayName = inputArray->GetName();
565 output->ShallowCopy(input);
567 if(this->ExtractUniqueValues) {
569 this->
printMsg(
"Extracting unique values from '" + inputArrayName +
"'", 0,
572 auto uniqueValueArray
574 uniqueValueArray->SetName(
575 (
"Unique" + std::string(inputArrayName.data())).data());
578 switch(inputArray->GetDataType()) {
580 status = createUniqueValueArray<VTK_TT>(uniqueValueArray, inputArray));
583 this->
printErr(
"Unable to compute unique values.");
587 output->GetFieldData()->AddArray(uniqueValueArray);
589 this->
printMsg(
"Extracting unique values from '" + inputArrayName +
"'", 1,
593 std::string indicesString =
"";
594 doubleVectorToString(indicesString, indices);
596 this->
printMsg(
"Extracting values at [" + indicesString +
"] from '"
597 + inputArrayName +
"'",
602 outputArray->SetName(
603 (
"Extracted" + std::string(inputArray->GetName())).data());
604 outputArray->SetNumberOfComponents(inputArray->GetNumberOfComponents());
605 outputArray->SetNumberOfTuples(indices.size());
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);
613 this->
printErr(
"Index out of range (" + std::to_string(i) +
"/"
614 + std::to_string(inputArraySize) +
").");
619 output->GetFieldData()->AddArray(outputArray);
621 this->
printMsg(
"Extracting values at [" + indicesString +
"] from '"
622 + inputArrayName +
"'",
630 vtkDataObject *input,
631 const std::vector<double> &indices) {
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"
643 output->ShallowCopy(input);
645 auto outputAsDS = vtkDataSet::SafeDownCast(output);
647 this->
printErr(
"Array extraction requires vtkDataSet input.");
651 vtkFieldData *inputAttribute
652 = this->ArrayAttributeType == 0 ? outputAsDS->GetPointData()
653 : this->ArrayAttributeType == 1 ? outputAsDS->GetCellData()
654 : outputAsDS->GetFieldData();
656 if(indices.size() != 1) {
657 this->
printErr(
"Array extraction can only extract exactly one array.");
661 if(indices[0] < 0 || indices[0] >= inputAttribute->GetNumberOfArrays()) {
662 this->
printErr(
"Index out of bounds.");
666 auto inputArray = inputAttribute->GetArray(indices[0]);
668 copy->ShallowCopy(inputArray);
669 copy->SetName(this->OutputArrayName.data());
672 outputAttribute->AddArray(copy);
674 this->ArrayAttributeType == 0
675 ? outputAsDS->GetPointData()->ShallowCopy(outputAttribute)
676 : this->ArrayAttributeType == 1
677 ? outputAsDS->GetCellData()->ShallowCopy(outputAttribute)
678 : outputAsDS->GetFieldData()->ShallowCopy(outputAttribute);
680 this->
printMsg(
"Extracting array with indices [" + indicesString +
"] from "
681 + std::string(this->ArrayAttributeType == 0 ?
"point"
682 : this->ArrayAttributeType == 1 ?
"cell"
694 vtkInformationVector **inputVector,
695 vtkInformationVector *outputVector) {
697 auto input = vtkDataObject::GetData(inputVector[0]);
698 auto output = vtkDataObject::GetData(outputVector);
703 std::string finalExpressionString;
705 std::string errorMsg;
707 input->GetFieldData(), finalExpressionString,
714 std::vector<double> values;
717 auto mode = this->ExtractionMode;
719 if(input->IsA(
"vtkMultiBlockDataSet"))
721 else if(input->IsA(
"vtkTable"))
724 this->
printErr(
"Unable to automatically determine extraction mode.");
734 && input->IsA(
"vtkMultiBlockDataSet")) {
735 inputAsMB->ShallowCopy(input);
736 nBlocks = inputAsMB->GetNumberOfBlocks();
738 for(
size_t b = 0; b < nBlocks; b++) {
739 auto inputBlock = inputAsMB->GetBlock(b);
748 outputAsMB->SetBlock(b, outputBlock);
750 output->ShallowCopy(outputAsMB);
752 inputAsMB->SetBlock(0, input);
753 outputAsMB->SetBlock(0, output);
774 for(
size_t b = 0; b < nBlocks; b++)
776 outputAsMB->GetBlock(b), inputAsMB->GetBlock(b), values))
781 for(
size_t b = 0; b < nBlocks; b++)
783 outputAsMB->GetBlock(b), inputAsMB->GetBlock(b), values))
788 for(
size_t b = 0; b < nBlocks; b++)
790 outputAsMB->GetBlock(b), inputAsMB->GetBlock(b), values))
795 this->
printErr(
"Unsupported Extraction Mode");
printMsg(debug::output::BOLD+" | | | | | . \\ | | (__| | / __/| |_| / __/|__ _|"+debug::output::ENDCOLOR, debug::Priority::PERFORMANCE, debug::LineMode::NEW, stream)