1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkExtractSelectedThresholds.cxx
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
13
14 =========================================================================*/
15 #include "vtkExtractSelectedThresholds.h"
16
17 #include "vtkCellData.h"
18 #include "vtkCell.h"
19 #include "vtkDataSet.h"
20 #include "vtkDoubleArray.h"
21 #include "vtkIdList.h"
22 #include "vtkIdTypeArray.h"
23 #include "vtkInformation.h"
24 #include "vtkInformationVector.h"
25 #include "vtkObjectFactory.h"
26 #include "vtkPointData.h"
27 #include "vtkSelection.h"
28 #include "vtkSelectionNode.h"
29 #include "vtkSignedCharArray.h"
30 #include "vtkSmartPointer.h"
31 #include "vtkTable.h"
32 #include "vtkThreshold.h"
33 #include "vtkUnstructuredGrid.h"
34
35 #include <algorithm>
36
37 vtkStandardNewMacro(vtkExtractSelectedThresholds);
38
39 //----------------------------------------------------------------------------
vtkExtractSelectedThresholds()40 vtkExtractSelectedThresholds::vtkExtractSelectedThresholds()
41 {
42 this->SetNumberOfInputPorts(2);
43 }
44
45 //----------------------------------------------------------------------------
~vtkExtractSelectedThresholds()46 vtkExtractSelectedThresholds::~vtkExtractSelectedThresholds()
47 {
48 }
49
50 //----------------------------------------------------------------------------
RequestData(vtkInformation * vtkNotUsed (request),vtkInformationVector ** inputVector,vtkInformationVector * outputVector)51 int vtkExtractSelectedThresholds::RequestData(
52 vtkInformation *vtkNotUsed(request),
53 vtkInformationVector **inputVector,
54 vtkInformationVector *outputVector)
55 {
56 // get the info objects
57 vtkInformation *selInfo = inputVector[1]->GetInformationObject(0);
58 vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
59 vtkInformation *outInfo = outputVector->GetInformationObject(0);
60
61
62 vtkDataObject* inputDO = vtkDataObject::GetData(inInfo);
63
64 // verify the input, selection and ouptut
65 if ( ! selInfo )
66 {
67 //When not given a selection, quietly select nothing.
68 return 1;
69 }
70
71 vtkSelection *sel = vtkSelection::GetData(selInfo);
72 vtkSelectionNode *node = 0;
73 if (sel->GetNumberOfNodes() == 1)
74 {
75 node = sel->GetNode(0);
76 }
77 if (!node)
78 {
79 vtkErrorMacro("Selection must have a single node.");
80 return 1;
81 }
82 if (!node->GetProperties()->Has(vtkSelectionNode::CONTENT_TYPE()) ||
83 node->GetProperties()->Get(vtkSelectionNode::CONTENT_TYPE()) != vtkSelectionNode::THRESHOLDS)
84 {
85 vtkErrorMacro("Missing or invalid CONTENT_TYPE.");
86 return 1;
87 }
88
89 if (vtkDataSet* input = vtkDataSet::SafeDownCast(inputDO))
90 {
91 if (input->GetNumberOfCells() == 0 && input->GetNumberOfPoints() == 0)
92 {
93 // empty input, nothing to do..
94 return 1;
95 }
96
97 vtkDataSet *output = vtkDataSet::GetData(outInfo);
98 vtkDebugMacro(<< "Extracting from dataset");
99
100 int thresholdByPointVals = 0;
101 int fieldType = vtkSelectionNode::CELL;
102 if (node->GetProperties()->Has(vtkSelectionNode::FIELD_TYPE()))
103 {
104 fieldType = node->GetProperties()->Get(vtkSelectionNode::FIELD_TYPE());
105 if (fieldType == vtkSelectionNode::POINT)
106 {
107 if (node->GetProperties()->Has(vtkSelectionNode::CONTAINING_CELLS()))
108 {
109 thresholdByPointVals =
110 node->GetProperties()->Get(vtkSelectionNode::CONTAINING_CELLS());
111 }
112 }
113 }
114
115 if (thresholdByPointVals || fieldType == vtkSelectionNode::CELL)
116 {
117 return this->ExtractCells(node, input, output, thresholdByPointVals);
118 }
119 if (fieldType == vtkSelectionNode::POINT)
120 {
121 return this->ExtractPoints(node, input, output);
122 }
123 }
124 else if (vtkTable* inputTable = vtkTable::SafeDownCast(inputDO))
125 {
126 if (inputTable->GetNumberOfRows() == 0)
127 {
128 return 1;
129 }
130 vtkTable* output = vtkTable::GetData(outInfo);
131 return this->ExtractRows(node, inputTable, output);
132 }
133
134 return 0;
135 }
136
137 //----------------------------------------------------------------------------
ExtractCells(vtkSelectionNode * sel,vtkDataSet * input,vtkDataSet * output,int usePointScalars)138 int vtkExtractSelectedThresholds::ExtractCells(
139 vtkSelectionNode *sel,
140 vtkDataSet *input,
141 vtkDataSet *output,
142 int usePointScalars)
143 {
144 //find the values to threshold within
145 vtkDataArray *lims = vtkDataArray::SafeDownCast(sel->GetSelectionList());
146 if (lims == NULL)
147 {
148 vtkErrorMacro(<<"No values to threshold with");
149 return 1;
150 }
151
152 //find out what array we are supposed to threshold in
153 vtkDataArray *inScalars = NULL;
154 bool use_ids = false;
155 if (usePointScalars)
156 {
157 if (sel->GetSelectionList()->GetName())
158 {
159 if (strcmp(sel->GetSelectionList()->GetName(), "vtkGlobalIds") == 0)
160 {
161 inScalars = input->GetPointData()->GetGlobalIds();
162 }
163 else if (strcmp(sel->GetSelectionList()->GetName(), "vtkIndices") == 0)
164 {
165 use_ids = true;
166 }
167 else
168 {
169 inScalars = input->GetPointData()->GetArray(
170 sel->GetSelectionList()->GetName());
171 }
172 }
173 else
174 {
175 inScalars = input->GetPointData()->GetScalars();
176 }
177 }
178 else
179 {
180 if (sel->GetSelectionList()->GetName())
181 {
182 if (strcmp(sel->GetSelectionList()->GetName(), "vtkGlobalIds") == 0)
183 {
184 inScalars = input->GetCellData()->GetGlobalIds();
185 }
186 else if (strcmp(sel->GetSelectionList()->GetName(), "vtkIndices") == 0)
187 {
188 use_ids = true;
189 }
190 else
191 {
192 inScalars = input->GetCellData()->GetArray(
193 sel->GetSelectionList()->GetName());
194 }
195 }
196 else
197 {
198 inScalars = input->GetCellData()->GetScalars();
199 }
200 }
201 if (inScalars == NULL && !use_ids)
202 {
203 vtkErrorMacro("Could not figure out what array to threshold in.");
204 return 1;
205 }
206
207 int inverse = 0;
208 if (sel->GetProperties()->Has(vtkSelectionNode::INVERSE()))
209 {
210 inverse = sel->GetProperties()->Get(vtkSelectionNode::INVERSE());
211 }
212
213 int passThrough = 0;
214 if (this->PreserveTopology)
215 {
216 passThrough = 1;
217 }
218
219 int comp_no = 0;
220 if (sel->GetProperties()->Has(vtkSelectionNode::COMPONENT_NUMBER()))
221 {
222 comp_no = sel->GetProperties()->Get(vtkSelectionNode::COMPONENT_NUMBER());
223 }
224
225 vtkIdType cellId, newCellId;
226 vtkIdList *cellPts, *pointMap = NULL;
227 vtkIdList *newCellPts = NULL;
228 vtkCell *cell = 0;
229 vtkPoints *newPoints = 0;
230 vtkIdType i, ptId, newId, numPts, numCells;
231 int numCellPts;
232 double x[3];
233
234 vtkPointData *pd=input->GetPointData(), *outPD=output->GetPointData();
235 vtkCellData *cd=input->GetCellData(), *outCD=output->GetCellData();
236 int keepCell;
237
238
239 outPD->CopyGlobalIdsOn();
240 outPD->CopyAllocate(pd);
241 outCD->CopyGlobalIdsOn();
242 outCD->CopyAllocate(cd);
243
244 numPts = input->GetNumberOfPoints();
245 numCells = input->GetNumberOfCells();
246
247 vtkDataSet *outputDS = output;
248 vtkSignedCharArray *pointInArray = NULL;
249 vtkSignedCharArray *cellInArray = NULL;
250
251 vtkUnstructuredGrid *outputUG = NULL;
252 vtkIdTypeArray *originalCellIds = NULL;
253 vtkIdTypeArray *originalPointIds = NULL;
254
255 signed char flag = inverse ? 1 : -1;
256
257 if (passThrough)
258 {
259 outputDS->ShallowCopy(input);
260
261 pointInArray = vtkSignedCharArray::New();
262 pointInArray->SetNumberOfComponents(1);
263 pointInArray->SetNumberOfTuples(numPts);
264 for (i=0; i < numPts; i++)
265 {
266 pointInArray->SetValue(i, flag);
267 }
268 pointInArray->SetName("vtkInsidedness");
269 outPD->AddArray(pointInArray);
270 outPD->SetScalars(pointInArray);
271
272 cellInArray = vtkSignedCharArray::New();
273 cellInArray->SetNumberOfComponents(1);
274 cellInArray->SetNumberOfTuples(numCells);
275 for (i=0; i < numCells; i++)
276 {
277 cellInArray->SetValue(i, flag);
278 }
279 cellInArray->SetName("vtkInsidedness");
280 outCD->AddArray(cellInArray);
281 outCD->SetScalars(cellInArray);
282 }
283 else
284 {
285 outputUG = vtkUnstructuredGrid::SafeDownCast(output);
286 outputUG->Allocate(input->GetNumberOfCells());
287 newPoints = vtkPoints::New();
288 newPoints->Allocate(numPts);
289
290 pointMap = vtkIdList::New(); //maps old point ids into new
291 pointMap->SetNumberOfIds(numPts);
292 for (i=0; i < numPts; i++)
293 {
294 pointMap->SetId(i,-1);
295 }
296
297 newCellPts = vtkIdList::New();
298
299 originalCellIds = vtkIdTypeArray::New();
300 originalCellIds->SetName("vtkOriginalCellIds");
301 originalCellIds->SetNumberOfComponents(1);
302 outCD->AddArray(originalCellIds);
303
304 originalPointIds = vtkIdTypeArray::New();
305 originalPointIds->SetName("vtkOriginalPointIds");
306 originalPointIds->SetNumberOfComponents(1);
307 outPD->AddArray(originalPointIds);
308 originalPointIds->Delete();
309 }
310
311 flag = -flag;
312
313 // Check that the scalars of each cell satisfy the threshold criterion
314 for (cellId=0; cellId < input->GetNumberOfCells(); cellId++)
315 {
316 cell = input->GetCell(cellId);
317 cellPts = cell->GetPointIds();
318 numCellPts = cell->GetNumberOfPoints();
319
320 // BUG: This code misses the case where the threshold is contained
321 // completely within the cell but none of its points are inside
322 // the range. Consider as an example the threshold range [1, 2]
323 // with a cell [0, 3].
324 if ( usePointScalars )
325 {
326 keepCell = 0;
327 int totalAbove = 0;
328 int totalBelow = 0;
329 for ( i=0;
330 (i < numCellPts) && (passThrough || !keepCell);
331 i++)
332 {
333 int above = 0;
334 int below = 0;
335 ptId = cellPts->GetId(i);
336 int inside = this->EvaluateValue(
337 inScalars, comp_no, ptId, lims, &above, &below, NULL);
338 totalAbove += above;
339 totalBelow += below;
340 // Have we detected a cell that straddles the threshold?
341 if ((!inside) && (totalAbove && totalBelow))
342 {
343 inside = 1;
344 }
345 if (passThrough && (inside ^ inverse))
346 {
347 pointInArray->SetValue(ptId, flag);
348 cellInArray->SetValue(cellId, flag);
349 }
350 keepCell |= inside;
351 }
352 }
353 else //use cell scalars
354 {
355 keepCell = this->EvaluateValue(inScalars, comp_no, cellId, lims);
356 if (passThrough && (keepCell ^ inverse))
357 {
358 cellInArray->SetValue(cellId, flag);
359 }
360 }
361
362 if ( !passThrough &&
363 (numCellPts > 0) &&
364 (keepCell + inverse == 1) ) // Poor man's XOR
365 {
366 // satisfied thresholding (also non-empty cell, i.e. not VTK_EMPTY_CELL)
367 originalCellIds->InsertNextValue(cellId);
368
369 for (i=0; i < numCellPts; i++)
370 {
371 ptId = cellPts->GetId(i);
372 if ( (newId = pointMap->GetId(ptId)) < 0 )
373 {
374 input->GetPoint(ptId, x);
375 newId = newPoints->InsertNextPoint(x);
376 pointMap->SetId(ptId,newId);
377 outPD->CopyData(pd,ptId,newId);
378 originalPointIds->InsertNextValue(ptId);
379 }
380 newCellPts->InsertId(i,newId);
381 }
382 newCellId = outputUG->InsertNextCell(cell->GetCellType(),newCellPts);
383 outCD->CopyData(cd,cellId,newCellId);
384 newCellPts->Reset();
385 } // satisfied thresholding
386 } // for all cells
387
388 // now clean up / update ourselves
389 if (passThrough)
390 {
391 pointInArray->Delete();
392 cellInArray->Delete();
393 }
394 else
395 {
396 outputUG->SetPoints(newPoints);
397 newPoints->Delete();
398 pointMap->Delete();
399 newCellPts->Delete();
400 originalCellIds->Delete();
401 }
402
403 output->Squeeze();
404
405 return 1;
406 }
407
408 //----------------------------------------------------------------------------
ExtractPoints(vtkSelectionNode * sel,vtkDataSet * input,vtkDataSet * output)409 int vtkExtractSelectedThresholds::ExtractPoints(
410 vtkSelectionNode *sel,
411 vtkDataSet *input,
412 vtkDataSet *output)
413 {
414 //find the values to threshold within
415 vtkDataArray *lims = vtkDataArray::SafeDownCast(sel->GetSelectionList());
416 if (lims == NULL)
417 {
418 vtkErrorMacro(<<"No values to threshold with");
419 return 1;
420 }
421
422 //find out what array we are supposed to threshold in
423 vtkDataArray *inScalars = NULL;
424 bool use_ids = false;
425 if (sel->GetSelectionList()->GetName())
426 {
427 if (strcmp(sel->GetSelectionList()->GetName(), "vtkGlobalIds") == 0)
428 {
429 inScalars = input->GetPointData()->GetGlobalIds();
430 }
431 else if (strcmp(sel->GetSelectionList()->GetName(), "vtkIndices") == 0)
432 {
433 use_ids = true;
434 }
435 else
436 {
437 inScalars = input->GetPointData()->GetArray(
438 sel->GetSelectionList()->GetName());
439 }
440 }
441 else
442 {
443 inScalars = input->GetPointData()->GetScalars();
444 }
445 if (inScalars == NULL && !use_ids)
446 {
447 vtkErrorMacro("Could not figure out what array to threshold in.");
448 return 1;
449 }
450
451 int inverse = 0;
452 if (sel->GetProperties()->Has(vtkSelectionNode::INVERSE()))
453 {
454 inverse = sel->GetProperties()->Get(vtkSelectionNode::INVERSE());
455 }
456
457 int passThrough = 0;
458 if (this->PreserveTopology)
459 {
460 passThrough = 1;
461 }
462
463 int comp_no = 0;
464 if (sel->GetProperties()->Has(vtkSelectionNode::COMPONENT_NUMBER()))
465 {
466 comp_no = sel->GetProperties()->Get(vtkSelectionNode::COMPONENT_NUMBER());
467 }
468
469 vtkIdType numPts = input->GetNumberOfPoints();
470 vtkPointData *inputPD = input->GetPointData();
471 vtkPointData *outPD = output->GetPointData();
472
473 vtkDataSet *outputDS = output;
474 vtkSignedCharArray *pointInArray = NULL;
475
476 vtkUnstructuredGrid * outputUG = NULL;
477 vtkPoints *newPts = vtkPoints::New();
478
479 vtkIdTypeArray* originalPointIds = 0;
480
481 signed char flag = inverse ? 1 : -1;
482
483 if (passThrough)
484 {
485 outputDS->ShallowCopy(input);
486
487 pointInArray = vtkSignedCharArray::New();
488 pointInArray->SetNumberOfComponents(1);
489 pointInArray->SetNumberOfTuples(numPts);
490 for (vtkIdType i=0; i < numPts; i++)
491 {
492 pointInArray->SetValue(i, flag);
493 }
494 pointInArray->SetName("vtkInsidedness");
495 outPD->AddArray(pointInArray);
496 outPD->SetScalars(pointInArray);
497 }
498 else
499 {
500 outputUG = vtkUnstructuredGrid::SafeDownCast(output);
501 outputUG->Allocate(numPts);
502
503 newPts->Allocate(numPts);
504 outputUG->SetPoints(newPts);
505
506 outPD->CopyGlobalIdsOn();
507 outPD->CopyAllocate(inputPD);
508
509 originalPointIds = vtkIdTypeArray::New();
510 originalPointIds->SetNumberOfComponents(1);
511 originalPointIds->SetName("vtkOriginalPointIds");
512 outPD->AddArray(originalPointIds);
513 originalPointIds->Delete();
514 }
515
516 flag = -flag;
517
518 vtkIdType outPtCnt = 0;
519 for (vtkIdType ptId = 0; ptId < numPts; ptId++)
520 {
521 int keepPoint = this->EvaluateValue( inScalars, comp_no, ptId, lims );
522 if (keepPoint ^ inverse)
523 {
524 if (passThrough)
525 {
526 pointInArray->SetValue(ptId, flag);
527 }
528 else
529 {
530 double X[4];
531 input->GetPoint(ptId, X);
532 newPts->InsertNextPoint(X);
533 outPD->CopyData(inputPD, ptId, outPtCnt);
534 originalPointIds->InsertNextValue(ptId);
535 outputUG->InsertNextCell(VTK_VERTEX, 1, &outPtCnt);
536 outPtCnt++;
537 }
538 }
539 }
540
541 if (passThrough)
542 {
543 pointInArray->Delete();
544 }
545 newPts->Delete();
546 output->Squeeze();
547 return 1;
548 }
549
550 //----------------------------------------------------------------------------
ExtractRows(vtkSelectionNode * sel,vtkTable * input,vtkTable * output)551 int vtkExtractSelectedThresholds::ExtractRows(
552 vtkSelectionNode* sel, vtkTable* input, vtkTable* output)
553 {
554 //find the values to threshold within
555 vtkDataArray *lims = vtkDataArray::SafeDownCast(sel->GetSelectionList());
556 if (lims == NULL)
557 {
558 vtkErrorMacro(<<"No values to threshold with");
559 return 1;
560 }
561
562 // Determine the array to threshold.
563 vtkDataArray *inScalars = NULL;
564 bool use_ids = false;
565 if (sel->GetSelectionList()->GetName())
566 {
567 if (strcmp(sel->GetSelectionList()->GetName(), "vtkGlobalIds") == 0)
568 {
569 inScalars = input->GetRowData()->GetGlobalIds();
570 }
571 else if (strcmp(sel->GetSelectionList()->GetName(), "vtkIndices") == 0)
572 {
573 use_ids = true;
574 }
575 else
576 {
577 inScalars = input->GetRowData()->GetArray(
578 sel->GetSelectionList()->GetName());
579 }
580 }
581
582 if (inScalars == NULL && !use_ids)
583 {
584 vtkErrorMacro("Could not figure out what array to threshold in.");
585 return 1;
586 }
587
588 int inverse = 0;
589 if (sel->GetProperties()->Has(vtkSelectionNode::INVERSE()))
590 {
591 inverse = sel->GetProperties()->Get(vtkSelectionNode::INVERSE());
592 }
593
594 int passThrough = 0;
595 if (this->PreserveTopology)
596 {
597 passThrough = 1;
598 }
599
600 int comp_no = 0;
601 if (sel->GetProperties()->Has(vtkSelectionNode::COMPONENT_NUMBER()))
602 {
603 comp_no = sel->GetProperties()->Get(vtkSelectionNode::COMPONENT_NUMBER());
604 }
605
606 vtkDataSetAttributes* inRD = input->GetRowData();
607 vtkDataSetAttributes* outRD = output->GetRowData();
608 vtkSmartPointer<vtkSignedCharArray> rowInArray;
609 vtkSmartPointer<vtkIdTypeArray> originalRowIds;
610 vtkIdType numRows = input->GetNumberOfRows();
611
612 signed char flag = inverse ? 1 : -1;
613
614 if (passThrough)
615 {
616 output->ShallowCopy(input);
617
618 rowInArray = vtkSmartPointer<vtkSignedCharArray>::New();
619 rowInArray->SetNumberOfComponents(1);
620 rowInArray->SetNumberOfTuples(numRows);
621 std::fill(rowInArray->GetPointer(0), rowInArray->GetPointer(0) + numRows, flag);
622 rowInArray->SetName("vtkInsidedness");
623 outRD->AddArray(rowInArray);
624 }
625 else
626 {
627 outRD->CopyGlobalIdsOn();
628 outRD->CopyAllocate(inRD);
629
630 originalRowIds = vtkSmartPointer<vtkIdTypeArray>::New();
631 originalRowIds->SetNumberOfComponents(1);
632 originalRowIds->SetName("vtkOriginalRowIds");
633 originalRowIds->Allocate(numRows);
634 outRD->AddArray(originalRowIds);
635 }
636
637 flag = -flag;
638
639 vtkIdType outRCnt = 0;
640 for (vtkIdType rowId = 0; rowId < numRows; rowId++)
641 {
642 int keepRow = this->EvaluateValue(inScalars, comp_no, rowId, lims);
643 if (keepRow ^ inverse)
644 {
645 if (passThrough)
646 {
647 rowInArray->SetValue(rowId, flag);
648 }
649 else
650 {
651 outRD->CopyData(inRD, rowId, outRCnt);
652 originalRowIds->InsertNextValue(rowId);
653 outRCnt++;
654 }
655 }
656 }
657 outRD->Squeeze();
658 return 1;
659 }
660
661
662 //----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)663 void vtkExtractSelectedThresholds::PrintSelf(ostream& os, vtkIndent indent)
664 {
665 this->Superclass::PrintSelf(os,indent);
666
667 }
668
669 namespace
670 {
671 template <class daT>
TestItem(vtkIdType numLims,daT * limsPtr,double value)672 bool TestItem(vtkIdType numLims, daT* limsPtr, double value)
673 {
674 for (int i = 0; i < numLims; i+=2)
675 {
676 if (value >= limsPtr[i] && value <= limsPtr[i+1])
677 {
678 return true;
679 }
680 }
681 return false;
682 }
683
684 template <class daT>
TestItem(vtkIdType numLims,daT * limsPtr,double value,int & above,int & below,int & inside)685 bool TestItem(vtkIdType numLims, daT* limsPtr, double value,
686 int &above, int &below, int& inside)
687 {
688 bool keepCell = false;
689 for (vtkIdType i = 0; i < numLims; i+=2)
690 {
691 daT low = limsPtr[i];
692 daT high = limsPtr[i+1];
693 if (value >= low && value <= high)
694 {
695 keepCell = true;
696 ++inside;
697 }
698 else if (value < low)
699 {
700 ++below;
701 }
702 else if (value > high)
703 {
704 ++above;
705 }
706 }
707 return keepCell;
708 }
709 };
710 //----------------------------------------------------------------------------
EvaluateValue(vtkDataArray * scalars,int comp_no,vtkIdType id,vtkDataArray * lims)711 int vtkExtractSelectedThresholds::EvaluateValue(
712 vtkDataArray *scalars, int comp_no, vtkIdType id, vtkDataArray *lims)
713 {
714 int keepCell = 0;
715 //check the value in the array against all of the thresholds in lims
716 //if it is inside any, return true
717 double value = 0.0;
718 if (comp_no < 0 && scalars)
719 {
720 // use magnitude.
721 int numComps = scalars->GetNumberOfComponents();
722 const double *tuple = scalars->GetTuple(id);
723 for (int cc=0; cc < numComps; cc++)
724 {
725 value += tuple[cc]*tuple[cc];
726 }
727 value = sqrt(value);
728 }
729 else
730 {
731 value = scalars? scalars->GetComponent(id, comp_no) :
732 static_cast<double>(id); /// <=== precision loss when using id.
733 }
734
735 void* rawLimsPtr = lims->GetVoidPointer(0);
736 vtkIdType numLims = lims->GetNumberOfComponents() * lims->GetNumberOfTuples();
737 switch (lims->GetDataType())
738 {
739 vtkTemplateMacro(
740 keepCell = TestItem<VTK_TT>(numLims,
741 static_cast<VTK_TT*>(rawLimsPtr),
742 value));
743 }
744 return keepCell;
745 }
746
747
748 //----------------------------------------------------------------------------
EvaluateValue(vtkDataArray * scalars,int comp_no,vtkIdType id,vtkDataArray * lims,int * AboveCount,int * BelowCount,int * InsideCount)749 int vtkExtractSelectedThresholds::EvaluateValue(
750 vtkDataArray *scalars, int comp_no, vtkIdType id, vtkDataArray *lims,
751 int *AboveCount, int *BelowCount, int *InsideCount)
752 {
753 double value = 0.0;
754 if (comp_no < 0 && scalars)
755 {
756 // use magnitude.
757 int numComps = scalars->GetNumberOfComponents();
758 const double *tuple = scalars->GetTuple(id);
759 for (int cc=0; cc < numComps; cc++)
760 {
761 value += tuple[cc]*tuple[cc];
762 }
763 value = sqrt(value);
764 }
765 else
766 {
767 value = scalars? scalars->GetComponent(id, comp_no) :
768 static_cast<double>(id); /// <=== precision loss when using id.
769 }
770
771 int keepCell = 0;
772 //check the value in the array against all of the thresholds in lims
773 //if it is inside any, return true
774 int above = 0;
775 int below = 0;
776 int inside = 0;
777
778 void* rawLimsPtr = lims->GetVoidPointer(0);
779 vtkIdType numLims = lims->GetNumberOfComponents() * lims->GetNumberOfTuples();
780 switch (lims->GetDataType())
781 {
782 vtkTemplateMacro(
783 keepCell = TestItem<VTK_TT>(numLims,
784 static_cast<VTK_TT*>(rawLimsPtr),
785 value,
786 above, below, inside));
787 }
788
789 if (AboveCount) *AboveCount = above;
790 if (BelowCount) *BelowCount = below;
791 if (InsideCount) *InsideCount = inside;
792 return keepCell;
793 }
794
795