cgv
Loading...
Searching...
No Matches
transfer_function.h
1#pragma once
2
3#include <algorithm>
4#include <vector>
5
6#include <cgv/math/interpolate.h>
7#include <cgv/math/fvec.h>
8
9#include "color.h"
10#include "color_scale.h"
11#include "color_scheme.h"
12
13#include "lib_begin.h"
14
15namespace cgv {
16namespace media {
17
21class CGV_API transfer_function : public color_scale {
22public:
24 enum class InterpolationMode {
25 kStep,
26 kLinear,
27 kSmooth
28 };
29
33 using opacity_type = float;
35 using color_point_type = std::pair<float, color_type>;
37 using opacity_point_type = std::pair<float, opacity_type>;
38
41
46 transfer_function(std::initializer_list<color_point_type> colors);
47
54 transfer_function(std::initializer_list<color_point_type> colors, std::initializer_list<opacity_point_type> opacities);
55
59 bool is_opaque() const override {
60 return opacity_points_.empty();
61 }
62
65 bool is_discrete() const override {
66 return false;
67 }
68
72 bool empty() const {
73 return color_points_.empty() && opacity_points_.empty();
74 }
75
80 void set_color_points(const std::vector<color_point_type>& colors);
81
87 void set_color_points_from_scheme(const cgv::media::continuous_color_scheme& scheme, size_t n);
88
94 void set_opacity_points(const std::vector<opacity_point_type>& opacities);
95
101 void add_color_point(float x, const color_type& color);
102
109 void add_opacity_point(float x, float opacity);
110
115 bool remove_color_point(float x);
116
121 bool remove_opacity_point(float x);
122
129 void set_domain(cgv::vec2 domain) override;
130
135 void rescale(cgv::vec2 domain);
136
138 float normalize_value(float value) const override;
139
141 cgv::rgba map_value(float value) const override;
142
144 cgv::rgb get_mapped_color(float value) const override;
145
147 float get_mapped_opacity(float value) const override;
148
150 std::vector<cgv::rgba> quantize(size_t count) const override;
151
154 std::vector<cgv::rgb> quantize_color(size_t count) const;
155
158 std::vector<float> quantize_opacity(size_t count) const;
159
161 std::vector<float> get_ticks(size_t request_count) const override;
162
164 void clear();
165
167 void clear_color_points();
168
170 void clear_opacity_points();
171
175 const std::vector<color_point_type>& get_color_points() const {
176 return color_points_;
177 }
178
182 const std::vector<opacity_point_type>& get_opacity_points() const {
183 return opacity_points_;
184 }
185
189 void set_interpolation(InterpolationMode interpolation);
190
194 void set_color_interpolation(InterpolationMode interpolation);
195
200 return color_interpolation_;
201 }
202
206 void set_opacity_interpolation(InterpolationMode interpolation);
207
212 return color_interpolation_;
213 }
214
215private:
222 template<typename value_type>
223 bool remove_point(std::vector<std::pair<float, value_type>>& points, float x) {
224 auto it = std::find_if(points.begin(), points.end(), [&x](const std::pair<float, value_type>& point) { return point.first == x; });
225 if(it == points.end() || it == points.begin() || it == --points.end())
226 return false;
227 points.erase(it);
228 return true;
229 }
230
236 template<typename value_type>
237 void ensure_control_points_cover_domain(std::vector<std::pair<float, value_type>>& points) {
238 if(!points.empty()) {
239 cgv::vec2 domain = get_domain();
240 if(domain[0] < points.front().first)
241 points.insert(points.begin(), { domain[0], points.front().second });
242 if(domain[1] > points.back().first)
243 points.push_back({ domain[1], points.back().second });
244 }
245 }
246
251 template<typename value_type>
252 void sort_points_and_update_domain(std::vector<std::pair<float, value_type>>& points) {
253 std::sort(points.begin(), points.end(), [](const auto& lhs, const auto& rhs) { return lhs.first < rhs.first; });
254 // Only call modified if this did not already happen in update_domain.
255 if(!update_domain())
256 modified();
257 }
258
265 template<typename value_type>
266 value_type interpolate_step(const std::vector<std::pair<float, value_type>>& points, float x) const {
267 return cgv::math::detail::interpolate_piece(points, x, [](const value_type& a, const value_type& b, float t_local) { return a; });
268 }
269
276 template<typename value_type>
277 std::vector<value_type> interpolate_step_n(const std::vector<std::pair<float, value_type>>& points, size_t n) const {
278 return cgv::math::detail::interpolate_n(points, [](const value_type& a, const value_type& b, float t_local) { return a; }, n);
279 }
280
288 template<typename value_type>
289 value_type interpolate(const std::vector<std::pair<float, value_type>>& points, float x, InterpolationMode interpolation) const {
290 switch(interpolation) {
291 case InterpolationMode::kStep:
292 return interpolate_step(points, x);
293 case InterpolationMode::kSmooth:
294 return cgv::math::interpolate_smooth_cubic(points, x);
295 default:
296 return cgv::math::interpolate_linear(points, x);
297 }
298 }
299
307 template<typename value_type>
308 std::vector<value_type> quantize(const std::vector<std::pair<float, value_type>>& points, size_t n, InterpolationMode interpolation) const {
309 switch(interpolation) {
310 case InterpolationMode::kStep:
311 return interpolate_step_n(points, n);
312 case InterpolationMode::kSmooth:
313 return cgv::math::interpolate_smooth_cubic_n(points, n);
314 default:
315 return cgv::math::interpolate_linear_n(points, n);
316 }
317 }
318
324 bool update_domain();
325
327 InterpolationMode color_interpolation_ = InterpolationMode::kLinear;
329 InterpolationMode opacity_interpolation_ = InterpolationMode::kLinear;
331 std::vector<color_point_type> color_points_;
333 std::vector<opacity_point_type> opacity_points_;
334};
335
336} // namespace media
337} // namespace cgv
338
339#include <cgv/config/lib_end.h>
Base class defining an interface for color scales.
Definition color_scale.h:22
This class represents a continuous color scheme using an interpolator to convert continuous scalar va...
Implementation of a color_scale with a continuous input domain that maps explicit domain values to co...
InterpolationMode
The interpolation modes supported by the transfer function.
std::pair< float, opacity_type > opacity_point_type
The used opacity control point type.
transfer_function()
Construct using default arguments.
const std::vector< opacity_point_type > & get_opacity_points() const
Get the opacity control points.
InterpolationMode set_opacity_interpolation() const
Get the interpolation mode of the opacity function.
bool is_discrete() const override
See color_scale::is_discrete().
const std::vector< color_point_type > & get_color_points() const
Get the color control points.
InterpolationMode get_color_interpolation() const
Get the interpolation mode of the color function.
std::pair< float, color_type > color_point_type
The used color control point type.
bool empty() const
Check whether the transfer function is empty.
bool is_opaque() const override
Return whether the color scale maps to opacity.
float opacity_type
The used opacity type.
this header is dependency free
Definition print.h:11
cgv::media::color< float, cgv::media::RGB > rgb
declare rgb color type with 32 bit components
Definition color.h:896