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