OGS
VtkColorLookupTable.cpp
Go to the documentation of this file.
1
15#include "VtkColorLookupTable.h"
16
17#include <vtkObjectFactory.h>
18
19#include <cmath>
20#include <sstream>
21
23#include "BaseLib/Logging.h"
24
26
28
30{
31 for (auto& it : _dict)
32 {
33 delete it.second;
34 }
35}
36
37unsigned char VtkColorLookupTable::linInterpolation(unsigned char a,
38 unsigned char b,
39 double p) const
40{
41 return static_cast<unsigned char>(a * (1 - p) + b * p);
42}
43
44unsigned char VtkColorLookupTable::expInterpolation(unsigned char a,
45 unsigned char b,
46 double gamma,
47 double p) const
48{
49 assert(gamma > 0 && gamma < 4);
50 return static_cast<unsigned char>((b - a) * pow(p, gamma) + a);
51}
52
54{
55 double range[2];
56 this->GetTableRange(range);
57 const double interval = range[1] - range[0];
58 this->SetNumberOfTableValues(static_cast<vtkIdType>(ceil(interval)) + 1);
59 // const vtkIdType nColours = this->GetNumberOfTableValues();
60 if (!_dict.empty())
61 {
62 // make sure that color map starts with the first color in the
63 // dictionary
64 unsigned char startcolor[4] = {0, 0, 0, 0};
65 std::pair<std::size_t, unsigned char*> lastValue(0, startcolor);
66
67 for (auto& it : _dict)
68 {
69 double val = (it.first < range[0])
70 ? range[0]
71 : ((it.first > range[1]) ? range[1] : it.first);
72 auto const nextIndex =
73 static_cast<std::size_t>(std::floor(val - range[0]));
74
75 this->SetTableValueRGBA(nextIndex, it.second);
76
77 if (nextIndex - lastValue.first > 0)
78 {
79 for (std::size_t i = lastValue.first + 1; i < nextIndex; i++)
80 {
81 unsigned char int_rgba[4];
82 double pos =
83 (i - lastValue.first) /
84 (static_cast<double>(nextIndex - lastValue.first));
85
87 {
88 for (std::size_t j = 0; j < 4; j++)
89 {
90 int_rgba[j] = linInterpolation(
91 (lastValue.second)[j], (it.second)[j], pos);
92 }
93 }
95 {
96 for (std::size_t j = 0; j < 4; j++)
97 {
98 int_rgba[j] =
99 expInterpolation((lastValue.second)[j],
100 (it.second)[j], 0.2, pos);
101 }
102 }
103 else
104 { // no interpolation
105 for (std::size_t j = 0; j < 4; j++)
106 {
107 int_rgba[j] = (lastValue.second)[j];
108 }
109 }
110
111 this->SetTableValueRGBA(i, int_rgba);
112 }
113 }
114
115 lastValue.first = nextIndex;
116 lastValue.second = it.second;
117 }
118 }
119 else
120 {
121 vtkLookupTable::Build();
122 }
123}
124
127{
128 std::size_t const n_colors(lut.size());
129 for (std::size_t i = 0; i < n_colors; ++i)
130 {
131 setColor(std::get<0>(lut[i]), std::get<1>(lut[i]));
132 }
134 auto const range(lut.getTableRange());
135 SetTableRange(range.first, range.second);
136 Build();
137}
138
139void VtkColorLookupTable::writeToFile(const std::string& filename)
140{
141 std::stringstream strout;
142 strout << "Writing color table to " << filename << " ... ";
143 std::ofstream out(filename.c_str(), std::ios::out);
144
145 std::size_t nColors = this->GetNumberOfTableValues();
146 for (std::size_t i = 0; i < nColors; i++)
147 {
148 unsigned char rgba[4];
149 this->GetTableValue(i, rgba);
150 out << i << "\t" << rgba[0] << "\t" << rgba[1] << "\t" << rgba[2]
151 << "\n";
152 }
153
154 strout << " done." << std::endl;
155 INFO("{:s}", strout.str());
156 out.close();
157}
158
160 unsigned char rgba[4])
161{
162 double value[4];
163
164 for (unsigned i = 0; i < 4; ++i)
165 {
166 value[i] = rgba[i] / 255.0;
167 }
168 vtkLookupTable::SetTableValue(idx, value);
169}
170
171void VtkColorLookupTable::GetTableValue(vtkIdType idx, unsigned char rgba[4])
172{
173 double value[4];
174 vtkLookupTable::GetTableValue(idx, value);
175
176 for (unsigned i = 0; i < 4; ++i)
177 {
178 rgba[i] = static_cast<unsigned char>(value[i] * 255.0);
179 }
180}
181
183 DataHolderLib::Color const& color)
184{
185 auto* dict_rgba = new unsigned char[4];
186 for (std::size_t i = 0; i < 4; i++)
187 {
188 dict_rgba[i] = color[i];
189 }
190 _dict.insert(std::pair<double, unsigned char*>(pos, dict_rgba));
191}
192
193void VtkColorLookupTable::getColor(vtkIdType indx, unsigned char rgba[4]) const
194{
195 indx = ((indx < this->TableRange[0])
196 ? static_cast<vtkIdType>(this->TableRange[0])
197 : (indx >= this->TableRange[1]
198 ? static_cast<vtkIdType>(this->TableRange[1]) - 1
199 : indx));
200 indx = static_cast<std::size_t>(std::floor(
201 (indx - this->TableRange[0]) *
202 (this->NumberOfColors / (this->TableRange[1] - this->TableRange[0]))));
203
204 unsigned char* _rgba;
205 _rgba = this->Table->GetPointer(indx * 4);
206 for (std::size_t i = 0; i < 4; i++)
207 {
208 rgba[i] = _rgba[i];
209 }
210}
Definition of the Color class.
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:35
vtkStandardNewMacro(VtkColorLookupTable)
Definition of the VtkColorLookupTable class.
DataHolderLib::LUTType getInterpolationType() const
std::pair< double, double > getTableRange() const
Calculates and stores a colour lookup table.
~VtkColorLookupTable() override
Destructor.
DataHolderLib::LUTType _type
void setColor(double pos, DataHolderLib::Color const &color)
unsigned char expInterpolation(unsigned char a, unsigned char b, double gamma, double p) const
Interpolates values exponentially. gamma should roughly be in [0,4), for gamma=1 interpolation is lin...
void writeToFile(const std::string &filename)
Exports a color table to a file.
std::map< double, unsigned char * > _dict
void SetTableValueRGBA(vtkIdType idx, unsigned char rgba[4])
Set a value within the LUT.
void Build() override
Builds the colour table based on the previously set parameters. This method should only be called aft...
unsigned char linInterpolation(unsigned char a, unsigned char b, double p) const
Interpolates values linearly.
void GetTableValue(vtkIdType idx, unsigned char rgba[4])
Get a value from the LUT.
VtkColorLookupTable()
Constructor.
void setInterpolationType(DataHolderLib::LUTType type)
Sets the type of interpolation.
void getColor(vtkIdType indx, unsigned char rgba[4]) const
void setLookupTable(DataHolderLib::ColorLookupTable const &lut)
Imports settings of OGS lookup table class.
std::array< unsigned char, 4 > Color
Definition Color.h:24