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