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.
40template <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
79template <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<>
90template <typename 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<>
128template <typename T>
129struct 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.
168template <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
bool IsLabelValue(T label) override
std::unordered_set< T > Map
LabelSet(const double *values, int numValues)
std::vector< T > Map
LabelVector(const double *values, int numValues)
bool IsLabelValue(T label) override
bool IsLabelValue(T label) override
SingleLabelValue(const double *values)
provide an efficient numeric label lookup
virtual ~vtkLabelMapLookup()=default
vtkLabelMapLookup(const double *values, int vtkNotUsed(numValues))
static vtkLabelMapLookup< T > * CreateLabelLookup(const double *values, vtkIdType numLabels)
bool IsLabelValueInCache(T label, bool &inLabelSet)
virtual bool IsLabelValue(T label)=0
int vtkIdType
Definition: vtkType.h:332