VTK
vtkGenericDataArrayLookupHelper.h
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Visualization Toolkit
4  Module: vtkGenericDataArrayLookupHelper.h
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 =========================================================================*/
22 #ifndef vtkGenericDataArrayLookupHelper_h
23 #define vtkGenericDataArrayLookupHelper_h
24 
25 #include <algorithm>
26 #include <cmath>
27 #include "vtkIdList.h"
28 
29 namespace detail
30 {
31 // this can be removed when C++11 is required.
32 template< class T > struct remove_const { typedef T type; };
33 template< class T > struct remove_const<const T> { typedef T type; };
34 
35 template <typename T, bool> struct has_NaN;
36 
37 template <typename T>
38 struct has_NaN<T, true>
39 {
40 static bool isnan(T x)
41 {
42  return std::isnan(x);
43 }
44 };
45 
46 template <typename T>
47 struct has_NaN<T, false>
48 {
49  static bool isnan(T)
50  {
51  return false;
52  }
53 };
54 
55 template <typename T>
56 bool isnan(T x)
57 {
58  // Select the correct partially specialized type.
60 }
61 }
62 
63 template <class ArrayTypeT>
65 {
66 public:
67  typedef ArrayTypeT ArrayType;
68  typedef typename ArrayType::ValueType ValueType;
69 
70  // Constructor.
72  : AssociatedArray(nullptr), SortedArray(nullptr),
73  FirstValue(nullptr), SortedArraySize(0)
74  {
75  }
77  {
78  this->ClearLookup();
79  }
80 
81  void SetArray(ArrayTypeT *array)
82  {
83  if (this->AssociatedArray != array)
84  {
85  this->ClearLookup();
86  this->AssociatedArray = array;
87  }
88  }
89 
90  vtkIdType LookupValue(ValueType elem)
91  {
92  this->UpdateLookup();
93 
94  if (this->SortedArraySize == 0)
95  {
96  return -1;
97  }
98 
99  if(::detail::isnan(elem))
100  {
101  if(this->SortedArray && ::detail::isnan(this->SortedArray->Value))
102  {
103  return this->SortedArray->Index;
104  }
105  else
106  {
107  return -1;
108  }
109  }
110 
111  ValueWithIndex temp;
112  temp.Value = elem;
113  ValueWithIndex* pos =
114  std::lower_bound(this->FirstValue,
115  this->SortedArray + this->SortedArraySize, temp);
116  if (pos == (this->SortedArray + this->SortedArraySize))
117  {
118  return -1;
119  }
120  if (pos->Value != elem)
121  {
122  return -1;
123  }
124  return pos->Index;
125  }
126 
127  void LookupValue(ValueType elem, vtkIdList* ids)
128  {
129  ids->Reset();
130  this->UpdateLookup();
131 
132  if (this->SortedArraySize == 0)
133  {
134  return;
135  }
136 
137  if(::detail::isnan(elem))
138  {
139  ValueWithIndex *range = this->SortedArray;
140  while (range != this->FirstValue)
141  {
142  ids->InsertNextId(range->Index);
143  ++range;
144  }
145  }
146  else
147  {
148  ValueWithIndex temp;
149  temp.Value = elem;
150  std::pair<ValueWithIndex*, ValueWithIndex*> range =
151  std::equal_range(this->FirstValue,
152  this->SortedArray + this->SortedArraySize, temp);
153  while (range.first != range.second)
154  {
155  // assert(range.first->Value == elem);
156  ids->InsertNextId(range.first->Index);
157  ++range.first;
158  }
159  }
160  }
161 
163 
166  void ClearLookup()
167  {
168  free(this->SortedArray);
169  this->SortedArray = nullptr;
170  this->SortedArraySize = 0;
171  }
173 
174 private:
176  void operator=(const vtkGenericDataArrayLookupHelper&) = delete;
177 
178  struct ValueWithIndex
179  {
181  vtkIdType Index;
182  inline bool operator<(const ValueWithIndex& other) const
183  {
184  return this->Value < other.Value;
185  }
186  };
187 
188  static bool isnan(const ValueWithIndex &tmp)
189  {
190  return ::detail::isnan(tmp.Value);
191  }
192 
193  void UpdateLookup()
194  {
195  if (!this->AssociatedArray || this->SortedArray)
196  {
197  return;
198  }
199 
200  int numComps = this->AssociatedArray->GetNumberOfComponents();
201  this->SortedArraySize =
202  this->AssociatedArray->GetNumberOfTuples() * numComps;
203 
204  if (this->SortedArraySize == 0)
205  {
206  return;
207  }
208 
209  this->SortedArray = reinterpret_cast<ValueWithIndex*>(
210  malloc(this->SortedArraySize * sizeof(ValueWithIndex)));
211  for (vtkIdType cc = 0, max = this->AssociatedArray->GetNumberOfValues();
212  cc < max; ++cc)
213  {
214  ValueWithIndex& item = this->SortedArray[cc];
215  item.Value = this->AssociatedArray->GetValue(cc);
216  item.Index = cc;
217  }
218  this->FirstValue = std::partition(this->SortedArray, this->SortedArray + this->SortedArraySize, isnan);
219  std::sort(this->FirstValue, this->SortedArray + this->SortedArraySize);
220  }
221 
222  ArrayTypeT *AssociatedArray;
223  ValueWithIndex* SortedArray;
224  ValueWithIndex* FirstValue;
225  vtkIdType SortedArraySize;
226 };
227 
228 #endif
229 // VTK-HeaderTest-Exclude: vtkGenericDataArrayLookupHelper.h
void LookupValue(ValueType elem, vtkIdList *ids)
internal class used by vtkGenericDataArray to support LookupValue.
void Reset()
Reset to an empty state but retain previously allocated memory.
Definition: vtkIdList.h:133
int vtkIdType
Definition: vtkType.h:347
VTKCOMMONCORE_EXPORT bool operator<(const vtkUnicodeString &lhs, const vtkUnicodeString &rhs)
void ClearLookup()
Release any allocated memory for internal data-structures.
list of point or cell ids
Definition: vtkIdList.h:36
vtkIdType InsertNextId(const vtkIdType vtkid)
Add the id specified to the end of the list.
Definition: vtkIdList.h:202
#define max(a, b)