Developer documentation
Version 3.0.3-105-gd3941f44
volume.h
Go to the documentation of this file.
1/* Copyright (c) 2008-2022 the MRtrix3 contributors.
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 *
7 * Covered Software is provided under this License on an "as is"
8 * basis, without warranty of any kind, either expressed, implied, or
9 * statutory, including, without limitation, warranties that the
10 * Covered Software is free of defects, merchantable, fit for a
11 * particular purpose or non-infringing.
12 * See the Mozilla Public License v. 2.0 for more details.
13 *
14 * For more details, see http://www.mrtrix.org/.
15 */
16
17#ifndef __gui_mrview_volume_h__
18#define __gui_mrview_volume_h__
19
20#include "header.h"
21#include "transform.h"
22
23#include "file/config.h"
24#include "gui/opengl/gl.h"
26
27
28namespace MR
29{
30 namespace GUI
31 {
32 class Projection;
33
34 namespace MRView
35 {
36
37 class Window;
38
39 class Volume : public Displayable
40 { MEMALIGN(Volume)
41 public:
42 Volume (MR::Header&& header) :
43 Displayable (header.name()),
44 _header (std::move (header)),
45 //CONF option: ImageInterpolation
46 //CONF default: true
47 //CONF Define default interplation setting for image and image overlay.
48 interpolation (File::Config::get_bool("ImageInterpolation", true) ? gl::LINEAR : gl::NEAREST),
50 texture_mode_changed (true) { }
51
52 virtual ~Volume();
53
54 void set_interpolate (bool linear) { interpolation = linear ? gl::LINEAR : gl::NEAREST; }
55 bool interpolate () const { return interpolation == gl::LINEAR; }
56
57 void set_colourmap (size_t index) {
58 if (ColourMap::maps[index].special || ColourMap::maps[colourmap].special)
59 if (index != colourmap)
61 Displayable::colourmap = index;
62 }
63
64 void render (Displayable::Shader& shader_program, const Projection& projection, float depth) {
65 start (shader_program, _scale_factor);
66 projection.set (shader_program);
67 texture().bind();
68 set_vertices_for_slice_render (projection, depth);
70 stop (shader_program);
71 }
72
73 void bind () {
74 if (!texture()) { // allocate:
75 texture().gen (gl::TEXTURE_3D);
76 texture().bind();
77 }
78 else
79 texture().bind();
80 texture().set_interp (interpolation);
81 }
82
83
84 Eigen::Transform<float,3,Eigen::AffineCompact> image2scanner () const {
85 return _header.transform().cast<float>();
86 }
87
88 Eigen::Transform<float,3,Eigen::AffineCompact> scanner2image () const {
89 return _header.transform().inverse().cast<float>();
90 }
91
92 Eigen::Transform<float,3,Eigen::AffineCompact> voxel2scanner () const {
93 auto T = _header.transform();
94 return T.scale (Eigen::Vector3d (_header.spacing(0), _header.spacing(1), _header.spacing(2))).cast<float>();
95 }
96
97 Eigen::Transform<float,3,Eigen::AffineCompact> scanner2voxel () const {
98 auto T = _header.transform().inverse();
99 return T.prescale (Eigen::Vector3d (1.0/_header.spacing(0), 1.0/_header.spacing(1), 1.0/_header.spacing(2))).cast<float>();
100 }
101
102 void allocate();
103
104 float focus_rate () const {
105 return 1.0e-3 * (std::pow (
106 _header.size(0) * _header.spacing(0) *
107 _header.size(1) * _header.spacing(1) *
108 _header.size(2) * _header.spacing(2),
109 float (1.0/3.0)));
110 }
111
112 float scale_factor () const { return _scale_factor; }
113 const GL::Texture& texture () const { return *_current_texture; }
114 GL::Texture& texture () { return *_current_texture; }
115 const MR::Header& header () const { return _header; }
116 MR::Header& header () { return _header; }
117
118 void min_max_set() {
120 if (std::isnan (display_midpoint) || std::isnan (display_range))
121 reset_windowing();
122 }
123
124
125
126 inline void upload_data (const std::array<ssize_t,3>& x, const std::array<ssize_t,3>& size, const void* data) {
127 gl::TexSubImage3D (gl::TEXTURE_3D, 0,
128 x[0], x[1], x[2],
129 size[0], size[1], size[2],
130 format, type, data);
131 }
132
133 protected:
143
144 Eigen::Vector3f pos[4], tex[4], z, im_z;
145 Eigen::Vector3f vertices[8];
146
147 inline Eigen::Vector3f div (const Eigen::Vector3f& a, const Eigen::Vector3f& b) {
148 return Eigen::Vector3f (a[0]/b[0], a[1]/b[1], a[2]/b[2]);
149 }
150
151 void set_vertices_for_slice_render (const Projection& projection, float depth)
152 {
153 vertices[0] = projection.screen_to_model (projection.x_position(), projection.y_position()+projection.height(), depth);
154 vertices[2] = projection.screen_to_model (projection.x_position(), projection.y_position(), depth);
155 vertices[4] = projection.screen_to_model (projection.x_position()+projection.width(), projection.y_position(), depth);
156 vertices[6] = projection.screen_to_model (projection.x_position()+projection.width(), projection.y_position()+projection.height(), depth);
157
158 const Eigen::Vector3f sizes (_header.size (0), _header.size (1), _header.size (2));
159 const auto S2V = scanner2voxel();
160 vertices[1] = div ((S2V * vertices[0]) + Eigen::Vector3f { 0.5, 0.5, 0.5 }, sizes);
161 vertices[3] = div ((S2V * vertices[2]) + Eigen::Vector3f { 0.5, 0.5, 0.5 }, sizes);
162 vertices[5] = div ((S2V * vertices[4]) + Eigen::Vector3f { 0.5, 0.5, 0.5 }, sizes);
163 vertices[7] = div ((S2V * vertices[6]) + Eigen::Vector3f { 0.5, 0.5, 0.5 }, sizes);
164 }
165
167 {
169 assert (!vertex_buffer);
170 assert (!vertex_array_object);
171
174
175 vertex_buffer.bind (gl::ARRAY_BUFFER);
177
178 gl::EnableVertexAttribArray (0);
179 gl::VertexAttribPointer (0, 3, gl::FLOAT, gl::FALSE_, 2*sizeof(Eigen::Vector3f), (void*)0);
180
181 gl::EnableVertexAttribArray (1);
182 gl::VertexAttribPointer (1, 3, gl::FLOAT, gl::FALSE_, 2*sizeof(Eigen::Vector3f), (void*)(sizeof(Eigen::Vector3f)));
183 }
184 else {
185 vertex_buffer.bind (gl::ARRAY_BUFFER);
187 }
188
189 gl::BufferData (gl::ARRAY_BUFFER, 8*sizeof(Eigen::Vector3f), &vertices[0][0], gl::STREAM_DRAW);
190 gl::DrawArrays (gl::TRIANGLE_FAN, 0, 4);
191 }
192
193 };
194
195
196 }
197 }
198}
199
200#endif
201
static bool get_bool(const std::string &key, bool default_value)
void set_interp(GLint type) const
Definition: gl.h:207
void gen(GLenum target, GLint interp_type=gl::LINEAR)
Definition: gl.h:174
void bind() const
Definition: gl.h:201
void bind(GLenum target) const
Definition: gl.h:243
Eigen::Vector3f z
Definition: volume.h:144
MR::Header _header
Definition: volume.h:134
GL::Texture _texture
Definition: volume.h:136
Eigen::Vector3f im_z
Definition: volume.h:144
Eigen::Vector3f tex[4]
Definition: volume.h:144
Eigen::Vector3f vertices[8]
Definition: volume.h:145
GL::Texture * _current_texture
Definition: volume.h:137
GL::VertexBuffer vertex_buffer
Definition: volume.h:138
GL::VertexArrayObject vertex_array_object
Definition: volume.h:139
void set_vertices_for_slice_render(const Projection &projection, float depth)
Definition: volume.h:151
Eigen::Vector3f div(const Eigen::Vector3f &a, const Eigen::Vector3f &b)
Definition: volume.h:147
Eigen::Vector3f pos[4]
Definition: volume.h:144
Eigen::Vector3f screen_to_model(float x, float y, float depth) const
Definition: projection.h:101
void set(GL::Shader::Program &shader_program) const
Definition: projection.h:277
const Entry maps[]
Definition: base.h:24
size_t index