1#ifndef TATOOINE_RENDERING_INTERACTIVE_UNSTRUCTURED_TRIANGULAR_GRID2_H
2#define TATOOINE_RENDERING_INTERACTIVE_UNSTRUCTURED_TRIANGULAR_GRID2_H
14template <
floating_po
int Real>
16 static constexpr std::array<std::string_view, 5> vector_component_names = {
17 "magnitude",
"x",
"y",
"z",
"w"};
22 typename renderable_type::template typed_vertex_property_type<T>;
26 static constexpr std::string_view vertex_shader =
28 "layout (location = 0) in vec2 position;\n"
29 "layout (location = 1) in float property;\n"
30 "uniform mat4 model_view_matrix;\n"
31 "uniform mat4 projection_matrix;\n"
32 "uniform vec2 pixel_width;\n"
33 "out float property_frag;\n"
35 " gl_Position = projection_matrix *\n"
36 " model_view_matrix *\n"
37 " vec4(position, 0, 1);\n"
38 " property_frag = property;\n"
41 static constexpr std::string_view fragment_shader =
43 "uniform sampler1D color_scale;\n"
44 "uniform float min;\n"
45 "uniform float max;\n"
46 "uniform int invert_scale;\n"
47 "uniform int show_solid_color;\n"
48 "uniform vec3 solid_color;\n"
50 "in float property_frag;\n"
52 "out vec4 out_color;\n"
54 " if (show_solid_color == 1) { out_color.rgb = solid_color; return;}\n"
55 " float scalar = property_frag;"
56 " if (isnan(scalar)) {\n"
57 " out_color = vec4(1,0,0,1);\n"
60 " scalar = clamp((scalar - min) / (max - min), 0, 1);\n"
61 " if (invert_scale == 1) {\n"
62 " scalar = 1 - scalar;\n"
64 " vec3 col = texture(color_scale, scalar).rgb;\n"
65 " out_color = vec4(col, 1);\n"
68 static auto get() ->
auto& {
79 set_uniform(
"color_scale", 1);
85 show_solid_color(
true);
86 set_solid_color(1,0,0);
87 set_uniform(
"color_scale", 0);
93 set_uniform_mat4(
"projection_matrix", P.data());
97 set_uniform_mat4(
"model_view_matrix", MV.data());
104 set_uniform(
"invert_scale", invert ? 1 : 0);
108 set_uniform(
"show_solid_color",
show ? 1 : 0);
112 set_uniform(
"solid_color", r, g, b);
116 set_uniform(
"solid_color", col);
123 struct property_settings {
125 GLfloat min_scalar = std::numeric_limits<GLfloat>::max();
126 GLfloat max_scalar = -std::numeric_limits<GLfloat>::max();
127 bool scale_inverted =
false;
129 bool show_wireframe =
false;
131 GLfloat line_width = 1;
133 std::unordered_map<std::string, property_settings>
settings;
135 std::string
const* selected_property_name =
nullptr;
148 init_grid_geometry(
grid);
149 init_properties(
grid);
157 auto data = m_geometry.
wmap();
158 auto k = std::size_t{};
159 for (
auto const v :
grid.vertices()) {
164 auto data = m_triangles.
wmap();
165 auto k = std::size_t{};
166 for (
auto const s :
grid.simplices()) {
167 auto const [v0, v1, v2] =
grid[s];
174 auto data = m_wireframe.
wmap();
175 auto k = std::size_t{};
176 for (
auto const s :
grid.simplices()) {
177 auto const [v0, v1, v2] =
grid[s];
189 for (
auto const& key_value :
grid.vertex_properties()) {
190 auto const& [name, prop] = key_value;
191 if (prop_holds_scalar(prop)) {
192 auto min_scalar = std::numeric_limits<GLfloat>::max();
193 auto max_scalar = -std::numeric_limits<GLfloat>::max();
194 retrieve_typed_prop(prop.get(), [&](
auto const& prop) {
195 using prop_type = std::decay_t<decltype(prop)>;
196 using value_type = typename prop_type::value_type;
197 if constexpr (is_arithmetic<value_type>) {
198 for (auto const v : grid.vertices()) {
199 auto const p = prop[v.index()];
200 min_scalar = std::min(min_scalar, static_cast<GLfloat>(p));
201 max_scalar = std::max(max_scalar, static_cast<GLfloat>(p));
206 }
else if (prop_holds_vector(prop)) {
207 retrieve_typed_prop(prop.get(), [&](
auto const& prop) {
208 using prop_type = std::decay_t<decltype(prop)>;
209 using value_type = typename prop_type::value_type;
210 if constexpr (static_vec<value_type>) {
211 auto constexpr num_comps = value_type::num_components();
212 auto min_scalars = std::vector<GLfloat>(
213 num_comps + 1, std::numeric_limits<GLfloat>::max());
214 auto max_scalars = std::vector<GLfloat>(
215 num_comps + 1, -std::numeric_limits<GLfloat>::max());
216 for (auto const v : grid.vertices()) {
217 auto const p = prop[v.index()];
218 auto mag = typename value_type::value_type{};
219 for (std::size_t j = 0; j < num_comps; ++j) {
222 std::min(min_scalars[j + 1], static_cast<GLfloat>(p(j)));
224 std::max(max_scalars[j + 1], static_cast<GLfloat>(p(j)));
226 mag = std::sqrt(mag);
228 std::min(min_scalars[0], static_cast<GLfloat>(mag));
230 std::max(max_scalars[0], static_cast<GLfloat>(mag));
233 for (std::size_t j = 0; j < num_comps + 1; ++j) {
234 settings[key_value.first +
'_' + std::string{vector_component_names[j]}] = {
235 &color_scale::viridis(), min_scalars[j], max_scalars[j]};
237 selected_component[key_value.first] = vector_component_names[0];
245 if (prop->type() ==
typeid(
float)) {
246 f(prop->template cast_to_typed<float>());
247 }
else if (prop->type() ==
typeid(
double)) {
248 f(prop->template cast_to_typed<double>());
249 }
else if (prop->type() ==
typeid(
vec2d)) {
250 f(prop->template cast_to_typed<vec2d>());
251 }
else if (prop->type() ==
typeid(
vec2f)) {
252 f(prop->template cast_to_typed<vec2f>());
253 }
else if (prop->type() ==
typeid(
vec3d)) {
254 f(prop->template cast_to_typed<vec3d>());
255 }
else if (prop->type() ==
typeid(
vec3f)) {
256 f(prop->template cast_to_typed<vec3f>());
257 }
else if (prop->type() ==
typeid(
vec4d)) {
258 f(prop->template cast_to_typed<vec4d>());
259 }
else if (prop->type() ==
typeid(
vec4f)) {
260 f(prop->template cast_to_typed<vec4f>());
265 return prop->type() ==
typeid(float) || prop->type() ==
typeid(
double);
269 return prop->type() ==
typeid(
vec2f) || prop->type() ==
typeid(
vec2d) ||
270 prop->type() ==
typeid(
vec3f) || prop->type() ==
typeid(
vec3d) ||
271 prop->type() ==
typeid(
vec4f) || prop->type() ==
typeid(
vec4d);
275 auto data = m_geometry.rwmap();
276 for (std::size_t i = 0; i <
grid.vertices().
size(); ++i) {
277 get<1>(data[i]) =
static_cast<GLfloat
>(get_data(prop, i));
282 retrieve_typed_prop(prop, [&](
auto&& prop) {
283 using prop_type = std::decay_t<
decltype(prop)>;
284 using value_type =
typename prop_type::value_type;
285 if constexpr (is_arithmetic<value_type>) {
288 [](
auto const& prop,
auto const i) {
return prop[i]; },
295 retrieve_typed_prop(prop, [&](
auto&& prop) {
296 using prop_type = std::decay_t<
decltype(prop)>;
297 using value_type =
typename prop_type::value_type;
301 [](
auto const& prop,
auto const i) {
302 auto mag =
typename value_type::value_type{};
304 mag += prop[i](j) * prop[i](j);
314 retrieve_typed_prop(prop, [&](
auto&& prop) {
315 using prop_type = std::decay_t<
decltype(prop)>;
316 using value_type =
typename prop_type::value_type;
320 [](
auto const& prop,
auto const i) {
return prop[i].x(); },
327 retrieve_typed_prop(prop, [&](
auto&& prop) {
328 using prop_type = std::decay_t<
decltype(prop)>;
329 using value_type =
typename prop_type::value_type;
333 [](
auto const& prop,
auto const i) {
return prop[i].y(); },
340 retrieve_typed_prop(prop, [&](
auto&& prop) {
341 using prop_type = std::decay_t<
decltype(prop)>;
342 using value_type =
typename prop_type::value_type;
347 [](
auto const& prop,
auto const i) {
357 retrieve_typed_prop(prop, [&](
auto&& prop) {
358 using prop_type = std::decay_t<
decltype(prop)>;
359 using value_type =
typename prop_type::value_type;
364 [](
auto const& prop,
auto const i) {
374 auto name = std::string{};
375 if (selected_property_name !=
nullptr) {
376 name = *selected_property_name;
377 if (
auto c = selected_component.find(name);
378 c !=
end(selected_component)) {
387 if (ImGui::BeginCombo(
"##combo", selected_property_name !=
nullptr
388 ? selected_property_name->c_str()
390 if (ImGui::Selectable(
"Solid Color", selected_property ==
nullptr)) {
391 selected_property =
nullptr;
393 if (selected_property ==
nullptr) {
394 ImGui::SetItemDefaultFocus();
396 for (
auto const& [name, prop] :
grid.vertex_properties()) {
397 if (prop->type() ==
typeid(
float) || prop->type() ==
typeid(
double) ||
398 prop->type() ==
typeid(
vec2f) || prop->type() ==
typeid(
vec2d) ||
399 prop->type() ==
typeid(
vec3f) || prop->type() ==
typeid(
vec3d) ||
400 prop->type() ==
typeid(
vec4f) || prop->type() ==
typeid(
vec4d)) {
401 auto is_selected = selected_property == prop.get();
402 if (ImGui::Selectable(name.c_str(), is_selected)) {
403 selected_property = prop.get();
404 selected_property_name = &name;
405 if (prop_holds_scalar(prop)) {
406 upload_scalar_to_texture(selected_property,
grid);
408 }
else if (prop_holds_vector(prop)) {
409 upload_magnitude_to_texture(selected_property,
grid);
411 for (std::size_t i = 0; i < 5; ++i) {
412 auto const is_selected =
413 selected_component.at(*selected_property_name) ==
414 vector_component_names[i];
415 if (is_selected && i == 0) {
416 upload_magnitude_to_texture(selected_property,
grid);
417 }
else if (is_selected && i == 1) {
418 upload_x_to_texture(selected_property,
grid);
419 }
else if (is_selected && i == 2) {
420 upload_y_to_texture(selected_property,
grid);
421 }
else if (is_selected && i == 3) {
422 upload_z_to_texture(selected_property,
grid);
423 }
else if (is_selected && i == 4) {
424 upload_w_to_texture(selected_property,
grid);
432 ImGui::SetItemDefaultFocus();
441 if (ImGui::BeginCombo(
442 "##combo_vector_component",
443 std::string{selected_component.at(*selected_property_name)}
445 auto n = std::size_t{};
446 retrieve_typed_prop(selected_property, [&](
auto&& prop) {
447 using prop_type = std::decay_t<
decltype(prop)>;
448 using value_type =
typename prop_type::value_type;
453 for (std::size_t i = 0; i < n + 1; ++i) {
454 auto const is_selected =
455 selected_component.at(*selected_property_name) ==
456 vector_component_names[i];
457 if (ImGui::Selectable(std::string{vector_component_names[i]}.c_str(),
459 selected_component.at(*selected_property_name) =
460 vector_component_names[i];
462 upload_magnitude_to_texture(selected_property,
grid);
464 upload_x_to_texture(selected_property,
grid);
466 upload_y_to_texture(selected_property,
grid);
468 upload_z_to_texture(selected_property,
grid);
470 upload_w_to_texture(selected_property,
grid);
482 if (selected_property !=
nullptr) {
483 auto combo_pos = ImGui::GetCursorScreenPos();
484 auto& setting = settings.at(selected_settings_name());
485 if (ImGui::BeginCombo(
"##combocolor",
486 selected_property_name !=
nullptr
487 ? selected_property_name->c_str()
489 ImGui::PushID(
"##viridis");
490 auto viridis_selected =
496 if (viridis_selected) {
500 ImGui::PushID(
"##GYPi");
513 ImGui::Text(
"Invert Color");
517 auto const backup_pos = ImGui::GetCursorScreenPos();
518 ImGuiStyle& style = ImGui::GetStyle();
519 ImGui::SetCursorScreenPos(
520 ImVec2(combo_pos.x + style.FramePadding.x, combo_pos.y));
521 ImGui::Image((
void*)(std::intptr_t)setting.c->tex_2d.id(),
523 ImGui::SetCursorScreenPos(backup_pos);
525 if (ImGui::Button(
"Rescale")) {
526 rescale_current_property(
grid);
532 auto const name = selected_settings_name();
533 auto& setting = settings[name];
534 auto min_scalar = std::numeric_limits<GLfloat>::max();
535 auto max_scalar = -std::numeric_limits<GLfloat>::max();
536 if (prop_holds_scalar(selected_property)) {
537 retrieve_typed_prop(selected_property, [&](
auto const& prop) {
538 using prop_type = std::decay_t<
decltype(prop)>;
539 using value_type =
typename prop_type::value_type;
540 if constexpr (is_arithmetic<value_type>) {
541 for (
auto const v :
grid.vertices()) {
542 auto const p = prop[v.index()];
543 min_scalar = std::min(min_scalar,
static_cast<GLfloat
>(p));
544 max_scalar = std::max(max_scalar,
static_cast<GLfloat
>(p));
548 }
else if (prop_holds_vector(selected_property)) {
549 retrieve_typed_prop(selected_property, [&](
auto const& prop) {
550 using prop_type = std::decay_t<
decltype(prop)>;
551 using value_type =
typename prop_type::value_type;
554 for (
auto const v :
grid.vertices()) {
555 auto const p = prop[v.index()];
556 if (selected_component.at(*selected_property_name) ==
557 vector_component_names[0]) {
558 auto mag =
typename value_type::value_type{};
559 for (std::size_t i = 0; i < num_comps; ++i) {
562 mag = std::sqrt(mag);
563 min_scalar = std::min(min_scalar,
static_cast<GLfloat
>(mag));
564 max_scalar = std::max(max_scalar,
static_cast<GLfloat
>(mag));
566 auto s =
typename value_type::value_type{};
567 if (selected_component.at(*selected_property_name) ==
568 vector_component_names[1]) {
570 }
else if (selected_component.at(*selected_property_name) ==
571 vector_component_names[2]) {
573 }
else if (selected_component.at(*selected_property_name) ==
574 vector_component_names[3]) {
578 }
else if (selected_component.at(*selected_property_name) ==
579 vector_component_names[4]) {
584 min_scalar = std::min(min_scalar,
static_cast<GLfloat
>(s));
585 max_scalar = std::max(max_scalar,
static_cast<GLfloat
>(s));
591 setting.min_scalar = min_scalar;
592 setting.max_scalar = max_scalar;
597 ImGui::Checkbox(
"Show Grid", &show_wireframe);
598 ImGui::DragFloat(
"Line width", &line_width, 1, 1, 20);
599 ImGui::DragFloat(
"Line width", &line_width, 1.0f, 1.0f, 2.0f,
"%.01f");
600 ImGui::ColorEdit4(
"Wireframe Color", wireframe_color.data());
601 grid_property_selection(
grid);
603 vector_component_selection(
grid);
605 if (selected_property !=
nullptr) {
606 auto& setting = settings[selected_settings_name()];
607 ImGui::DragFloat(
"Min", &setting.min_scalar, 0.01f, -FLT_MAX,
608 setting.max_scalar,
"%.06f");
609 ImGui::DragFloat(
"Max", &setting.max_scalar, 0.01f, setting.min_scalar,
612 if (selected_property ==
nullptr) {
613 ImGui::ColorEdit3(
"Solid Color", m_solid_color.data());
616 color_scale_selection(
grid);
620 if (show_wireframe) {
628 using CamReal =
typename std::decay_t<
decltype(cam)>
::real_type;
629 static auto constexpr cam_is_float = is_same<GLfloat, CamReal>;
630 if (show_wireframe) {
631 if constexpr (cam_is_float) {
638 if constexpr (cam_is_float) {
645 if constexpr (cam_is_float) {
652 if constexpr (cam_is_float) {
666 gl::line_width(line_width);
670 m_geometry.activate_attributes();
672 vao.draw_lines(m_wireframe.size());
677 if (selected_property_name !=
nullptr) {
678 auto const name = selected_settings_name();
679 auto& setting = settings.at(name);
680 setting.c->tex.bind(0);
692 m_geometry.activate_attributes();
694 vao.draw_triangles(m_wireframe.size());
auto resize(GLsizei size) -> void
Definition: buffer.h:640
auto wmap()
Definition: buffer.h:506
Definition: indexbuffer.h:13
DLL_API void bind() const
Definition: vertexarray.h:15
DLL_API void bind() const
Definition: vertexbuffer.h:22
Definition: grid_edge.h:16
Definition: tensor_concepts.h:23
auto ToggleButton(const char *str_id, bool *v) -> bool
Definition: interactive.h:15
auto show(std::index_sequence< Is... >, Renderables &&... renderables)
Definition: interactive.h:60
Definition: algorithm.h:6
typename get_impl< Container, I >::type get
Definition: get.h:11
typename value_type_impl< T >::type value_type
Definition: type_traits.h:280
auto end(Range &&range)
Definition: iterator_facade.h:322
constexpr auto max(A &&a, B &&b)
Definition: math.h:20
auto size(vec< ValueType, N > const &v)
Definition: vec.h:148
constexpr auto min(A &&a, B &&b)
Definition: math.h:15
typename Line::vertex_property_type vertex_property_type
Definition: vtk_writer.h:20
static constexpr GLsizei num_components
Definition: texcomponents.h:10
Definition: shadersource.h:8
Definition: color_scale.h:25
static auto viridis() -> auto &
Definition: color_scale.h:82
auto init_properties(renderable_type const &grid)
Definition: unstructured_triangular_grid2.h:188
auto update(auto const, renderable_type const &, camera auto const &cam)
Definition: unstructured_triangular_grid2.h:626
auto grid_property_selection(renderable_type const &grid)
Definition: unstructured_triangular_grid2.h:386
auto render_property()
Definition: unstructured_triangular_grid2.h:675
std::unordered_map< std::string, property_settings > settings
Definition: unstructured_triangular_grid2.h:133
gl::vertexbuffer< Vec2< GLfloat >, GLfloat > m_geometry
Definition: unstructured_triangular_grid2.h:141
gl::indexbuffer m_wireframe
Definition: unstructured_triangular_grid2.h:143
auto rescale_current_property(renderable_type const &grid)
Definition: unstructured_triangular_grid2.h:531
std::unordered_map< std::string, std::string_view > selected_component
Definition: unstructured_triangular_grid2.h:134
auto selected_settings_name() const
Definition: unstructured_triangular_grid2.h:373
auto upload_w_to_texture(auto &&prop, renderable_type const &grid)
Definition: unstructured_triangular_grid2.h:356
auto upload_z_to_texture(auto &&prop, renderable_type const &grid)
Definition: unstructured_triangular_grid2.h:339
auto prop_holds_vector(auto const &prop)
Definition: unstructured_triangular_grid2.h:268
renderer(renderable_type const &grid)
Definition: unstructured_triangular_grid2.h:147
auto upload_data(auto &&prop, auto &&get_data, renderable_type const &grid)
Definition: unstructured_triangular_grid2.h:274
auto render_wireframe()
Definition: unstructured_triangular_grid2.h:660
auto upload_scalar_to_texture(auto &&prop, renderable_type const &grid)
Definition: unstructured_triangular_grid2.h:281
auto retrieve_typed_prop(auto &&prop, auto &&f)
Definition: unstructured_triangular_grid2.h:244
auto init_grid_geometry(renderable_type const &grid)
Definition: unstructured_triangular_grid2.h:152
auto prop_holds_scalar(auto const &prop)
Definition: unstructured_triangular_grid2.h:264
auto color_scale_selection(renderable_type const &grid)
Definition: unstructured_triangular_grid2.h:481
auto upload_x_to_texture(auto &&prop, renderable_type const &grid)
Definition: unstructured_triangular_grid2.h:313
gl::indexbuffer m_triangles
Definition: unstructured_triangular_grid2.h:142
auto properties(renderable_type const &grid)
Definition: unstructured_triangular_grid2.h:595
auto upload_y_to_texture(auto &&prop, renderable_type const &grid)
Definition: unstructured_triangular_grid2.h:326
auto render()
Definition: unstructured_triangular_grid2.h:619
typename renderable_type::template typed_vertex_property_type< T > typed_vertex_property_interface_type
Definition: unstructured_triangular_grid2.h:22
auto upload_magnitude_to_texture(auto &&prop, renderable_type const &grid)
Definition: unstructured_triangular_grid2.h:294
auto vector_component_selection(renderable_type const &grid)
Definition: unstructured_triangular_grid2.h:440
cook_torrance_brdf_shader property_shader
Definition: unstructured_triangular_grid3.h:25
auto set_solid_color(GLfloat r, GLfloat g, GLfloat b) -> void
Definition: unstructured_triangular_grid2.h:111
property_shader()
Definition: unstructured_triangular_grid2.h:75
auto set_model_view_matrix(Mat4< GLfloat > const &MV) -> void
Definition: unstructured_triangular_grid2.h:96
auto set_max(GLfloat const max) -> void
Definition: unstructured_triangular_grid2.h:101
auto set_projection_matrix(Mat4< GLfloat > const &P) -> void
Definition: unstructured_triangular_grid2.h:92
auto invert_scale(bool const invert) -> void
Definition: unstructured_triangular_grid2.h:103
auto set_min(GLfloat const min) -> void
Definition: unstructured_triangular_grid2.h:100
auto show_solid_color(bool const show) -> void
Definition: unstructured_triangular_grid2.h:107
auto set_solid_color(Vec3< GLfloat > const &col) -> void
Definition: unstructured_triangular_grid2.h:115
static auto get() -> auto &
Definition: unstructured_triangular_grid2.h:68
auto set_color(GLfloat r, GLfloat g, GLfloat b, GLfloat a=1) -> void
Definition: shaders.h:85
Definition: unstructured_simplicial_grid.h:52
Definition: unstructured_triangular_grid.h:10
Definition: property.h:16