VTK  9.3.1
vtkLabelMapLookup.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
19 #ifndef vtkLabelMapLookup_h
20 #define vtkLabelMapLookup_h
21 
22 #include "vtkCommonDataModelModule.h"
23 
24 #include <unordered_set>
25 #include <vector>
26 
27 VTK_ABI_NAMESPACE_BEGIN
28 // Determine whether an image label/object has been specified for output.
29 // This requires looking up an image pixel/scalar value and determining
30 // whether it's part of a segmented object. Since this can be relatively
31 // expensive when performed many times, different lookup classes are used
32 // depending on the number of labels specified. A cache is used for the
33 // common case of repeated queries for the same label value.
34 template <typename T>
36 {
40 
41  vtkLabelMapLookup(const double* values, int vtkNotUsed(numValues))
42  {
43  this->CachedValue = static_cast<T>(values[0]);
44  this->CachedOutValue = static_cast<T>(values[0]);
45  this->CachedOutValueInitialized = false;
46  }
47  virtual ~vtkLabelMapLookup() = default;
48  virtual bool IsLabelValue(T label) = 0;
49  bool IsLabelValueInCache(T label, bool& inLabelSet)
50  {
51  if (label == this->CachedValue)
52  {
53  inLabelSet = true;
54  return true;
55  }
56  else if (this->CachedOutValueInitialized && label == this->CachedOutValue)
57  {
58  inLabelSet = false;
59  return true;
60  }
61  else
62  {
63  return false;
64  }
65  }
66 
67  // A factory method for creating the right type of label map based
68  // on the number of labels in the set.
69  static vtkLabelMapLookup<T>* CreateLabelLookup(const double* values, vtkIdType numLabels);
70 }; // vtkLabelMapLookup
71 
72 // Cache a single contour value
73 template <typename T>
75 {
76  SingleLabelValue(const double* values)
77  : vtkLabelMapLookup<T>(values, 1)
78  {
79  }
80  bool IsLabelValue(T label) override { return label == this->CachedValue; }
81 }; // SingleLabelValue
82 
83 // Represent a few contour values with a std::vector<>
84 template <typename T>
85 struct LabelVector : public vtkLabelMapLookup<T>
86 {
87  std::vector<T> Map;
88 
89  LabelVector(const double* values, int numValues)
90  : vtkLabelMapLookup<T>(values, numValues)
91  {
92  for (int vidx = 0; vidx < numValues; vidx++)
93  {
94  Map.push_back(static_cast<T>(values[vidx]));
95  }
96  }
97  bool IsLabelValue(T label) override
98  {
99  bool inLabelSet;
100  // Check the cache
101  if (this->IsLabelValueInCache(label, inLabelSet))
102  {
103  return inLabelSet;
104  }
105 
106  // Not in the cache, check the vector
107  if (std::find(this->Map.begin(), this->Map.end(), label) != this->Map.end())
108  {
109  this->CachedValue = label;
110  return true;
111  }
112  else
113  {
114  this->CachedOutValue = label;
115  this->CachedOutValueInitialized = true;
116  return false;
117  }
118  }
119 }; // LabelVector
120 
121 // Represent many contour values with a std::set<>
122 template <typename T>
123 struct LabelSet : public vtkLabelMapLookup<T>
124 {
125  std::unordered_set<T> Map;
126 
127  LabelSet(const double* values, int numValues)
128  : vtkLabelMapLookup<T>(values, numValues)
129  {
130  for (int vidx = 0; vidx < numValues; vidx++)
131  {
132  Map.insert(static_cast<T>(values[vidx]));
133  }
134  }
135  bool IsLabelValue(T label) override
136  {
137  bool inLabelSet;
138  // Check the cache
139  if (this->IsLabelValueInCache(label, inLabelSet))
140  {
141  return inLabelSet;
142  }
143 
144  // Not in cache, check the map
145  if (this->Map.find(label) != this->Map.end())
146  {
147  this->CachedValue = label;
148  return true;
149  }
150  else
151  {
152  this->CachedOutValue = label;
153  this->CachedOutValueInitialized = true;
154  return false;
155  }
156  }
157 }; // LabelSet
158 
159 // Given a list of label values (represented generically as doubles),
160 // create the appropriate lookup class and add the label values to
161 // the collection of labels.
162 template <typename T>
164  const double* values, vtkIdType numLabels)
165 {
166  // These cutoffs are empirical and can be changed.
167  if (numLabels == 1)
168  {
169  return new SingleLabelValue<T>(values);
170  }
171  else if (numLabels < 20)
172  {
173  return new LabelVector<T>(values, numLabels);
174  }
175  else
176  {
177  return new LabelSet<T>(values, numLabels);
178  }
179 }
180 
181 VTK_ABI_NAMESPACE_END
182 #endif
183 // VTK-HeaderTest-Exclude: vtkLabelMapLookup.h
std::unordered_set< T > Map
bool IsLabelValueInCache(T label, bool &inLabelSet)
int vtkIdType
Definition: vtkType.h:315
provide an efficient numeric label lookup
virtual bool IsLabelValue(T label)=0
bool IsLabelValue(T label) override
SingleLabelValue(const double *values)
LabelVector(const double *values, int numValues)
LabelSet(const double *values, int numValues)
vtkLabelMapLookup(const double *values, int vtkNotUsed(numValues))
static vtkLabelMapLookup< T > * CreateLabelLookup(const double *values, vtkIdType numLabels)
bool IsLabelValue(T label) override
std::vector< T > Map
bool IsLabelValue(T label) override
virtual ~vtkLabelMapLookup()=default