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 template<typename DataT>
21 class control_point : public cgv::g2d::draggable {
22 public:
23 control_point(vec2 size, const cgv::g2d::irect* constraint) : cgv::g2d::draggable({ 0.0f }, size) {
24 position_is_center = true;
25 constraint_reference = cgv::g2d::ConstraintReference::kCenter;
26 this->constraint = constraint;
27 }
28
29 void set_position_and_update_uv(vec2 position) {
30 if(!constraint)
31 return;
32
33 const auto& area = static_cast<cgv::g2d::rect>(*constraint);
34 this->position = cgv::math::clamp(position, area.a(), area.b());
35 uv = (this->position - area.position) / area.size;
36 }
37
38 void set_uv_and_update_position(vec2 uv) {
39 if(!constraint)
40 return;
41
42 const auto& area = static_cast<cgv::g2d::rect>(*constraint);
43 this->uv = cgv::math::clamp(uv, 0.0f, 1.0f);
44 position = area.position + this->uv * area.size;
45 }
46
47 bool operator<(const control_point& other) const {
48 return uv.x() < other.uv.x();
49 }
50
51 vec2 uv = { 0.0f };
52 vec2 value = { 0.0f };
53 DataT data = {};
54 };
55
58
59 static const vec2 color_point_size;
60 static const vec2 opacity_point_size;
61
62 enum class DraggableType {
63 kColor,
64 kOpacity
65 };
66
68 int total_height;
69 int color_editor_height;
70 int opacity_editor_height;
71 cgv::g2d::irect color_draggables_rect;
72 cgv::g2d::irect color_editor_rect;
73 cgv::g2d::irect opacity_editor_rect;
74 } layout;
75
76 bool supports_opacity = false;
77 cgv::media::transfer_function::InterpolationMode color_interpolation = cgv::media::transfer_function::InterpolationMode::kLinear;
78 cgv::media::transfer_function::InterpolationMode opacity_interpolation = cgv::media::transfer_function::InterpolationMode::kLinear;
79
80 std::string value_label;
81 cgv::g2d::rect value_label_rectangle;
82
83 // general appearance
84 rgba handle_color = { 0.9f, 0.9f, 0.9f, 1.0f };
85 rgba highlight_color = { 0.5f, 0.5f, 0.5f, 1.0f };
86 cgv::g2d::shape2d_style border_style, color_map_style, bg_style, hist_style, label_box_style, opacity_handle_style, polygon_style;
87 cgv::g2d::arrow2d_style color_handle_style;
88 cgv::g2d::line2d_style line_style;
89
90 // label appearance
91 cgv::g2d::text2d_style cursor_label_style, value_label_style;
92
93 std::vector<unsigned> histogram;
94 unsigned hist_max = 1;
95 unsigned hist_max_non_zero = 1;
96 bool hist_norm_ignore_zero = true;
97 float hist_norm_gamma = 1.0f;
98 enum class HistogramType {
99 kNone = 0,
100 kNearest = 1,
101 kLinear = 2,
102 kSmooth = 3
103 };
104 HistogramType histogram_type = HistogramType::kNone;
105
106 //int discretization_resolution = 256;
107 float opacity_scale_exponent = 1.0f;
108
109 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 };
110 cgv::render::texture preview_tex = { "uint8[R,G,B,A]" };
111 cgv::render::texture histogram_tex = { "flt32[R]" };
112
113 cgv::g2d::generic_2d_renderer color_handle_renderer, opacity_handle_renderer, line_renderer, polygon_renderer;
114 DEFINE_GENERIC_RENDER_DATA_CLASS(textured_geometry, 2, vec2, position, vec2, texcoord);
115
116 std::shared_ptr<cgv::media::transfer_function> transfer_function;
117
118 cgv::g2d::draggable_collection<color_point> color_draggables;
119 cgv::g2d::draggable_collection<opacity_point> opacity_draggables;
120 color_point* selected_color_draggable = nullptr;
121 opacity_point* selected_opacity_draggable = nullptr;
122 vec2 color_draggable_start_position = { 0.0f };
123 vec2 opacity_draggable_start_position = { 0.0f };
124 cgv::g2d::generic_render_data_vec2_rgba color_draggables_geometry, opacity_draggables_geometry;
125 textured_geometry line_geometry;
126 textured_geometry triangle_geometry;
127 vec2 input_domain = { 0.0f, 1.0f };
128 float input_position = 0.0f;
129
130 cgv::data::time_stamp build_time;
131
132 void init_styles() override;
133 void update_layout(const ivec2& parent_size);
134
135 color_point make_color_point() const {
136 return color_point(color_point_size, &layout.color_draggables_rect);
137 }
138
139 opacity_point make_opacity_point() const {
140 return opacity_point(opacity_point_size, &layout.opacity_editor_rect);
141 }
142
143 void clear_data();
144 void force_update_data_from_transfer_function();
145 void update_data_from_transfer_function();
146 void update_transfer_function_from_data();
147 void rescale_domain();
148
149 void add_point(const vec2& pos);
150 void erase_point(const cgv::g2d::draggable* point);
151 void set_selected_point_domain_value();
152 cgv::g2d::draggable* get_hit_point(const vec2& pos);
153
154 void set_value_label(vec2 position, const std::string& text);
155 void handle_drag(cgv::g2d::DragAction action, DraggableType type);
156 void handle_selection_change();
157 std::string value_to_string(float value);
158 void sort_points();
159 void update_point_positions();
160
161 bool create_preview_texture();
162 bool create_background_texture();
163 void create_geometry();
164
165 void create_gui_impl() override;
166
167 std::function<void(void)> on_change_callback;
168 std::function<void(rgb)> on_color_point_select_callback;
169 std::function<void(void)> on_color_point_deselect_callback;
170
171public:
172 transfer_function_editor();
173 std::string get_type_name() const override { return "transfer_function_editor"; }
174
175 void clear(cgv::render::context& ctx) override;
176
177 bool handle_mouse_event(cgv::gui::mouse_event& e, cgv::ivec2 local_mouse_pos) override;
178 void handle_member_change(cgv::data::informed_ptr ptr) override;
179
180 bool init(cgv::render::context& ctx) override;
181 void init_frame(cgv::render::context& ctx) override;
182 void draw_content(cgv::render::context& ctx) override;
183
184 void handle_theme_change(const cgv::gui::theme_info& theme) override;
185
186 bool get_opacity_support() { return supports_opacity; }
187 void set_opacity_support(bool flag);
188
189 std::shared_ptr<cgv::media::transfer_function> get_transfer_function() const {
190 return transfer_function;
191 }
192 void set_transfer_function(std::shared_ptr<cgv::media::transfer_function> transfer_function);
193
194 void notify_transfer_function_change() {
195 force_update_data_from_transfer_function();
196 }
197
198 void set_histogram_data(const std::vector<unsigned> data);
199
200 void set_selected_color(rgb color);
201
202 void set_on_change_callback(std::function<void(void)> cb) {
203 on_change_callback = cb;
204 }
205 void set_on_color_point_select_callback(std::function<void(rgb)> cb) {
206 on_color_point_select_callback = cb;
207 }
208 void set_on_color_point_deselect_callback(std::function<void(void)> cb) {
209 on_color_point_deselect_callback = cb;
210 }
211};
212
213typedef cgv::data::ref_ptr<transfer_function_editor> transfer_function_editor_ptr;
214
215static void connect_color_selector_to_transfer_function_editor(const transfer_function_editor_ptr cme_ptr, const color_selector_ptr cs_ptr) {
216 if(cme_ptr && cs_ptr) {
217 cme_ptr->set_on_color_point_select_callback(std::bind(&cgv::overlay::color_selector::set_rgb_color, cs_ptr, std::placeholders::_1));
218 cme_ptr->set_on_color_point_deselect_callback(std::bind(&cgv::overlay::color_selector::set_visibility, cs_ptr, false));
219 cs_ptr->set_on_change_rgb_callback(std::bind(&cgv::overlay::transfer_function_editor::set_selected_color, cme_ptr, std::placeholders::_1));
220 }
221}
222
223} // namespace overlay
224} // namespace cgv
225
226#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 & 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:668
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