1#ifndef TATOOINE_RENDER_TOPOLOGICAL_SKELETON
2#define TATOOINE_RENDER_TOPOLOGICAL_SKELETON
4#include <tatooine/diff.h>
5#include <tatooine/gpu/lic.h>
7#include <tatooine/grid_sampler.h>
8#include <tatooine/sampled_field.h>
14#include <tatooine/gl/orthographiccamera.h>
18#include <boost/range/adaptor/transformed.hpp>
19#include <boost/range/algorithm/copy.hpp>
24template <
typename Real,
typename Integrator,
25 template <
typename>
typename Interpolator>
31 const integration::integrator<Real, 2, Interpolator, Integrator>&
34 const Real tau = 100,
const Real eps = 1e-7) {
36 struct point_shader : shader {
38 add_stage<vertexshader>(
40 "layout(location = 0) in vec2 pos;\n"
41 "layout(location = 1) in vec3 col;\n"
42 "out vec2 geom_pos;\n"
43 "out vec3 geom_col;\n"
48 shaderstageparser::SOURCE);
49 add_stage<geometryshader>(
51 "#define pi 3.1415926535897932384626433832795\n"
52 "layout (points) in;\n"
53 "layout (triangle_strip, max_vertices = 100) out;\n"
55 "uniform mat4 projection;\n"
56 "uniform vec2 domain_min;\n"
57 "uniform vec2 domain_max;\n"
58 "uniform float radius;\n"
60 "in vec2[] geom_pos;\n"
61 "in vec3[] geom_col;\n"
63 "out vec3 frag_col;\n"
64 "out float frag_param;\n"
68 " frag_col = geom_col[0];\n"
69 " for (uint i = 0; i < n - 1; ++i) {\n"
70 " gl_Position = projection * vec4(geom_pos[0], 0, 1);\n"
73 " gl_Position = projection * vec4(geom_pos[0] +\n"
74 " vec2(cos(float(i) / float(n-1) * 2*pi),\n"
75 " sin(float(i) / float(n-1) * 2*pi)) * radius,\n"
79 " gl_Position = projection * vec4(geom_pos[0] +\n"
80 " vec2(cos(float(i+1) / float(n-1) * 2*pi),\n"
81 " sin(float(i+1) / float(n-1) * 2*pi)) * radius,\n"
88 shaderstageparser::SOURCE);
89 add_stage<fragmentshader>(
92 "in float frag_param;\n"
93 "layout(location = 0) out vec4 frag;\n"
95 " if (frag_param > 0.8) {\n"
96 " frag = vec4(vec3(0), 1);\n"
98 " frag = vec4(frag_col, 1);\n"
101 shaderstageparser::SOURCE);
104 void set_projection(
const glm::mat4x4& p) { set_uniform(
"projection", p); }
105 void set_radius(
const GLfloat radius) { set_uniform(
"radius", radius); }
108 struct line_shader : shader {
110 add_stage<vertexshader>(
112 "uniform mat4 projection;\n"
113 "layout(location = 0) in vec2 pos;\n"
115 " gl_Position = projection * vec4(pos, 0, 1);\n"
117 shaderstageparser::SOURCE);
118 add_stage<fragmentshader>(
120 "layout(location = 0) out vec4 frag;\n"
122 " frag = vec4(0,0,0,1);\n"
124 shaderstageparser::SOURCE);
127 void set_projection(
const glm::mat4x4& p) { set_uniform(
"projection", p); }
129 using namespace interpolation;
130 using gpu_point_data_t = indexeddata<vec2f, vec3f>;
131 using gpu_line_data_t = indexeddata<vec2f>;
132 using sampler_t = grid_sampler<double, 2, vec<double, 2>, linear, linear>;
134 gpu_point_data_t::vbo_data_vec vbo_point_data;
135 gpu_point_data_t::ibo_data_vec ibo_point_data;
136 gpu_line_data_t::vbo_data_vec vbo_line_data;
137 gpu_line_data_t::ibo_data_vec ibo_line_data;
142 for (
const auto& x : skel.saddles) {
143 vbo_point_data.push_back({{float(x(0)), float(x(1))}, {1.0f, 1.0f, .0f}});
144 ibo_point_data.push_back(ibo_point_data.size());
146 for (
const auto& x : skel.sinks) {
147 vbo_point_data.push_back({{float(x(0)), float(x(1))}, {1.0f, .0f, .0f}});
148 ibo_point_data.push_back(ibo_point_data.size());
150 for (
const auto& x : skel.sources) {
151 vbo_point_data.push_back({{float(x(0)), float(x(1))}, {.0f, .0f, 1.0f}});
152 ibo_point_data.push_back(ibo_point_data.size());
154 for (
const auto& x : skel.attracting_foci) {
155 vbo_point_data.push_back({{float(x(0)), float(x(1))}, {1.0f, .25f, .25f}});
156 ibo_point_data.push_back(ibo_point_data.size());
158 for (
const auto& x : skel.repelling_foci) {
159 vbo_point_data.push_back({{float(x(0)), float(x(1))}, {.25f, .25f, 1.0f}});
160 ibo_point_data.push_back(ibo_point_data.size());
162 for (
const auto& x : skel.centers) {
163 vbo_point_data.push_back({{float(x(0)), float(x(1))}, {.0f, 0.75f, 0.0f}});
164 ibo_point_data.push_back(ibo_point_data.size());
166 for (
const auto& x : skel.boundary_switch_points) {
167 vbo_point_data.push_back({{float(x(0)), float(x(1))}, {1.0f, 1.0f, 1.0f}});
168 ibo_point_data.push_back(ibo_point_data.size());
170 gpu_point_data_t gpu_point_data{vbo_point_data, ibo_point_data};
171 gpu_point_data.setup_vao();
175 for (
const auto& separatrix : skel.separatrices) {
176 for (
size_t i = 0; i < separatrix.vertices().size(); ++i) {
177 vbo_line_data.push_back({
static_cast<float>(separatrix.vertex_at(i)(0)),
178 static_cast<float>(separatrix.vertex_at(i)(1))});
180 for (
size_t i = 0; i < separatrix.vertices().size() - 1; ++i) {
181 ibo_line_data.push_back(line_cnt);
182 ibo_line_data.push_back(++line_cnt);
186 gpu_line_data_t gpu_line_data{vbo_line_data, ibo_line_data};
187 gpu_line_data.setup_vao();
190 const Real pixel_size =
191 std::min((v.sampler().back(0) - v.sampler().front(0)) / resolution(0),
192 (v.sampler().back(1) - v.sampler().front(1)) / resolution(1));
193 const Real lic_stepsize = pixel_size / 4;
194 const size_t lic_num_samples = 100;
195 auto image = gpu::lic(v.sampler(), resolution, lic_num_samples, lic_stepsize,
197 orthographiccamera cam(v.sampler().front(0), v.sampler().back(0),
198 v.sampler().front(1), v.sampler().back(1), -10, 10, 0,
199 0, resolution(0), resolution(1));
202 framebuffer fbo{image};
209 shader.set_projection(cam.projection_matrix());
211 gpu_line_data.draw_lines();
217 shader.set_projection(cam.projection_matrix());
218 shader.set_radius(pixel_size*10);
219 gpu_point_data.draw_points();
DLL_API auto line_width(GLfloat width) -> void
DLL_API auto viewport(GLint x, GLint y, GLsizei width, GLsizei height) -> void
Definition: algorithm.h:6
auto render_topological_skeleton(const sampled_field< grid_sampler< Real, 2, vec< Real, 2 >, interpolation::linear, interpolation::linear >, Real, 2, 2 > &v, const integration::integrator< Real, 2, Interpolator, Integrator > &integrator, const vec< size_t, 2 > &resolution, const Real tau=100, const Real eps=1e-7)
you need a gl::context for this
Definition: render_topological_skeleton.h:26
auto compute_topological_skeleton(const sampled_field< grid_sampler< Real, 2, vec< Real, 2 >, interpolation::linear, interpolation::linear >, Real, 2, 2 > &v, const integration::integrator< Real, 2, Interpolator, Integrator > &integrator, const Real tau=100, const Real eps=1e-7)
Definition: topological_skeleton.h:31
Definition: interpolation.h:16