VTK  9.3.1
vtkGenericDataArrayLookupHelper.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2 // SPDX-License-Identifier: BSD-3-Clause
10 #ifndef vtkGenericDataArrayLookupHelper_h
11 #define vtkGenericDataArrayLookupHelper_h
12 
13 #include "vtkIdList.h"
14 #include <algorithm>
15 #include <cmath>
16 #include <limits>
17 #include <unordered_map>
18 #include <vector>
19 
21 {
22 VTK_ABI_NAMESPACE_BEGIN
23 template <typename T, bool>
24 struct has_NaN;
25 
26 template <typename T>
27 struct has_NaN<T, true>
28 {
29  static bool isnan(T x) { return std::isnan(x); }
30 };
31 
32 template <typename T>
33 struct has_NaN<T, false>
34 {
35  static bool isnan(T) { return false; }
36 };
37 
38 template <typename T>
39 bool isnan(T x)
40 {
41  // Select the correct partially specialized type.
43 }
44 VTK_ABI_NAMESPACE_END
45 } // namespace detail
46 
47 VTK_ABI_NAMESPACE_BEGIN
48 template <class ArrayTypeT>
50 {
51 public:
52  typedef ArrayTypeT ArrayType;
53  typedef typename ArrayType::ValueType ValueType;
54 
56 
58 
59  void SetArray(ArrayTypeT* array)
60  {
61  if (this->AssociatedArray != array)
62  {
63  this->ClearLookup();
64  this->AssociatedArray = array;
65  }
66  }
67 
68  vtkIdType LookupValue(ValueType elem)
69  {
70  this->UpdateLookup();
71  auto indices = FindIndexVec(elem);
72  if (indices == nullptr)
73  {
74  return -1;
75  }
76  return indices->front();
77  }
78 
79  void LookupValue(ValueType elem, vtkIdList* ids)
80  {
81  ids->Reset();
82  this->UpdateLookup();
83  auto indices = FindIndexVec(elem);
84  if (indices)
85  {
86  ids->Allocate(static_cast<vtkIdType>(indices->size()));
87  for (auto index : *indices)
88  {
89  ids->InsertNextId(index);
90  }
91  }
92  }
93 
95 
98  void ClearLookup()
99  {
100  this->ValueMap.clear();
101  this->NanIndices.clear();
102  }
104 
105 private:
107  void operator=(const vtkGenericDataArrayLookupHelper&) = delete;
108 
109  void UpdateLookup()
110  {
111  if (!this->AssociatedArray || (this->AssociatedArray->GetNumberOfTuples() < 1) ||
112  (!this->ValueMap.empty() || !this->NanIndices.empty()))
113  {
114  return;
115  }
116 
117  vtkIdType num = this->AssociatedArray->GetNumberOfValues();
118  this->ValueMap.reserve(num);
119  for (vtkIdType i = 0; i < num; ++i)
120  {
121  auto value = this->AssociatedArray->GetValue(i);
123  {
124  NanIndices.push_back(i);
125  }
126  this->ValueMap[value].push_back(i);
127  }
128  }
129 
130  // Return a pointer to the relevant vector of indices if specified value was
131  // found in the array.
132  std::vector<vtkIdType>* FindIndexVec(ValueType value)
133  {
134  std::vector<vtkIdType>* indices{ nullptr };
135  if (vtkGenericDataArrayLookupHelper_detail::isnan(value) && !this->NanIndices.empty())
136  {
137  indices = &this->NanIndices;
138  }
139  const auto& pos = this->ValueMap.find(value);
140  if (pos != this->ValueMap.end())
141  {
142  indices = &pos->second;
143  }
144  return indices;
145  }
146 
147  ArrayTypeT* AssociatedArray{ nullptr };
148  std::unordered_map<ValueType, std::vector<vtkIdType>> ValueMap;
149  std::vector<vtkIdType> NanIndices;
150 };
151 
152 VTK_ABI_NAMESPACE_END
153 #endif
154 // 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:134
int vtkIdType
Definition: vtkType.h:315
vtkIdType InsertNextId(vtkIdType vtkid)
Add the id specified to the end of the list.
Definition: vtkIdList.h:226
void ClearLookup()
Release any allocated memory for internal data-structures.
list of point or cell ids
Definition: vtkIdList.h:22
int Allocate(vtkIdType sz, int strategy=0)
Allocate a capacity for sz ids in the list and set the number of stored ids in the list to 0...