1#include "transfer_function.h"
3#include <cgv/media/ticks.h>
4#include <cgv/utils/algorithm.h>
19 color_points_ = colors;
20 sort_points_and_update_domain(color_points_);
21 ensure_control_points_cover_domain(color_points_);
22 ensure_control_points_cover_domain(opacity_points_);
26 std::vector<float> positions;
28 std::vector<cgv::rgb> colors = scheme.
quantize(n);
33 opacity_points_ = opacities;
34 std::for_each(opacity_points_.begin(), opacity_points_.end(), [](
const opacity_point_type& point) { cgv::math::saturate(point.second); });
35 sort_points_and_update_domain(opacity_points_);
36 ensure_control_points_cover_domain(opacity_points_);
37 ensure_control_points_cover_domain(color_points_);
42 color_points_.push_back({ x,
color });
43 sort_points_and_update_domain(color_points_);
44 ensure_control_points_cover_domain(opacity_points_);
49 opacity_points_.push_back({ x, cgv::math::saturate(opacity) });
50 sort_points_and_update_domain(opacity_points_);
51 ensure_control_points_cover_domain(color_points_);
55 if(remove_point(color_points_, x)) {
63 if(remove_point(opacity_points_, x)) {
74 float lower_bound = current_domain[0] < domain[0] ? domain[0] : current_domain[0];
75 float upper_bound = current_domain[1] > domain[1] ? domain[1] : current_domain[1];
77 if(!color_points_.empty() && color_points_.front().first != lower_bound)
79 if(!opacity_points_.empty() && opacity_points_.front().first != lower_bound)
82 if(!color_points_.empty() && color_points_.back().first != upper_bound)
84 if(!opacity_points_.empty() && opacity_points_.back().first != upper_bound)
88 const auto is_point_out_of_range = [domain](
const auto& point) {
89 return point.first < domain[0] || point.first > domain[1];
92 const auto remove_points_out_of_range = [domain, &is_point_out_of_range](
auto& points) {
98 auto it = std::find_if(points.begin(), points.end(), is_point_out_of_range);
99 if(it != points.end()) {
109 bool removed_color_points = remove_points_out_of_range(color_points_);
110 bool removed_opacity_points = remove_points_out_of_range(opacity_points_);
111 if(removed_color_points || removed_opacity_points)
114 sort_points_and_update_domain(color_points_);
120 if(current_domain == domain)
123 const auto map_point = [
this, current_domain, domain](
auto& point) {
124 point.first =
map_range_safe(point.first, current_domain[0], current_domain[1], domain[0], domain[1]);
127 if(!color_points_.empty())
128 std::for_each(color_points_.begin(), color_points_.end(), map_point);
130 if(!opacity_points_.empty())
131 std::for_each(opacity_points_.begin(), opacity_points_.end(), map_point);
138 value = cgv::math::clamp(value, domain[0], domain[1]);
150 if(
is_unknown(value) || color_points_.empty())
154 return interpolate(color_points_, value, color_interpolation_);
158 if(opacity_points_.empty())
160 return interpolate(opacity_points_, value, opacity_interpolation_);
167 std::vector<cgv::rgba> values;
168 values.reserve(count);
169 std::transform(colors.begin(), colors.end(), opacities.begin(), std::back_inserter(values), [](
const cgv::rgba&
color,
float opacity) {
170 return cgv::rgba(color, opacity);
177 if(color_points_.empty())
178 return std::vector<cgv::rgb>(count, { 0.0f });
180 std::vector<cgv::rgb> colors =
quantize(color_points_, count, color_interpolation_);
182 std::reverse(colors.begin(), colors.end());
187 if(opacity_points_.empty())
188 return std::vector<float>(count, 1.0f);
189 std::vector<float> opacities =
quantize(opacity_points_, count, opacity_interpolation_);
191 std::reverse(opacities.begin(), opacities.end());
205 return compute_ticks(domain[0], domain[1], request_count);
209 color_points_.clear();
210 opacity_points_.clear();
215 color_points_.clear();
220 opacity_points_.clear();
225 if(color_interpolation_ != interpolation || opacity_interpolation_ != interpolation) {
226 color_interpolation_ = interpolation;
227 opacity_interpolation_ = interpolation;
233 if(color_interpolation_ != interpolation) {
234 color_interpolation_ = interpolation;
240 if(opacity_interpolation_ != interpolation) {
241 opacity_interpolation_ = interpolation;
246bool transfer_function::update_domain() {
250 if(!color_points_.empty()) {
251 domain[0] = color_points_.front().first;
252 domain[1] = color_points_.back().first;
254 if(!opacity_points_.empty()) {
255 domain[0] = std::min(domain[0], opacity_points_.front().first);
256 domain[1] = std::max(domain[1], opacity_points_.back().first);
259 if(old_domain != domain) {
OutputIt zip(const InputIt1 first1, const InputIt1 last1, const InputIt2 first2, OutputIt d_first)
Zip two sequences together to form a single sequene of pairs and store the results in an output range...
void subdivision_sequence(OutputIt output_first, ParamT start, ParamT stop, size_t n)
Generate a sequence of n uniformly-spaced values in [start,stop] and store the result in an output ra...
this header is dependency free