cgv
Loading...
Searching...
No Matches
transfer_function_editor.h
1#pragma once
2
3#include <cgv/data/time_stamp.h>
4#include <cgv/media/transfer_function.h>
5#include <cgv/render/texture.h>
6#include <cgv_g2d/draggable_collection.h>
7#include <cgv_g2d/generic_2d_renderer.h>
8#include <cgv_g2d/generic_2d_render_data.h>
9#include <cgv_g2d/msdf_text_geometry.h>
10#include <cgv_overlay/color_selector.h>
11#include <cgv_overlay/themed_canvas_overlay.h>
12
13#include "lib_begin.h"
14
15namespace cgv {
16namespace overlay {
17
19protected:
20 enum class DraggableType {
21 kColor,
22 kOpacity
23 };
24
25 template<typename DataT>
26 class control_point : public cgv::g2d::draggable {
27 public:
28 control_point(vec2 size, const cgv::g2d::irect* constraint) : cgv::g2d::draggable({ 0.0f }, size) {
29 position_is_center = true;
30 constraint_reference = cgv::g2d::ConstraintReference::kCenter;
31 this->constraint = constraint;
32 }
33
34 void set_position_and_update_uv(vec2 position) {
35 if(!constraint)
36 return;
37
38 const auto area = static_cast<cgv::g2d::rect>(*constraint);
39 this->position = cgv::math::clamp(position, area.a(), area.b());
40 uv = (this->position - area.position) / area.size;
41 update_domain_value();
42 }
43
44 void set_uv_and_update_position(vec2 uv) {
45 if(!constraint)
46 return;
47
48 const auto area = static_cast<cgv::g2d::rect>(*constraint);
49 this->uv = cgv::math::clamp(uv, 0.0f, 1.0f);
50 position = area.position + this->uv * area.size;
51 update_domain_value();
52 }
53
54 bool operator<(const control_point& other) const {
55 return uv.x() < other.uv.x();
56 }
57
58 static vec2 domain;
59
60 vec2 uv = { 0.0f };
61 float domain_value = 0.0f;
62 DataT data = {};
63
64 private:
65 void update_domain_value() {
66 domain_value = cgv::math::lerp(domain.x(), domain.y(), uv.x());
67 }
68 };
69
72
74 int total_height;
75 int color_editor_height;
76 int opacity_editor_height;
77 cgv::g2d::irect color_draggables_rect;
78 cgv::g2d::irect color_editor_rect;
79 cgv::g2d::irect opacity_editor_rect;
80 } layout;
81
82 static const vec2 color_point_size;
83 static const vec2 opacity_point_size;
84 static const size_t preview_texture_resolution;
85
86 bool supports_opacity = false;
87 cgv::media::transfer_function::InterpolationMode color_interpolation = cgv::media::transfer_function::InterpolationMode::kLinear;
88 cgv::media::transfer_function::InterpolationMode opacity_interpolation = cgv::media::transfer_function::InterpolationMode::kLinear;
89
90 std::string value_label;
91 cgv::g2d::rect value_label_rectangle;
92
93 // general appearance
94 rgba handle_color = { 0.9f, 0.9f, 0.9f, 1.0f };
95 rgba highlight_color = { 0.5f, 0.5f, 0.5f, 1.0f };
96 cgv::g2d::shape2d_style border_style, color_map_style, background_style, histogram_style, label_box_style, opacity_handle_style, polygon_style;
97 cgv::g2d::arrow2d_style color_handle_style;
98 cgv::g2d::line2d_style line_style;
99
100 // label appearance
101 cgv::g2d::text2d_style cursor_label_style, value_label_style;
102
103 std::vector<unsigned> histogram;
104 unsigned hist_max = 1;
105 unsigned hist_max_non_zero = 1;
106 bool hist_norm_ignore_zero = true;
107 float hist_norm_gamma = 1.0f;
108 enum class HistogramType {
109 kNone = 0,
110 kNearest = 1,
111 kLinear = 2,
112 kSmooth = 3
113 };
114 HistogramType histogram_type = HistogramType::kNone;
115
116 cgv::render::texture background_tex = { "flt32[R,G,B]", cgv::render::TF_NEAREST, cgv::render::TF_NEAREST, cgv::render::TW_REPEAT, cgv::render::TW_REPEAT };
117 cgv::render::texture preview_tex = { "uint8[R,G,B,A]" };
118 cgv::render::texture histogram_tex = { "flt32[R]" };
119
120 cgv::g2d::generic_2d_renderer color_handle_renderer, opacity_handle_renderer, line_renderer, polygon_renderer;
121 DEFINE_GENERIC_RENDER_DATA_CLASS(textured_geometry, 2, vec2, position, vec2, texcoord);
122
123 std::shared_ptr<cgv::media::transfer_function> transfer_function;
124
125 cgv::g2d::draggable_collection<color_point> color_draggables;
126 cgv::g2d::draggable_collection<opacity_point> opacity_draggables;
127 color_point* selected_color_draggable = nullptr;
128 opacity_point* selected_opacity_draggable = nullptr;
129 vec2 color_draggable_start_position = { 0.0f };
130 vec2 opacity_draggable_start_position = { 0.0f };
131 cgv::g2d::generic_render_data_vec2_rgba color_draggables_geometry, opacity_draggables_geometry;
132 textured_geometry line_geometry;
133 textured_geometry triangle_geometry;
134 vec2 input_domain = { 0.0f, 1.0f };
135 float input_position = 0.0f;
136
137 cgv::data::time_stamp build_time;
138
139 void init_styles() override;
140 void update_layout(const ivec2& parent_size);
141
142 color_point make_color_point() const {
143 return color_point(color_point_size, &layout.color_draggables_rect);
144 }
145
146 opacity_point make_opacity_point() const {
147 return opacity_point(opacity_point_size, &layout.opacity_editor_rect);
148 }
149
150 void clear_data();
151 void force_update_data_from_transfer_function();
152 void update_data_from_transfer_function();
153 void update_transfer_function_from_data();
154 void rescale_domain();
155
156 void add_point(const vec2& pos);
157 void erase_point(const cgv::g2d::draggable* point);
158 void set_selected_point_domain_value();
159 cgv::g2d::draggable* get_hit_point(const vec2& pos);
160
161 void set_value_label(vec2 position, const std::string& text);
162 void handle_drag(cgv::g2d::DragAction action, DraggableType type);
163 void handle_selection_change();
164 std::string value_to_string(float value);
165 void sort_points();
166 void update_point_positions();
167
168 bool create_preview_texture();
169 bool create_background_texture();
170 void create_geometry();
171
172 void create_gui_impl() override;
173
174 std::function<void(void)> on_change_callback;
175 std::function<void(rgb)> on_color_point_select_callback;
176 std::function<void(void)> on_color_point_deselect_callback;
177
178public:
179 transfer_function_editor();
180 std::string get_type_name() const override { return "transfer_function_editor"; }
181
182 void clear(cgv::render::context& ctx) override;
183
184 bool handle_mouse_event(cgv::gui::mouse_event& e, cgv::ivec2 local_mouse_pos) override;
185 void handle_member_change(cgv::data::informed_ptr ptr) override;
186
187 bool init(cgv::render::context& ctx) override;
188 void init_frame(cgv::render::context& ctx) override;
189 void draw_content(cgv::render::context& ctx) override;
190
191 void handle_theme_change(const cgv::gui::theme_info& theme) override;
192
193 bool get_opacity_support() { return supports_opacity; }
194 void set_opacity_support(bool flag);
195
196 std::shared_ptr<cgv::media::transfer_function> get_transfer_function() const {
197 return transfer_function;
198 }
199 void set_transfer_function(std::shared_ptr<cgv::media::transfer_function> transfer_function);
200
201 void notify_transfer_function_change() {
202 force_update_data_from_transfer_function();
203 }
204
205 void set_histogram_data(const std::vector<unsigned> data);
206
207 void set_selected_color(rgb color);
208
209 void set_on_change_callback(std::function<void(void)> cb) {
210 on_change_callback = cb;
211 }
212 void set_on_color_point_select_callback(std::function<void(rgb)> cb) {
213 on_color_point_select_callback = cb;
214 }
215 void set_on_color_point_deselect_callback(std::function<void(void)> cb) {
216 on_color_point_deselect_callback = cb;
217 }
218};
219
220typedef cgv::data::ref_ptr<transfer_function_editor> transfer_function_editor_ptr;
221
222static void connect_color_selector_to_transfer_function_editor(const transfer_function_editor_ptr cme_ptr, const color_selector_ptr cs_ptr) {
223 if(cme_ptr && cs_ptr) {
224 cme_ptr->set_on_color_point_select_callback(std::bind(&cgv::overlay::color_selector::set_rgb_color, cs_ptr, std::placeholders::_1));
225 cme_ptr->set_on_color_point_deselect_callback(std::bind(&cgv::overlay::color_selector::set_visibility, cs_ptr, false));
226 cs_ptr->set_on_change_rgb_callback(std::bind(&cgv::overlay::transfer_function_editor::set_selected_color, cme_ptr, std::placeholders::_1));
227 }
228}
229
230} // namespace overlay
231} // namespace cgv
232
233#include <cgv/config/lib_end.h>
This class provides methods to test if a stored pointer points to addresses of given variables or ins...
reference counted pointer, which can work together with types that are derived from ref_counted,...
Definition ref_ptr.h:160
Keep a time stamp to store modified time of objects.
Definition time_stamp.h:11
class to represent all possible mouse events with the EID_MOUSE
Definition mouse_event.h:33
T & y()
return second component
Definition fvec.h:140
T & x()
return first component
Definition fvec.h:136
static cgv::type::uint32_type size()
return number of components
Definition fvec.h:134
InterpolationMode
The interpolation modes supported by the transfer function.
void set_visibility(bool visible)
set the visibility of the overlay
Definition overlay.cxx:116
std::string get_type_name() const override
overload to return the type name of this object
base class for all drawables, which is independent of the used rendering API.
Definition context.h:670
the texture class encapsulates all functionality independent of the rendering api.
Definition texture.h:15
this header is dependency free
Definition print.h:11
cgv::math::fvec< float, 2 > vec2
declare type of 2d single precision floating point vectors
Definition fvec.h:681