volmetrics

changeset 36:1df14c5ffa71

conversion to Qt
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 06 Feb 2015 22:39:51 +0200
parents df4a277adb82
children 1d935677d3ab
files .hgignore src/glview.cc src/glview.h src/main.cc src/mainwin.cc src/mainwin.h src/opengl.h src/view3d.cc src/view3d.h ui/mainwin.ui volmetrics.pro
diffstat 11 files changed, 441 insertions(+), 594 deletions(-) [+]
line diff
     1.1 --- a/.hgignore	Fri Feb 06 21:15:23 2015 +0200
     1.2 +++ b/.hgignore	Fri Feb 06 22:39:51 2015 +0200
     1.3 @@ -3,3 +3,5 @@
     1.4  \.swp$
     1.5  ^data/
     1.6  ^test1$
     1.7 +^build/
     1.8 +\.user$
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/glview.cc	Fri Feb 06 22:39:51 2015 +0200
     2.3 @@ -0,0 +1,38 @@
     2.4 +#include <QApplication>
     2.5 +#include "opengl.h"
     2.6 +#include "glview.h"
     2.7 +#include "view3d.h"
     2.8 +//#include "view2d.h"
     2.9 +
    2.10 +extern View3D view3d;
    2.11 +
    2.12 +GLView::GLView(QWidget *parent)
    2.13 +	: QOpenGLWidget(parent)
    2.14 +{
    2.15 +}
    2.16 +
    2.17 +GLView::~GLView()
    2.18 +{
    2.19 +}
    2.20 +
    2.21 +
    2.22 +void GLView::initializeGL()
    2.23 +{
    2.24 +	glewInit();
    2.25 +
    2.26 +	if(!view3d.init(this)) {
    2.27 +		QApplication::quit();
    2.28 +	}
    2.29 +}
    2.30 +
    2.31 +void GLView::paintGL()
    2.32 +{
    2.33 +	view3d.display();
    2.34 +}
    2.35 +
    2.36 +void GLView::resizeGL(int x, int y)
    2.37 +{
    2.38 +	glViewport(0, 0, x, y);
    2.39 +
    2.40 +	view3d.reshape(x, y);
    2.41 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/glview.h	Fri Feb 06 22:39:51 2015 +0200
     3.3 @@ -0,0 +1,16 @@
     3.4 +#ifndef GLVIEW_H
     3.5 +#define GLVIEW_H
     3.6 +
     3.7 +#include <QOpenGLWidget>
     3.8 +
     3.9 +class GLView : public QOpenGLWidget {
    3.10 +public:
    3.11 +	GLView(QWidget * parent = 0);
    3.12 +	~GLView();
    3.13 +
    3.14 +	void initializeGL();
    3.15 +	void paintGL();
    3.16 +	void resizeGL(int x, int y);
    3.17 +};
    3.18 +
    3.19 +#endif // GLVIEW_H
     4.1 --- a/src/main.cc	Fri Feb 06 21:15:23 2015 +0200
     4.2 +++ b/src/main.cc	Fri Feb 06 22:39:51 2015 +0200
     4.3 @@ -1,588 +1,11 @@
     4.4 -#include "opengl.h"
     4.5 +#include "mainwin.h"
     4.6 +#include <QApplication>
     4.7  
     4.8 -#include <math.h>
     4.9 -#include <stdio.h>
    4.10 -#include <assert.h>
    4.11 +int main(int argc, char *argv[])
    4.12 +{
    4.13 +	QApplication a(argc, argv);
    4.14 +	MainWin w;
    4.15 +	w.show();
    4.16  
    4.17 -#include <vector>
    4.18 -
    4.19 -#include "mesh.h"
    4.20 -#include "sdr.h"
    4.21 -#include "volume.h"
    4.22 -
    4.23 -static bool init(void);
    4.24 -static GLUI *create_ui(void);
    4.25 -static void display(void);
    4.26 -static void reshape(int x, int y);
    4.27 -static void keyboard(unsigned char key, int x, int y);
    4.28 -static void keyboard_up(unsigned char key, int x, int y);
    4.29 -static void mouse(int button, int state, int x, int y);
    4.30 -static void motion(int x, int y);
    4.31 -static bool init_xfer(void);
    4.32 -static void display_xfer(void);
    4.33 -static void reshape_xfer(int x, int y);
    4.34 -static void mouse_xfer(int button, int state, int x, int y);
    4.35 -static void motion_xfer(int x, int y);
    4.36 -static void volume_preview();
    4.37 -static void draw_iso();
    4.38 -static void draw_volume();
    4.39 -
    4.40 -static int mainwin_id, xferwin_id;
    4.41 -//todo keyb esc
    4.42 -
    4.43 -static int win_xsz, win_ysz;
    4.44 -static float cam_phi, cam_theta, cam_dist = 6;
    4.45 -static std::vector<bool> key_state(256);
    4.46 -
    4.47 -static const char *vol_fname = "data/test1.vol";
    4.48 -static const char *vsdr_path = "data/shaders/transfer.v.glsl";
    4.49 -static const char *fsdr_path = "data/shaders/transfer.f.glsl";
    4.50 -static const char *vsdr_vol_path = "data/shaders/vol.v.glsl";
    4.51 -static const char *fsdr_vol_path = "data/shaders/vol.f.glsl";
    4.52 -
    4.53 -static unsigned int sprog;
    4.54 -static unsigned int sprog_vol;
    4.55 -
    4.56 -static Volume *vol;
    4.57 -static Mesh *mesh;
    4.58 -static float cur_z, thres = 0.5, thres2 = 1.0;
    4.59 -static float slice_z = 0.5;
    4.60 -
    4.61 -static int use_orig_vol_res = 1;
    4.62 -static int vol_res[3]; // volume sampling resolution x/y/z
    4.63 -static float bound_scale = 1.42;
    4.64 -
    4.65 -static GLUI *ui;
    4.66 -
    4.67 -static int num_poly = 128;
    4.68 -
    4.69 -int main(int argc, char **argv)
    4.70 -{
    4.71 -	glutInitWindowSize(512, 512);
    4.72 -	glutInit(&argc, argv);
    4.73 -	if(argv[1])
    4.74 -		vol_fname = argv[1];
    4.75 -
    4.76 -	if(!init()) {
    4.77 -		fprintf(stderr, "Failed to initialize program.\n");
    4.78 -		return 1;
    4.79 -	}
    4.80 -
    4.81 -	init_xfer();
    4.82 -
    4.83 -	glutMainLoop();
    4.84 -	return 0;
    4.85 +	return a.exec();
    4.86  }
    4.87 -
    4.88 -static bool init()
    4.89 -{
    4.90 -	glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
    4.91 -
    4.92 -	mainwin_id = glutCreateWindow("CT scan");
    4.93 -	glutDisplayFunc(display);
    4.94 -	glutReshapeFunc(reshape);
    4.95 -	glutKeyboardFunc(keyboard);
    4.96 -	glutKeyboardUpFunc(keyboard_up);
    4.97 -	glutMouseFunc(mouse);
    4.98 -	glutMotionFunc(motion);
    4.99 -
   4.100 -	glewInit();
   4.101 -
   4.102 -	glEnable(GL_DEPTH_TEST);
   4.103 -	glEnable(GL_NORMALIZE);
   4.104 -
   4.105 -	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
   4.106 -
   4.107 -	//FIXME shaders setup
   4.108 -	if(!(sprog = sdr_getprog(vsdr_path, fsdr_path)))
   4.109 -	{
   4.110 -		fprintf(stderr, "Failed to create shader program!\n");
   4.111 -		return false;
   4.112 -	}
   4.113 -
   4.114 -	if(!(sprog_vol = sdr_getprog(vsdr_vol_path, fsdr_vol_path)))
   4.115 -	{
   4.116 -		fprintf(stderr, "Failed to create shader program!\n");
   4.117 -		return false;
   4.118 -	}
   4.119 -
   4.120 -	vol = new Volume;
   4.121 -	if(!vol->load(vol_fname)) {
   4.122 -		fprintf(stderr, "Failed to load %s", vol_fname);
   4.123 -		return false;
   4.124 -	}
   4.125 -	mesh = new Mesh;
   4.126 -	cur_z = 0.5;
   4.127 -
   4.128 -	vol_res[0] = vol->get_slice(0)->get_width();
   4.129 -	vol_res[1] = vol->get_slice(0)->get_height();
   4.130 -	vol_res[2] = vol->get_slice_count();
   4.131 -
   4.132 -	num_poly = std::max(vol_res[0], std::max(vol_res[1], vol_res[2])) * bound_scale;
   4.133 -
   4.134 -	if(!(ui = create_ui())) {
   4.135 -		return false;
   4.136 -	}
   4.137 -
   4.138 -	return true;
   4.139 -}
   4.140 -
   4.141 -static GLUI_Spinner *res_spin[3];
   4.142 -static void toggle_use_orig(int id)
   4.143 -{
   4.144 -	for(int i=0; i<3; i++) {
   4.145 -		if(use_orig_vol_res) {
   4.146 -			res_spin[i]->disable();
   4.147 -		} else {
   4.148 -			res_spin[i]->enable();
   4.149 -		}
   4.150 -	}
   4.151 -}
   4.152 -static void thres_change(int id)
   4.153 -{
   4.154 -	static float prev_thres = thres;
   4.155 -	static float prev_thres2 = thres2;
   4.156 -
   4.157 -	if(prev_thres != thres || prev_thres2 != thres2) {
   4.158 -		prev_thres = thres;
   4.159 -		prev_thres2 = thres2;
   4.160 -
   4.161 -		mesh->clear();
   4.162 -
   4.163 -		glutSetWindow(xferwin_id);
   4.164 -		glutPostRedisplay();
   4.165 -		glutSetWindow(mainwin_id);
   4.166 -		glutPostRedisplay();
   4.167 -	}
   4.168 -}
   4.169 -
   4.170 -static void res_change(int id)
   4.171 -{
   4.172 -	static float prev_resx = vol_res[0];
   4.173 -	static float prev_resy = vol_res[1];
   4.174 -	static float prev_resz = vol_res[2];
   4.175 -
   4.176 -	if(prev_resx != vol_res[0] || prev_resy != vol_res[1] || prev_resz != vol_res[2]) {
   4.177 -		prev_resx = vol_res[0];
   4.178 -		prev_resy = vol_res[1];
   4.179 -		prev_resz = vol_res[2];
   4.180 -		mesh->clear();
   4.181 -	}
   4.182 -}
   4.183 -static GLUI *create_ui()
   4.184 -{
   4.185 -	GLUI *ui = GLUI_Master.create_glui("ui");
   4.186 -	assert(ui);
   4.187 -
   4.188 -	ui->set_main_gfx_window(glutGetWindow());
   4.189 -
   4.190 -	GLUI_Panel *thres_panel = ui->add_panel("iso thresholds");
   4.191 -
   4.192 -	GLUI_Spinner *thres_spin = ui->add_spinner_to_panel(thres_panel, "T1", GLUI_SPINNER_FLOAT, &thres, 0, thres_change);
   4.193 -	thres_spin->set_float_limits(0, 1);
   4.194 -
   4.195 -	GLUI_Spinner *thres2_spin = ui->add_spinner_to_panel(thres_panel, "T2", GLUI_SPINNER_FLOAT, &thres2, 0, thres_change);
   4.196 -	thres2_spin->set_float_limits(0, 1);
   4.197 -
   4.198 -#ifdef ISO
   4.199 -	GLUI_Panel *res_panel = ui->add_panel("volume resolution");
   4.200 -
   4.201 -	ui->add_checkbox_to_panel(res_panel, "original resolution", &use_orig_vol_res, 0, toggle_use_orig);
   4.202 -
   4.203 -	static const char *res_spin_name[] = {"x", "y", "z"};
   4.204 -	for(int i=0; i<3; i++) {
   4.205 -		res_spin[i] = ui->add_spinner_to_panel(res_panel, res_spin_name[i], GLUI_SPINNER_INT, vol_res + i, 0, res_change);
   4.206 -		res_spin[i]->set_int_limits(8, 256); // TODO limits as arguments or config
   4.207 -		res_spin[i]->disable();
   4.208 -	}
   4.209 -#endif
   4.210 -	GLUI_Panel *preview_panel = ui->add_panel("volume preview");
   4.211 -
   4.212 -	GLUI_Spinner *preview_spin = ui->add_spinner_to_panel(preview_panel, "slice z", GLUI_SPINNER_FLOAT, &slice_z, 0);
   4.213 -	preview_spin->set_float_limits(0, 1);
   4.214 -
   4.215 -	return ui;
   4.216 -}
   4.217 -
   4.218 -static void volume_preview ()
   4.219 -{
   4.220 -	float aspect = win_xsz / win_ysz;
   4.221 -
   4.222 -	glDisable(GL_DEPTH_TEST);
   4.223 -
   4.224 -	glUseProgram(sprog);
   4.225 -	int tmin_loc = glGetUniformLocation(sprog, "tmin");
   4.226 -	if(tmin_loc != -1)
   4.227 -		glUniform1f(tmin_loc, std::min(thres, thres2));
   4.228 -	int tmax_loc = glGetUniformLocation(sprog, "tmax");
   4.229 -	if(tmax_loc != -1)
   4.230 -		glUniform1f(tmax_loc, std::max(thres, thres2));
   4.231 -
   4.232 -	glMatrixMode(GL_MODELVIEW);
   4.233 -	glPushMatrix();
   4.234 -	glLoadIdentity();
   4.235 -
   4.236 -	glMatrixMode(GL_PROJECTION);
   4.237 -	glPushMatrix();
   4.238 -	glLoadIdentity();
   4.239 -	glOrtho(0, aspect, 0, 1, -1, 1);
   4.240 -
   4.241 -	glBindTexture(GL_TEXTURE_3D, vol->get_texture());
   4.242 -	glEnable(GL_TEXTURE_3D);
   4.243 -	glBegin(GL_QUADS);
   4.244 -	glColor3f(1.0, 1.0, 1.0);
   4.245 -	glTexCoord3f(0, 0, slice_z); glVertex3f(0, 1, 0);
   4.246 -	glTexCoord3f(0, 1, slice_z); glVertex3f(0, 0.75, 0);
   4.247 -	glTexCoord3f(1, 1, slice_z); glVertex3f(0.25, 0.75, 0);
   4.248 -	glTexCoord3f(1, 0, slice_z); glVertex3f(0.25, 1, 0);
   4.249 -	glEnd();
   4.250 -	glDisable(GL_TEXTURE_3D);
   4.251 -
   4.252 -	glUseProgram(0);
   4.253 -
   4.254 -	glLineWidth(2);
   4.255 -	glBegin(GL_LINE_LOOP);
   4.256 -	glColor3f(0.8, 0.3, 0.8);
   4.257 -	glVertex3f(0, 1, 0);
   4.258 -	glVertex3f(0, 0.75, 0);
   4.259 -	glVertex3f(0.25, 0.75, 0);
   4.260 -	glVertex3f(0.25, 1, 0);
   4.261 -	glEnd();
   4.262 -
   4.263 -	glMatrixMode(GL_PROJECTION);
   4.264 -	glPopMatrix();
   4.265 -
   4.266 -	glMatrixMode(GL_MODELVIEW);
   4.267 -	glPopMatrix();
   4.268 -
   4.269 -	glEnable(GL_DEPTH_TEST);
   4.270 -}
   4.271 -
   4.272 -static void draw_iso()
   4.273 -{
   4.274 -	if(mesh->is_empty()) {
   4.275 -		printf("recalculating isosurface ... ");
   4.276 -		fflush(stdout);
   4.277 -		vol->create_mesh(mesh, thres, thres2, vol_res[0], vol_res[1], vol_res[2]);
   4.278 -		printf("done.\n");
   4.279 -	}
   4.280 -	mesh->draw();
   4.281 -}
   4.282 -
   4.283 -static void draw_volume()
   4.284 -{
   4.285 -	glUseProgram(sprog_vol);
   4.286 -
   4.287 -	int tmin_loc = glGetUniformLocation(sprog_vol, "tmin");
   4.288 -	if(tmin_loc != -1)
   4.289 -		glUniform1f(tmin_loc, std::min(thres, thres2));
   4.290 -	int tmax_loc = glGetUniformLocation(sprog_vol, "tmax");
   4.291 -	if(tmax_loc != -1)
   4.292 -		glUniform1f(tmax_loc, std::max(thres, thres2));
   4.293 -
   4.294 -	int res_loc = glGetUniformLocation(sprog_vol, "res");
   4.295 -	if(res_loc != -1)
   4.296 -		glUniform3f(res_loc, (float)vol_res[0], (float)vol_res[1], (float)vol_res[2]);
   4.297 -
   4.298 -	glRotatef(-vol->get_volume_rotation(), 1, 0, 0);
   4.299 -
   4.300 -	glDisable(GL_DEPTH_TEST);
   4.301 -	glBindTexture(GL_TEXTURE_3D, vol->get_texture());
   4.302 -	glEnable(GL_TEXTURE_3D);
   4.303 -	glEnable(GL_BLEND);
   4.304 -	glBegin(GL_QUADS);
   4.305 -	for(int i=0; i<num_poly; i++)
   4.306 -	{
   4.307 -		float tex_z = (float)i / (float)num_poly;
   4.308 -		float z = 2 * tex_z - 1;
   4.309 -
   4.310 -		glTexCoord3f(0, 0, tex_z); glVertex3f(-bound_scale, -bound_scale, z * bound_scale);
   4.311 -		glTexCoord3f(0, 1, tex_z); glVertex3f(-bound_scale, bound_scale, z * bound_scale);
   4.312 -		glTexCoord3f(1, 1, tex_z); glVertex3f(bound_scale, bound_scale, z * bound_scale);
   4.313 -		glTexCoord3f(1, 0, tex_z); glVertex3f(bound_scale, -bound_scale, z * bound_scale);
   4.314 -	}
   4.315 -	glEnd();
   4.316 -	glDisable(GL_BLEND);
   4.317 -	glDisable(GL_TEXTURE_3D);
   4.318 -	glEnable(GL_DEPTH_TEST);
   4.319 -
   4.320 -	glUseProgram(0);
   4.321 -}
   4.322 -
   4.323 -static void display(void)
   4.324 -{
   4.325 -	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   4.326 -
   4.327 -	glMatrixMode(GL_MODELVIEW);
   4.328 -	glLoadIdentity();
   4.329 -	glTranslatef(0, 0, -cam_dist);
   4.330 -	glRotatef(cam_phi, 1, 0, 0);
   4.331 -	glRotatef(cam_theta, 0, 1, 0);
   4.332 -
   4.333 -	//draw_slices();
   4.334 -	//draw_iso();
   4.335 -	draw_volume();
   4.336 -
   4.337 -	volume_preview();
   4.338 -	glutSwapBuffers();
   4.339 -	assert(glGetError() == GL_NO_ERROR);
   4.340 -}
   4.341 -
   4.342 -static void reshape(int x, int y)
   4.343 -{
   4.344 -	glViewport(0, 0, x, y);
   4.345 -	glMatrixMode(GL_PROJECTION);
   4.346 -	glLoadIdentity();
   4.347 -	gluPerspective(45, (float)x / (float)y, 0.5, 500);
   4.348 -
   4.349 -	win_xsz = x;
   4.350 -	win_ysz = y;
   4.351 -}
   4.352 -
   4.353 -static void keyboard(unsigned char key, int x, int y)
   4.354 -{
   4.355 -	key_state[(int)key] = true;
   4.356 -
   4.357 -	switch(key) {
   4.358 -		case 27:
   4.359 -			exit(0);
   4.360 -		case 'w':
   4.361 -			{
   4.362 -				static bool wire;
   4.363 -				wire = !wire;
   4.364 -				glPolygonMode(GL_FRONT_AND_BACK, wire ? GL_LINE : GL_FILL);
   4.365 -			}
   4.366 -			break;
   4.367 -		default:
   4.368 -			break;
   4.369 -	}
   4.370 -}
   4.371 -
   4.372 -static void keyboard_up(unsigned char key, int x, int y)
   4.373 -{
   4.374 -	key_state[(int) key] = false;
   4.375 -}
   4.376 -
   4.377 -static int prev_x, prev_y;
   4.378 -static bool bn_state[32];
   4.379 -static float prev_thres, prev_thres2;
   4.380 -
   4.381 -static void mouse(int bn, int state, int x, int y)
   4.382 -{
   4.383 -	prev_x = x;
   4.384 -	prev_y = y;
   4.385 -
   4.386 -	bn_state[bn - GLUT_LEFT_BUTTON] = (state == GLUT_DOWN);
   4.387 -
   4.388 -	if(state == GLUT_DOWN) {
   4.389 -		prev_thres = thres;
   4.390 -		prev_thres2 = thres2;
   4.391 -	}
   4.392 -	else {
   4.393 -		if(thres != prev_thres || thres2 != prev_thres2) {
   4.394 -			mesh->clear();
   4.395 -		}
   4.396 -	}
   4.397 -}
   4.398 -
   4.399 -static void motion(int x, int y)
   4.400 -{
   4.401 -	int dx = x - prev_x;
   4.402 -	int dy = y - prev_y;
   4.403 -
   4.404 -	if(!dx && !dy)
   4.405 -		return;
   4.406 -
   4.407 -	prev_x = x;
   4.408 -	prev_y = y;
   4.409 -
   4.410 -	if(key_state[(int)'t']) {
   4.411 -		thres = (float)x / (float)win_xsz;
   4.412 -		printf("threshold: %f\n", thres);
   4.413 -
   4.414 -		glutPostRedisplay();
   4.415 -		return;
   4.416 -	}
   4.417 -
   4.418 -	// camera
   4.419 -	if(bn_state[0]) {
   4.420 -		if(key_state[(int)'z']) {
   4.421 -			//zoom the camera
   4.422 -
   4.423 -			cam_dist += dy * 0.1;
   4.424 -
   4.425 -			if(cam_dist < 0)
   4.426 -				cam_dist = 0;
   4.427 -		}
   4.428 -		else {
   4.429 -			//rotate the camera
   4.430 -
   4.431 -			cam_phi += dy * 0.5;
   4.432 -			cam_theta += dx * 0.5;
   4.433 -
   4.434 -			if(cam_phi > 90)
   4.435 -				cam_phi = 90;
   4.436 -			if(cam_phi < -90)
   4.437 -				cam_phi = -90;
   4.438 -		}
   4.439 -
   4.440 -		glutPostRedisplay();
   4.441 -	}
   4.442 -}
   4.443 -
   4.444 -static bool init_xfer(void)
   4.445 -{
   4.446 -	glutSetWindow(mainwin_id);
   4.447 -	int x = glutGet(GLUT_WINDOW_X);
   4.448 -	int y = glutGet(GLUT_WINDOW_Y) + glutGet(GLUT_WINDOW_HEIGHT);
   4.449 -
   4.450 -	glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
   4.451 -	glutInitWindowSize(512, 100);
   4.452 -	glutInitWindowPosition(x, y);
   4.453 -
   4.454 -	xferwin_id = glutCreateWindow("Transfer Function");
   4.455 -	glutDisplayFunc(display_xfer);
   4.456 -	glutReshapeFunc(reshape_xfer);
   4.457 -	glutMouseFunc(mouse_xfer);
   4.458 -	glutMotionFunc(motion_xfer);
   4.459 -
   4.460 -	return true;
   4.461 -}
   4.462 -
   4.463 -static void display_xfer(void)
   4.464 -{
   4.465 -	glClear(GL_COLOR_BUFFER_BIT);
   4.466 -
   4.467 -	int num_val = glutGet(GLUT_WINDOW_WIDTH) / 4.0;
   4.468 -	float x = 0;
   4.469 -	float dx = 1.0 / num_val;
   4.470 -	float low, high;
   4.471 -	if(thres < thres2) {
   4.472 -		low = thres;
   4.473 -		high = thres2;
   4.474 -	}
   4.475 -	else {
   4.476 -		low = thres2;
   4.477 -		high = thres;
   4.478 -	}
   4.479 -
   4.480 -
   4.481 -	//drawing the histogram
   4.482 -	float hmax = 1 / (float)vol->max_histogram_value;
   4.483 -
   4.484 -	glBegin(GL_QUADS);
   4.485 -	for (int i=0; i<HIST_SIZE; i++) {
   4.486 -		float x0 = (float)i / HIST_SIZE;
   4.487 -		float x1 = (float)(i + 1) / HIST_SIZE;
   4.488 -
   4.489 -		glColor3f(0.3, 0.3, 0.3);
   4.490 -		glVertex3f(x0, 0, 0);
   4.491 -		glVertex3f(x1, 0, 0);
   4.492 -		glVertex3f(x1, hmax * vol->histogram[i + 1], 0);
   4.493 -		glVertex3f(x0, hmax * vol->histogram[i], 0);
   4.494 -	}
   4.495 -	glEnd();
   4.496 -
   4.497 -	//drawing the transfer function curve
   4.498 -
   4.499 -	glLineWidth(3);
   4.500 -	glBegin(GL_LINE_STRIP);
   4.501 -	glColor3f(0.8, 0.3, 0.8);
   4.502 -	for(int i=0; i<num_val; i++) {
   4.503 -		float val = transfer_function(x, low, high);
   4.504 -		glVertex2f(x, val);
   4.505 -		x += dx;
   4.506 -	}
   4.507 -	glEnd();
   4.508 -
   4.509 -	//threshold bars
   4.510 -
   4.511 -	glLineWidth(2);
   4.512 -	glBegin(GL_LINES);
   4.513 -	glColor3f(0.4, 0.4, 0.8);
   4.514 -	glVertex2f(low, 0);
   4.515 -	glVertex2f(low, 1);
   4.516 -	glColor3f(0.4, 0.8, 0.4);
   4.517 -	glVertex2f(high, 0);
   4.518 -	glVertex2f(high, 1);
   4.519 -	glEnd();
   4.520 -
   4.521 -/*
   4.522 - * gradient
   4.523 - */
   4.524 -/*  glBegin(GL_QUADS);
   4.525 -	for(int i=0; i<num_val; i++) {
   4.526 -		float val = transfer_function(x, low, high);
   4.527 -		glColor3f(val, val, val);
   4.528 -		glVertex3f(x, 1.0, 0.0);
   4.529 -		glVertex3f(x, 0.0, 0.0);
   4.530 -
   4.531 -		val = transfer_function(x + dx, low, high);
   4.532 -		glColor3f(val, val, val);
   4.533 -		glVertex3f(x + dx, 0.0, 0.0);
   4.534 -		glVertex3f(x + dx, 1.0, 0.0);
   4.535 -		x += dx;
   4.536 -	}
   4.537 -	glEnd(); */
   4.538 -
   4.539 -	glutSwapBuffers();
   4.540 -	assert(glGetError() == GL_NO_ERROR);
   4.541 -}
   4.542 -
   4.543 -static void reshape_xfer(int x, int y)
   4.544 -{
   4.545 -	glViewport(0.0, 0.0, x, y);
   4.546 -	glMatrixMode(GL_PROJECTION);
   4.547 -	glLoadIdentity();
   4.548 -	glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
   4.549 -}
   4.550 -
   4.551 -static float *select_thres;
   4.552 -static float prev_select_thres;
   4.553 -static void mouse_xfer(int button, int state, int x, int y)
   4.554 -{
   4.555 -	if(button == GLUT_LEFT_BUTTON) {
   4.556 -		if(state == GLUT_DOWN) {
   4.557 -			int width = glutGet(GLUT_WINDOW_WIDTH);
   4.558 -			float xpos = (float)x / (float)width;
   4.559 -			if(fabs(xpos - thres) <= fabs(xpos - thres2) && fabs(xpos - thres) < 0.1) {
   4.560 -				select_thres = &thres;
   4.561 -			}
   4.562 -			else if (fabs(xpos - thres2) < 0.1) {
   4.563 -				select_thres = &thres2;
   4.564 -			}
   4.565 -			else
   4.566 -				select_thres = 0;
   4.567 -
   4.568 -			if (select_thres)
   4.569 -				prev_select_thres = *select_thres;
   4.570 -		}
   4.571 -		else {
   4.572 -			if(!prev_select_thres || !select_thres) {
   4.573 -				select_thres = 0;
   4.574 -				return;
   4.575 -			}
   4.576 -			if(fabs(*select_thres - prev_select_thres) > 0.001) {
   4.577 -				mesh->clear();
   4.578 -				ui->sync_live();
   4.579 -			}
   4.580 -			select_thres = 0;
   4.581 -		}
   4.582 -	}
   4.583 -}
   4.584 -
   4.585 -static void motion_xfer(int x, int y)
   4.586 -{
   4.587 -	if(!select_thres)
   4.588 -		return;
   4.589 -
   4.590 -	int width = glutGet(GLUT_WINDOW_WIDTH);
   4.591 -	float xpos = (float)x / (float)width;
   4.592 -
   4.593 -	*select_thres = xpos;
   4.594 -	thres_change(0);
   4.595 -
   4.596 -	glutPostRedisplay();
   4.597 -	glutSetWindow(mainwin_id);
   4.598 -	glutPostRedisplay();
   4.599 -}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/src/mainwin.cc	Fri Feb 06 22:39:51 2015 +0200
     5.3 @@ -0,0 +1,42 @@
     5.4 +#include <QMessageBox>
     5.5 +#include "mainwin.h"
     5.6 +#include "ui_mainwin.h"
     5.7 +#include "view3d.h"
     5.8 +
     5.9 +View3D view3d;
    5.10 +
    5.11 +MainWin::MainWin(QWidget *parent) :
    5.12 +	QMainWindow(parent),
    5.13 +	ui(new Ui::MainWin)
    5.14 +{
    5.15 +	ui->setupUi(this);
    5.16 +}
    5.17 +
    5.18 +MainWin::~MainWin()
    5.19 +{
    5.20 +	delete ui;
    5.21 +}
    5.22 +
    5.23 +void MainWin::on_action_quit_triggered()
    5.24 +{
    5.25 +	close();
    5.26 +}
    5.27 +
    5.28 +void MainWin::on_action_about_triggered()
    5.29 +{
    5.30 +	static const char *text =
    5.31 +			"Volmetrics version whatever\n"
    5.32 +			"Copyright (C) 2015 Eleni-Maria Stea, Stathis Kamperis\n"
    5.33 +			"web page, emails, support, blah blah ... whatever.";
    5.34 +	QMessageBox::about(this, "About", text);
    5.35 +}
    5.36 +
    5.37 +void MainWin::on_spin_win_low_valueChanged(double arg1)
    5.38 +{
    5.39 +	view3d.set_thresholds(arg1, ui->spin_win_high->value());
    5.40 +}
    5.41 +
    5.42 +void MainWin::on_spin_win_high_valueChanged(double arg1)
    5.43 +{
    5.44 +	view3d.set_thresholds(ui->spin_win_low->value(), arg1);
    5.45 +}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/mainwin.h	Fri Feb 06 22:39:51 2015 +0200
     6.3 @@ -0,0 +1,31 @@
     6.4 +#ifndef MAINWIN_H
     6.5 +#define MAINWIN_H
     6.6 +
     6.7 +#include <QMainWindow>
     6.8 +
     6.9 +namespace Ui {
    6.10 +class MainWin;
    6.11 +}
    6.12 +
    6.13 +class MainWin : public QMainWindow
    6.14 +{
    6.15 +	Q_OBJECT
    6.16 +
    6.17 +public:
    6.18 +	explicit MainWin(QWidget *parent = 0);
    6.19 +	~MainWin();
    6.20 +
    6.21 +private slots:
    6.22 +	void on_action_quit_triggered();
    6.23 +
    6.24 +	void on_action_about_triggered();
    6.25 +
    6.26 +	void on_spin_win_low_valueChanged(double arg1);
    6.27 +
    6.28 +	void on_spin_win_high_valueChanged(double arg1);
    6.29 +
    6.30 +private:
    6.31 +	Ui::MainWin *ui;
    6.32 +};
    6.33 +
    6.34 +#endif // MAINWIN_H
     7.1 --- a/src/opengl.h	Fri Feb 06 21:15:23 2015 +0200
     7.2 +++ b/src/opengl.h	Fri Feb 06 22:39:51 2015 +0200
     7.3 @@ -3,13 +3,4 @@
     7.4  
     7.5  #include <GL/glew.h>
     7.6  
     7.7 -#ifndef __APPLE__
     7.8 -#include <GL/glut.h>
     7.9 -#else
    7.10 -#include <GLUT/glut.h>
    7.11 -#endif
    7.12 -
    7.13 -#include <GL/glui.h>
    7.14 -
    7.15 -
    7.16  #endif	// OPENGL_H_
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/src/view3d.cc	Fri Feb 06 22:39:51 2015 +0200
     8.3 @@ -0,0 +1,68 @@
     8.4 +#include <algorithm>
     8.5 +#include "opengl.h"
     8.6 +#include "view3d.h"
     8.7 +#include "volume.h"
     8.8 +
     8.9 +static int win_width, win_height;
    8.10 +
    8.11 +View3D::View3D()
    8.12 +{
    8.13 +	vol = 0;
    8.14 +	thres_low = 0.0;
    8.15 +	thres_high = 1.0;
    8.16 +}
    8.17 +
    8.18 +View3D::~View3D()
    8.19 +{
    8.20 +	destroy();
    8.21 +}
    8.22 +
    8.23 +bool View3D::init(GLView *glview)
    8.24 +{
    8.25 +	this->glview = glview;
    8.26 +	return true;
    8.27 +}
    8.28 +
    8.29 +void View3D::destroy()
    8.30 +{
    8.31 +}
    8.32 +
    8.33 +void View3D::display()
    8.34 +{
    8.35 +	glClearColor(0, 0, 0, 1);
    8.36 +	glClear(GL_COLOR_BUFFER_BIT);
    8.37 +
    8.38 +	glBegin(GL_QUADS);
    8.39 +	glColor3f(1, 0, 0);
    8.40 +	glVertex2f(thres_low * 2.0 - 1.0, 1);
    8.41 +	glVertex2f(thres_low * 2.0 - 1.0, -1);
    8.42 +	glColor3f(0, 0, 1);
    8.43 +	glVertex2f(thres_high * 2.0 - 1.0, -1);
    8.44 +	glVertex2f(thres_high * 2.0 - 1.0, 1);
    8.45 +	glEnd();
    8.46 +}
    8.47 +
    8.48 +
    8.49 +void View3D::reshape(int x, int y)
    8.50 +{
    8.51 +	win_width = x;
    8.52 +	win_height = y;
    8.53 +}
    8.54 +
    8.55 +void View3D::set_volume(Volume *vol)
    8.56 +{
    8.57 +	if(this->vol) {
    8.58 +		delete this->vol;
    8.59 +	}
    8.60 +	this->vol = vol;
    8.61 +
    8.62 +	glview->update();
    8.63 +}
    8.64 +
    8.65 +void View3D::set_thresholds(float low, float high)
    8.66 +{
    8.67 +	thres_low = std::min(low, high);
    8.68 +	thres_high = std::max(low, high);
    8.69 +
    8.70 +	glview->update();
    8.71 +}
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/src/view3d.h	Fri Feb 06 22:39:51 2015 +0200
     9.3 @@ -0,0 +1,28 @@
     9.4 +#ifndef VIEW3D_H_
     9.5 +#define VIEW3D_H_
     9.6 +
     9.7 +#include "glview.h"
     9.8 +#include "volume.h"
     9.9 +
    9.10 +class View3D {
    9.11 +private:
    9.12 +	Volume *vol;
    9.13 +	float thres_low, thres_high;
    9.14 +	GLView *glview;
    9.15 +
    9.16 +public:
    9.17 +	View3D();
    9.18 +	~View3D();
    9.19 +
    9.20 +	bool init(GLView *glview);
    9.21 +	void destroy();
    9.22 +
    9.23 +	void display();
    9.24 +	void reshape(int x, int y);
    9.25 +
    9.26 +	void set_volume(Volume *vol);
    9.27 +	void set_thresholds(float low, float high);
    9.28 +};
    9.29 +
    9.30 +#endif // VIEW3D_H_
    9.31 +
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/ui/mainwin.ui	Fri Feb 06 22:39:51 2015 +0200
    10.3 @@ -0,0 +1,160 @@
    10.4 +<?xml version="1.0" encoding="UTF-8"?>
    10.5 +<ui version="4.0">
    10.6 + <class>MainWin</class>
    10.7 + <widget class="QMainWindow" name="MainWin">
    10.8 +  <property name="geometry">
    10.9 +   <rect>
   10.10 +    <x>0</x>
   10.11 +    <y>0</y>
   10.12 +    <width>701</width>
   10.13 +    <height>471</height>
   10.14 +   </rect>
   10.15 +  </property>
   10.16 +  <property name="windowTitle">
   10.17 +   <string>MainWin</string>
   10.18 +  </property>
   10.19 +  <widget class="QWidget" name="centralWidget">
   10.20 +   <layout class="QHBoxLayout" name="horizontalLayout">
   10.21 +    <item>
   10.22 +     <widget class="GLView" name="glview"/>
   10.23 +    </item>
   10.24 +   </layout>
   10.25 +  </widget>
   10.26 +  <widget class="QMenuBar" name="menuBar">
   10.27 +   <property name="geometry">
   10.28 +    <rect>
   10.29 +     <x>0</x>
   10.30 +     <y>0</y>
   10.31 +     <width>701</width>
   10.32 +     <height>22</height>
   10.33 +    </rect>
   10.34 +   </property>
   10.35 +   <widget class="QMenu" name="menu_File">
   10.36 +    <property name="title">
   10.37 +     <string>&amp;File</string>
   10.38 +    </property>
   10.39 +    <addaction name="action_open"/>
   10.40 +    <addaction name="separator"/>
   10.41 +    <addaction name="action_quit"/>
   10.42 +   </widget>
   10.43 +   <widget class="QMenu" name="menu_Help">
   10.44 +    <property name="title">
   10.45 +     <string>&amp;Help</string>
   10.46 +    </property>
   10.47 +    <addaction name="action_about"/>
   10.48 +   </widget>
   10.49 +   <addaction name="menu_File"/>
   10.50 +   <addaction name="menu_Help"/>
   10.51 +  </widget>
   10.52 +  <widget class="QToolBar" name="mainToolBar">
   10.53 +   <attribute name="toolBarArea">
   10.54 +    <enum>TopToolBarArea</enum>
   10.55 +   </attribute>
   10.56 +   <attribute name="toolBarBreak">
   10.57 +    <bool>false</bool>
   10.58 +   </attribute>
   10.59 +  </widget>
   10.60 +  <widget class="QStatusBar" name="status_bar"/>
   10.61 +  <widget class="QDockWidget" name="dockWidget">
   10.62 +   <attribute name="dockWidgetArea">
   10.63 +    <number>1</number>
   10.64 +   </attribute>
   10.65 +   <widget class="QWidget" name="dockWidgetContents">
   10.66 +    <layout class="QVBoxLayout" name="verticalLayout_2">
   10.67 +     <item>
   10.68 +      <widget class="QGroupBox" name="groupBox">
   10.69 +       <property name="title">
   10.70 +        <string>Windowing</string>
   10.71 +       </property>
   10.72 +       <layout class="QVBoxLayout" name="verticalLayout">
   10.73 +        <item>
   10.74 +         <layout class="QHBoxLayout" name="horizontalLayout_2">
   10.75 +          <item>
   10.76 +           <widget class="QLabel" name="label">
   10.77 +            <property name="text">
   10.78 +             <string>low</string>
   10.79 +            </property>
   10.80 +           </widget>
   10.81 +          </item>
   10.82 +          <item>
   10.83 +           <widget class="QDoubleSpinBox" name="spin_win_low">
   10.84 +            <property name="maximum">
   10.85 +             <double>1.000000000000000</double>
   10.86 +            </property>
   10.87 +            <property name="singleStep">
   10.88 +             <double>0.010000000000000</double>
   10.89 +            </property>
   10.90 +           </widget>
   10.91 +          </item>
   10.92 +         </layout>
   10.93 +        </item>
   10.94 +        <item>
   10.95 +         <layout class="QHBoxLayout" name="horizontalLayout_3">
   10.96 +          <item>
   10.97 +           <widget class="QLabel" name="label_2">
   10.98 +            <property name="text">
   10.99 +             <string>high</string>
  10.100 +            </property>
  10.101 +           </widget>
  10.102 +          </item>
  10.103 +          <item>
  10.104 +           <widget class="QDoubleSpinBox" name="spin_win_high">
  10.105 +            <property name="maximum">
  10.106 +             <double>1.000000000000000</double>
  10.107 +            </property>
  10.108 +            <property name="singleStep">
  10.109 +             <double>0.010000000000000</double>
  10.110 +            </property>
  10.111 +            <property name="value">
  10.112 +             <double>1.000000000000000</double>
  10.113 +            </property>
  10.114 +           </widget>
  10.115 +          </item>
  10.116 +         </layout>
  10.117 +        </item>
  10.118 +       </layout>
  10.119 +      </widget>
  10.120 +     </item>
  10.121 +     <item>
  10.122 +      <spacer name="verticalSpacer">
  10.123 +       <property name="orientation">
  10.124 +        <enum>Qt::Vertical</enum>
  10.125 +       </property>
  10.126 +       <property name="sizeHint" stdset="0">
  10.127 +        <size>
  10.128 +         <width>20</width>
  10.129 +         <height>252</height>
  10.130 +        </size>
  10.131 +       </property>
  10.132 +      </spacer>
  10.133 +     </item>
  10.134 +    </layout>
  10.135 +   </widget>
  10.136 +  </widget>
  10.137 +  <action name="action_open">
  10.138 +   <property name="text">
  10.139 +    <string>&amp;Open</string>
  10.140 +   </property>
  10.141 +  </action>
  10.142 +  <action name="action_quit">
  10.143 +   <property name="text">
  10.144 +    <string>&amp;Quit</string>
  10.145 +   </property>
  10.146 +  </action>
  10.147 +  <action name="action_about">
  10.148 +   <property name="text">
  10.149 +    <string>&amp;About</string>
  10.150 +   </property>
  10.151 +  </action>
  10.152 + </widget>
  10.153 + <layoutdefault spacing="6" margin="11"/>
  10.154 + <customwidgets>
  10.155 +  <customwidget>
  10.156 +   <class>GLView</class>
  10.157 +   <extends>QOpenGLWidget</extends>
  10.158 +   <header>glview.h</header>
  10.159 +  </customwidget>
  10.160 + </customwidgets>
  10.161 + <resources/>
  10.162 + <connections/>
  10.163 +</ui>
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/volmetrics.pro	Fri Feb 06 22:39:51 2015 +0200
    11.3 @@ -0,0 +1,48 @@
    11.4 +#-------------------------------------------------
    11.5 +#
    11.6 +# Project created by QtCreator 2015-02-06T21:21:47
    11.7 +#
    11.8 +#-------------------------------------------------
    11.9 +
   11.10 +QT       += core gui
   11.11 +
   11.12 +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
   11.13 +
   11.14 +TARGET = volmetrics
   11.15 +TEMPLATE = app
   11.16 +
   11.17 +CONFIG += c++11
   11.18 +
   11.19 +
   11.20 +SOURCES += \
   11.21 +    src/image.cc \
   11.22 +    src/main.cc \
   11.23 +    src/mainwin.cc \
   11.24 +    src/matrix.cc \
   11.25 +    src/mesh.cc \
   11.26 +    src/sdr.cc \
   11.27 +    src/vector.cc \
   11.28 +    src/volume.cc \
   11.29 +    src/glview.cc \
   11.30 +    src/view3d.cc
   11.31 +
   11.32 +HEADERS  += \
   11.33 +    src/image.h \
   11.34 +    src/mainwin.h \
   11.35 +    src/matrix.h \
   11.36 +    src/mesh.h \
   11.37 +    src/opengl.h \
   11.38 +    src/sdr.h \
   11.39 +    src/vector.h \
   11.40 +    src/volume.h \
   11.41 +    src/glview.h \
   11.42 +    src/view3d.h
   11.43 +
   11.44 +FORMS    += \
   11.45 +    ui/mainwin.ui
   11.46 +
   11.47 +INCLUDEPATH += src /usr/local/include
   11.48 +
   11.49 +LIBS += -limago
   11.50 +unix: LIBS += -L/usr/local/lib -lGLEW
   11.51 +win32: LIBS += -lglew32