VTK  9.3.20240327
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 
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
internal class used by vtkGenericDataArray to support LookupValue.
void LookupValue(ValueType elem, vtkIdList *ids)
void ClearLookup()
Release any allocated memory for internal data-structures.
list of point or cell ids
Definition: vtkIdList.h:132
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.
vtkIdType InsertNextId(vtkIdType vtkid)
Add the id specified to the end of the list.
Definition: vtkIdList.h:335
void Reset()
Reset to an empty state but retain previously allocated memory.
Definition: vtkIdList.h:243
@ value
Definition: vtkX3D.h:220
@ index
Definition: vtkX3D.h:246
int vtkIdType
Definition: vtkType.h:315