VTK  9.3.20240425
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
27VTK_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.
34template <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
73template <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<>
84template <typename 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<>
122template <typename T>
123struct 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.
162template <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
181VTK_ABI_NAMESPACE_END
182#endif
183// 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:315