volmetrics

diff src/main.cc @ 36:1df14c5ffa71

conversion to Qt
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 06 Feb 2015 22:39:51 +0200
parents df4a277adb82
children
line diff
     1.1 --- a/src/main.cc	Fri Feb 06 21:15:23 2015 +0200
     1.2 +++ b/src/main.cc	Fri Feb 06 22:39:51 2015 +0200
     1.3 @@ -1,588 +1,11 @@
     1.4 -#include "opengl.h"
     1.5 +#include "mainwin.h"
     1.6 +#include <QApplication>
     1.7  
     1.8 -#include <math.h>
     1.9 -#include <stdio.h>
    1.10 -#include <assert.h>
    1.11 +int main(int argc, char *argv[])
    1.12 +{
    1.13 +	QApplication a(argc, argv);
    1.14 +	MainWin w;
    1.15 +	w.show();
    1.16  
    1.17 -#include <vector>
    1.18 -
    1.19 -#include "mesh.h"
    1.20 -#include "sdr.h"
    1.21 -#include "volume.h"
    1.22 -
    1.23 -static bool init(void);
    1.24 -static GLUI *create_ui(void);
    1.25 -static void display(void);
    1.26 -static void reshape(int x, int y);
    1.27 -static void keyboard(unsigned char key, int x, int y);
    1.28 -static void keyboard_up(unsigned char key, int x, int y);
    1.29 -static void mouse(int button, int state, int x, int y);
    1.30 -static void motion(int x, int y);
    1.31 -static bool init_xfer(void);
    1.32 -static void display_xfer(void);
    1.33 -static void reshape_xfer(int x, int y);
    1.34 -static void mouse_xfer(int button, int state, int x, int y);
    1.35 -static void motion_xfer(int x, int y);
    1.36 -static void volume_preview();
    1.37 -static void draw_iso();
    1.38 -static void draw_volume();
    1.39 -
    1.40 -static int mainwin_id, xferwin_id;
    1.41 -//todo keyb esc
    1.42 -
    1.43 -static int win_xsz, win_ysz;
    1.44 -static float cam_phi, cam_theta, cam_dist = 6;
    1.45 -static std::vector<bool> key_state(256);
    1.46 -
    1.47 -static const char *vol_fname = "data/test1.vol";
    1.48 -static const char *vsdr_path = "data/shaders/transfer.v.glsl";
    1.49 -static const char *fsdr_path = "data/shaders/transfer.f.glsl";
    1.50 -static const char *vsdr_vol_path = "data/shaders/vol.v.glsl";
    1.51 -static const char *fsdr_vol_path = "data/shaders/vol.f.glsl";
    1.52 -
    1.53 -static unsigned int sprog;
    1.54 -static unsigned int sprog_vol;
    1.55 -
    1.56 -static Volume *vol;
    1.57 -static Mesh *mesh;
    1.58 -static float cur_z, thres = 0.5, thres2 = 1.0;
    1.59 -static float slice_z = 0.5;
    1.60 -
    1.61 -static int use_orig_vol_res = 1;
    1.62 -static int vol_res[3]; // volume sampling resolution x/y/z
    1.63 -static float bound_scale = 1.42;
    1.64 -
    1.65 -static GLUI *ui;
    1.66 -
    1.67 -static int num_poly = 128;
    1.68 -
    1.69 -int main(int argc, char **argv)
    1.70 -{
    1.71 -	glutInitWindowSize(512, 512);
    1.72 -	glutInit(&argc, argv);
    1.73 -	if(argv[1])
    1.74 -		vol_fname = argv[1];
    1.75 -
    1.76 -	if(!init()) {
    1.77 -		fprintf(stderr, "Failed to initialize program.\n");
    1.78 -		return 1;
    1.79 -	}
    1.80 -
    1.81 -	init_xfer();
    1.82 -
    1.83 -	glutMainLoop();
    1.84 -	return 0;
    1.85 +	return a.exec();
    1.86  }
    1.87 -
    1.88 -static bool init()
    1.89 -{
    1.90 -	glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
    1.91 -
    1.92 -	mainwin_id = glutCreateWindow("CT scan");
    1.93 -	glutDisplayFunc(display);
    1.94 -	glutReshapeFunc(reshape);
    1.95 -	glutKeyboardFunc(keyboard);
    1.96 -	glutKeyboardUpFunc(keyboard_up);
    1.97 -	glutMouseFunc(mouse);
    1.98 -	glutMotionFunc(motion);
    1.99 -
   1.100 -	glewInit();
   1.101 -
   1.102 -	glEnable(GL_DEPTH_TEST);
   1.103 -	glEnable(GL_NORMALIZE);
   1.104 -
   1.105 -	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
   1.106 -
   1.107 -	//FIXME shaders setup
   1.108 -	if(!(sprog = sdr_getprog(vsdr_path, fsdr_path)))
   1.109 -	{
   1.110 -		fprintf(stderr, "Failed to create shader program!\n");
   1.111 -		return false;
   1.112 -	}
   1.113 -
   1.114 -	if(!(sprog_vol = sdr_getprog(vsdr_vol_path, fsdr_vol_path)))
   1.115 -	{
   1.116 -		fprintf(stderr, "Failed to create shader program!\n");
   1.117 -		return false;
   1.118 -	}
   1.119 -
   1.120 -	vol = new Volume;
   1.121 -	if(!vol->load(vol_fname)) {
   1.122 -		fprintf(stderr, "Failed to load %s", vol_fname);
   1.123 -		return false;
   1.124 -	}
   1.125 -	mesh = new Mesh;
   1.126 -	cur_z = 0.5;
   1.127 -
   1.128 -	vol_res[0] = vol->get_slice(0)->get_width();
   1.129 -	vol_res[1] = vol->get_slice(0)->get_height();
   1.130 -	vol_res[2] = vol->get_slice_count();
   1.131 -
   1.132 -	num_poly = std::max(vol_res[0], std::max(vol_res[1], vol_res[2])) * bound_scale;
   1.133 -
   1.134 -	if(!(ui = create_ui())) {
   1.135 -		return false;
   1.136 -	}
   1.137 -
   1.138 -	return true;
   1.139 -}
   1.140 -
   1.141 -static GLUI_Spinner *res_spin[3];
   1.142 -static void toggle_use_orig(int id)
   1.143 -{
   1.144 -	for(int i=0; i<3; i++) {
   1.145 -		if(use_orig_vol_res) {
   1.146 -			res_spin[i]->disable();
   1.147 -		} else {
   1.148 -			res_spin[i]->enable();
   1.149 -		}
   1.150 -	}
   1.151 -}
   1.152 -static void thres_change(int id)
   1.153 -{
   1.154 -	static float prev_thres = thres;
   1.155 -	static float prev_thres2 = thres2;
   1.156 -
   1.157 -	if(prev_thres != thres || prev_thres2 != thres2) {
   1.158 -		prev_thres = thres;
   1.159 -		prev_thres2 = thres2;
   1.160 -
   1.161 -		mesh->clear();
   1.162 -
   1.163 -		glutSetWindow(xferwin_id);
   1.164 -		glutPostRedisplay();
   1.165 -		glutSetWindow(mainwin_id);
   1.166 -		glutPostRedisplay();
   1.167 -	}
   1.168 -}
   1.169 -
   1.170 -static void res_change(int id)
   1.171 -{
   1.172 -	static float prev_resx = vol_res[0];
   1.173 -	static float prev_resy = vol_res[1];
   1.174 -	static float prev_resz = vol_res[2];
   1.175 -
   1.176 -	if(prev_resx != vol_res[0] || prev_resy != vol_res[1] || prev_resz != vol_res[2]) {
   1.177 -		prev_resx = vol_res[0];
   1.178 -		prev_resy = vol_res[1];
   1.179 -		prev_resz = vol_res[2];
   1.180 -		mesh->clear();
   1.181 -	}
   1.182 -}
   1.183 -static GLUI *create_ui()
   1.184 -{
   1.185 -	GLUI *ui = GLUI_Master.create_glui("ui");
   1.186 -	assert(ui);
   1.187 -
   1.188 -	ui->set_main_gfx_window(glutGetWindow());
   1.189 -
   1.190 -	GLUI_Panel *thres_panel = ui->add_panel("iso thresholds");
   1.191 -
   1.192 -	GLUI_Spinner *thres_spin = ui->add_spinner_to_panel(thres_panel, "T1", GLUI_SPINNER_FLOAT, &thres, 0, thres_change);
   1.193 -	thres_spin->set_float_limits(0, 1);
   1.194 -
   1.195 -	GLUI_Spinner *thres2_spin = ui->add_spinner_to_panel(thres_panel, "T2", GLUI_SPINNER_FLOAT, &thres2, 0, thres_change);
   1.196 -	thres2_spin->set_float_limits(0, 1);
   1.197 -
   1.198 -#ifdef ISO
   1.199 -	GLUI_Panel *res_panel = ui->add_panel("volume resolution");
   1.200 -
   1.201 -	ui->add_checkbox_to_panel(res_panel, "original resolution", &use_orig_vol_res, 0, toggle_use_orig);
   1.202 -
   1.203 -	static const char *res_spin_name[] = {"x", "y", "z"};
   1.204 -	for(int i=0; i<3; i++) {
   1.205 -		res_spin[i] = ui->add_spinner_to_panel(res_panel, res_spin_name[i], GLUI_SPINNER_INT, vol_res + i, 0, res_change);
   1.206 -		res_spin[i]->set_int_limits(8, 256); // TODO limits as arguments or config
   1.207 -		res_spin[i]->disable();
   1.208 -	}
   1.209 -#endif
   1.210 -	GLUI_Panel *preview_panel = ui->add_panel("volume preview");
   1.211 -
   1.212 -	GLUI_Spinner *preview_spin = ui->add_spinner_to_panel(preview_panel, "slice z", GLUI_SPINNER_FLOAT, &slice_z, 0);
   1.213 -	preview_spin->set_float_limits(0, 1);
   1.214 -
   1.215 -	return ui;
   1.216 -}
   1.217 -
   1.218 -static void volume_preview ()
   1.219 -{
   1.220 -	float aspect = win_xsz / win_ysz;
   1.221 -
   1.222 -	glDisable(GL_DEPTH_TEST);
   1.223 -
   1.224 -	glUseProgram(sprog);
   1.225 -	int tmin_loc = glGetUniformLocation(sprog, "tmin");
   1.226 -	if(tmin_loc != -1)
   1.227 -		glUniform1f(tmin_loc, std::min(thres, thres2));
   1.228 -	int tmax_loc = glGetUniformLocation(sprog, "tmax");
   1.229 -	if(tmax_loc != -1)
   1.230 -		glUniform1f(tmax_loc, std::max(thres, thres2));
   1.231 -
   1.232 -	glMatrixMode(GL_MODELVIEW);
   1.233 -	glPushMatrix();
   1.234 -	glLoadIdentity();
   1.235 -
   1.236 -	glMatrixMode(GL_PROJECTION);
   1.237 -	glPushMatrix();
   1.238 -	glLoadIdentity();
   1.239 -	glOrtho(0, aspect, 0, 1, -1, 1);
   1.240 -
   1.241 -	glBindTexture(GL_TEXTURE_3D, vol->get_texture());
   1.242 -	glEnable(GL_TEXTURE_3D);
   1.243 -	glBegin(GL_QUADS);
   1.244 -	glColor3f(1.0, 1.0, 1.0);
   1.245 -	glTexCoord3f(0, 0, slice_z); glVertex3f(0, 1, 0);
   1.246 -	glTexCoord3f(0, 1, slice_z); glVertex3f(0, 0.75, 0);
   1.247 -	glTexCoord3f(1, 1, slice_z); glVertex3f(0.25, 0.75, 0);
   1.248 -	glTexCoord3f(1, 0, slice_z); glVertex3f(0.25, 1, 0);
   1.249 -	glEnd();
   1.250 -	glDisable(GL_TEXTURE_3D);
   1.251 -
   1.252 -	glUseProgram(0);
   1.253 -
   1.254 -	glLineWidth(2);
   1.255 -	glBegin(GL_LINE_LOOP);
   1.256 -	glColor3f(0.8, 0.3, 0.8);
   1.257 -	glVertex3f(0, 1, 0);
   1.258 -	glVertex3f(0, 0.75, 0);
   1.259 -	glVertex3f(0.25, 0.75, 0);
   1.260 -	glVertex3f(0.25, 1, 0);
   1.261 -	glEnd();
   1.262 -
   1.263 -	glMatrixMode(GL_PROJECTION);
   1.264 -	glPopMatrix();
   1.265 -
   1.266 -	glMatrixMode(GL_MODELVIEW);
   1.267 -	glPopMatrix();
   1.268 -
   1.269 -	glEnable(GL_DEPTH_TEST);
   1.270 -}
   1.271 -
   1.272 -static void draw_iso()
   1.273 -{
   1.274 -	if(mesh->is_empty()) {
   1.275 -		printf("recalculating isosurface ... ");
   1.276 -		fflush(stdout);
   1.277 -		vol->create_mesh(mesh, thres, thres2, vol_res[0], vol_res[1], vol_res[2]);
   1.278 -		printf("done.\n");
   1.279 -	}
   1.280 -	mesh->draw();
   1.281 -}
   1.282 -
   1.283 -static void draw_volume()
   1.284 -{
   1.285 -	glUseProgram(sprog_vol);
   1.286 -
   1.287 -	int tmin_loc = glGetUniformLocation(sprog_vol, "tmin");
   1.288 -	if(tmin_loc != -1)
   1.289 -		glUniform1f(tmin_loc, std::min(thres, thres2));
   1.290 -	int tmax_loc = glGetUniformLocation(sprog_vol, "tmax");
   1.291 -	if(tmax_loc != -1)
   1.292 -		glUniform1f(tmax_loc, std::max(thres, thres2));
   1.293 -
   1.294 -	int res_loc = glGetUniformLocation(sprog_vol, "res");
   1.295 -	if(res_loc != -1)
   1.296 -		glUniform3f(res_loc, (float)vol_res[0], (float)vol_res[1], (float)vol_res[2]);
   1.297 -
   1.298 -	glRotatef(-vol->get_volume_rotation(), 1, 0, 0);
   1.299 -
   1.300 -	glDisable(GL_DEPTH_TEST);
   1.301 -	glBindTexture(GL_TEXTURE_3D, vol->get_texture());
   1.302 -	glEnable(GL_TEXTURE_3D);
   1.303 -	glEnable(GL_BLEND);
   1.304 -	glBegin(GL_QUADS);
   1.305 -	for(int i=0; i<num_poly; i++)
   1.306 -	{
   1.307 -		float tex_z = (float)i / (float)num_poly;
   1.308 -		float z = 2 * tex_z - 1;
   1.309 -
   1.310 -		glTexCoord3f(0, 0, tex_z); glVertex3f(-bound_scale, -bound_scale, z * bound_scale);
   1.311 -		glTexCoord3f(0, 1, tex_z); glVertex3f(-bound_scale, bound_scale, z * bound_scale);
   1.312 -		glTexCoord3f(1, 1, tex_z); glVertex3f(bound_scale, bound_scale, z * bound_scale);
   1.313 -		glTexCoord3f(1, 0, tex_z); glVertex3f(bound_scale, -bound_scale, z * bound_scale);
   1.314 -	}
   1.315 -	glEnd();
   1.316 -	glDisable(GL_BLEND);
   1.317 -	glDisable(GL_TEXTURE_3D);
   1.318 -	glEnable(GL_DEPTH_TEST);
   1.319 -
   1.320 -	glUseProgram(0);
   1.321 -}
   1.322 -
   1.323 -static void display(void)
   1.324 -{
   1.325 -	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   1.326 -
   1.327 -	glMatrixMode(GL_MODELVIEW);
   1.328 -	glLoadIdentity();
   1.329 -	glTranslatef(0, 0, -cam_dist);
   1.330 -	glRotatef(cam_phi, 1, 0, 0);
   1.331 -	glRotatef(cam_theta, 0, 1, 0);
   1.332 -
   1.333 -	//draw_slices();
   1.334 -	//draw_iso();
   1.335 -	draw_volume();
   1.336 -
   1.337 -	volume_preview();
   1.338 -	glutSwapBuffers();
   1.339 -	assert(glGetError() == GL_NO_ERROR);
   1.340 -}
   1.341 -
   1.342 -static void reshape(int x, int y)
   1.343 -{
   1.344 -	glViewport(0, 0, x, y);
   1.345 -	glMatrixMode(GL_PROJECTION);
   1.346 -	glLoadIdentity();
   1.347 -	gluPerspective(45, (float)x / (float)y, 0.5, 500);
   1.348 -
   1.349 -	win_xsz = x;
   1.350 -	win_ysz = y;
   1.351 -}
   1.352 -
   1.353 -static void keyboard(unsigned char key, int x, int y)
   1.354 -{
   1.355 -	key_state[(int)key] = true;
   1.356 -
   1.357 -	switch(key) {
   1.358 -		case 27:
   1.359 -			exit(0);
   1.360 -		case 'w':
   1.361 -			{
   1.362 -				static bool wire;
   1.363 -				wire = !wire;
   1.364 -				glPolygonMode(GL_FRONT_AND_BACK, wire ? GL_LINE : GL_FILL);
   1.365 -			}
   1.366 -			break;
   1.367 -		default:
   1.368 -			break;
   1.369 -	}
   1.370 -}
   1.371 -
   1.372 -static void keyboard_up(unsigned char key, int x, int y)
   1.373 -{
   1.374 -	key_state[(int) key] = false;
   1.375 -}
   1.376 -
   1.377 -static int prev_x, prev_y;
   1.378 -static bool bn_state[32];
   1.379 -static float prev_thres, prev_thres2;
   1.380 -
   1.381 -static void mouse(int bn, int state, int x, int y)
   1.382 -{
   1.383 -	prev_x = x;
   1.384 -	prev_y = y;
   1.385 -
   1.386 -	bn_state[bn - GLUT_LEFT_BUTTON] = (state == GLUT_DOWN);
   1.387 -
   1.388 -	if(state == GLUT_DOWN) {
   1.389 -		prev_thres = thres;
   1.390 -		prev_thres2 = thres2;
   1.391 -	}
   1.392 -	else {
   1.393 -		if(thres != prev_thres || thres2 != prev_thres2) {
   1.394 -			mesh->clear();
   1.395 -		}
   1.396 -	}
   1.397 -}
   1.398 -
   1.399 -static void motion(int x, int y)
   1.400 -{
   1.401 -	int dx = x - prev_x;
   1.402 -	int dy = y - prev_y;
   1.403 -
   1.404 -	if(!dx && !dy)
   1.405 -		return;
   1.406 -
   1.407 -	prev_x = x;
   1.408 -	prev_y = y;
   1.409 -
   1.410 -	if(key_state[(int)'t']) {
   1.411 -		thres = (float)x / (float)win_xsz;
   1.412 -		printf("threshold: %f\n", thres);
   1.413 -
   1.414 -		glutPostRedisplay();
   1.415 -		return;
   1.416 -	}
   1.417 -
   1.418 -	// camera
   1.419 -	if(bn_state[0]) {
   1.420 -		if(key_state[(int)'z']) {
   1.421 -			//zoom the camera
   1.422 -
   1.423 -			cam_dist += dy * 0.1;
   1.424 -
   1.425 -			if(cam_dist < 0)
   1.426 -				cam_dist = 0;
   1.427 -		}
   1.428 -		else {
   1.429 -			//rotate the camera
   1.430 -
   1.431 -			cam_phi += dy * 0.5;
   1.432 -			cam_theta += dx * 0.5;
   1.433 -
   1.434 -			if(cam_phi > 90)
   1.435 -				cam_phi = 90;
   1.436 -			if(cam_phi < -90)
   1.437 -				cam_phi = -90;
   1.438 -		}
   1.439 -
   1.440 -		glutPostRedisplay();
   1.441 -	}
   1.442 -}
   1.443 -
   1.444 -static bool init_xfer(void)
   1.445 -{
   1.446 -	glutSetWindow(mainwin_id);
   1.447 -	int x = glutGet(GLUT_WINDOW_X);
   1.448 -	int y = glutGet(GLUT_WINDOW_Y) + glutGet(GLUT_WINDOW_HEIGHT);
   1.449 -
   1.450 -	glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
   1.451 -	glutInitWindowSize(512, 100);
   1.452 -	glutInitWindowPosition(x, y);
   1.453 -
   1.454 -	xferwin_id = glutCreateWindow("Transfer Function");
   1.455 -	glutDisplayFunc(display_xfer);
   1.456 -	glutReshapeFunc(reshape_xfer);
   1.457 -	glutMouseFunc(mouse_xfer);
   1.458 -	glutMotionFunc(motion_xfer);
   1.459 -
   1.460 -	return true;
   1.461 -}
   1.462 -
   1.463 -static void display_xfer(void)
   1.464 -{
   1.465 -	glClear(GL_COLOR_BUFFER_BIT);
   1.466 -
   1.467 -	int num_val = glutGet(GLUT_WINDOW_WIDTH) / 4.0;
   1.468 -	float x = 0;
   1.469 -	float dx = 1.0 / num_val;
   1.470 -	float low, high;
   1.471 -	if(thres < thres2) {
   1.472 -		low = thres;
   1.473 -		high = thres2;
   1.474 -	}
   1.475 -	else {
   1.476 -		low = thres2;
   1.477 -		high = thres;
   1.478 -	}
   1.479 -
   1.480 -
   1.481 -	//drawing the histogram
   1.482 -	float hmax = 1 / (float)vol->max_histogram_value;
   1.483 -
   1.484 -	glBegin(GL_QUADS);
   1.485 -	for (int i=0; i<HIST_SIZE; i++) {
   1.486 -		float x0 = (float)i / HIST_SIZE;
   1.487 -		float x1 = (float)(i + 1) / HIST_SIZE;
   1.488 -
   1.489 -		glColor3f(0.3, 0.3, 0.3);
   1.490 -		glVertex3f(x0, 0, 0);
   1.491 -		glVertex3f(x1, 0, 0);
   1.492 -		glVertex3f(x1, hmax * vol->histogram[i + 1], 0);
   1.493 -		glVertex3f(x0, hmax * vol->histogram[i], 0);
   1.494 -	}
   1.495 -	glEnd();
   1.496 -
   1.497 -	//drawing the transfer function curve
   1.498 -
   1.499 -	glLineWidth(3);
   1.500 -	glBegin(GL_LINE_STRIP);
   1.501 -	glColor3f(0.8, 0.3, 0.8);
   1.502 -	for(int i=0; i<num_val; i++) {
   1.503 -		float val = transfer_function(x, low, high);
   1.504 -		glVertex2f(x, val);
   1.505 -		x += dx;
   1.506 -	}
   1.507 -	glEnd();
   1.508 -
   1.509 -	//threshold bars
   1.510 -
   1.511 -	glLineWidth(2);
   1.512 -	glBegin(GL_LINES);
   1.513 -	glColor3f(0.4, 0.4, 0.8);
   1.514 -	glVertex2f(low, 0);
   1.515 -	glVertex2f(low, 1);
   1.516 -	glColor3f(0.4, 0.8, 0.4);
   1.517 -	glVertex2f(high, 0);
   1.518 -	glVertex2f(high, 1);
   1.519 -	glEnd();
   1.520 -
   1.521 -/*
   1.522 - * gradient
   1.523 - */
   1.524 -/*  glBegin(GL_QUADS);
   1.525 -	for(int i=0; i<num_val; i++) {
   1.526 -		float val = transfer_function(x, low, high);
   1.527 -		glColor3f(val, val, val);
   1.528 -		glVertex3f(x, 1.0, 0.0);
   1.529 -		glVertex3f(x, 0.0, 0.0);
   1.530 -
   1.531 -		val = transfer_function(x + dx, low, high);
   1.532 -		glColor3f(val, val, val);
   1.533 -		glVertex3f(x + dx, 0.0, 0.0);
   1.534 -		glVertex3f(x + dx, 1.0, 0.0);
   1.535 -		x += dx;
   1.536 -	}
   1.537 -	glEnd(); */
   1.538 -
   1.539 -	glutSwapBuffers();
   1.540 -	assert(glGetError() == GL_NO_ERROR);
   1.541 -}
   1.542 -
   1.543 -static void reshape_xfer(int x, int y)
   1.544 -{
   1.545 -	glViewport(0.0, 0.0, x, y);
   1.546 -	glMatrixMode(GL_PROJECTION);
   1.547 -	glLoadIdentity();
   1.548 -	glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
   1.549 -}
   1.550 -
   1.551 -static float *select_thres;
   1.552 -static float prev_select_thres;
   1.553 -static void mouse_xfer(int button, int state, int x, int y)
   1.554 -{
   1.555 -	if(button == GLUT_LEFT_BUTTON) {
   1.556 -		if(state == GLUT_DOWN) {
   1.557 -			int width = glutGet(GLUT_WINDOW_WIDTH);
   1.558 -			float xpos = (float)x / (float)width;
   1.559 -			if(fabs(xpos - thres) <= fabs(xpos - thres2) && fabs(xpos - thres) < 0.1) {
   1.560 -				select_thres = &thres;
   1.561 -			}
   1.562 -			else if (fabs(xpos - thres2) < 0.1) {
   1.563 -				select_thres = &thres2;
   1.564 -			}
   1.565 -			else
   1.566 -				select_thres = 0;
   1.567 -
   1.568 -			if (select_thres)
   1.569 -				prev_select_thres = *select_thres;
   1.570 -		}
   1.571 -		else {
   1.572 -			if(!prev_select_thres || !select_thres) {
   1.573 -				select_thres = 0;
   1.574 -				return;
   1.575 -			}
   1.576 -			if(fabs(*select_thres - prev_select_thres) > 0.001) {
   1.577 -				mesh->clear();
   1.578 -				ui->sync_live();
   1.579 -			}
   1.580 -			select_thres = 0;
   1.581 -		}
   1.582 -	}
   1.583 -}
   1.584 -
   1.585 -static void motion_xfer(int x, int y)
   1.586 -{
   1.587 -	if(!select_thres)
   1.588 -		return;
   1.589 -
   1.590 -	int width = glutGet(GLUT_WINDOW_WIDTH);
   1.591 -	float xpos = (float)x / (float)width;
   1.592 -
   1.593 -	*select_thres = xpos;
   1.594 -	thres_change(0);
   1.595 -
   1.596 -	glutPostRedisplay();
   1.597 -	glutSetWindow(mainwin_id);
   1.598 -	glutPostRedisplay();
   1.599 -}