glviewvol

changeset 6:f22be47a3572

moved to TransferFuncs completely
author John Tsiombikas <nuclear@member.fsf.org>
date Tue, 30 Dec 2014 06:22:54 +0200
parents 5417c25cb238
children 71b479ffb9f7
files src/dicomview.cc src/main.cc src/opt.cc src/opt.h src/rend_fast.cc src/rend_fast.h src/renderer.cc src/renderer.h src/xfer_view.cc src/xfer_view.h src/xfermap.cc src/xfermap.h
diffstat 12 files changed, 157 insertions(+), 108 deletions(-) [+]
line diff
     1.1 --- a/src/dicomview.cc	Mon Dec 29 15:59:55 2014 +0200
     1.2 +++ b/src/dicomview.cc	Tue Dec 30 06:22:54 2014 +0200
     1.3 @@ -15,6 +15,7 @@
     1.4  
     1.5  static Renderer *rend;
     1.6  static Volume *vol;
     1.7 +static TransferFunc *xfer;
     1.8  
     1.9  extern "C" {
    1.10  
    1.11 @@ -46,7 +47,10 @@
    1.12  	vol = voxvol;
    1.13  	rend->set_volume(vol);
    1.14  
    1.15 -	if(!xfview_init(rend)) {
    1.16 +	xfer = new TransferWindow;
    1.17 +	rend->set_transfer_function(xfer);
    1.18 +
    1.19 +	if(!xfview_init(xfer)) {
    1.20  		return -1;
    1.21  	}
    1.22  
    1.23 @@ -60,6 +64,7 @@
    1.24  	rend->destroy();
    1.25  	delete rend;
    1.26  	delete vol;
    1.27 +	delete xfer;
    1.28  }
    1.29  
    1.30  void ev_display()
     2.1 --- a/src/main.cc	Mon Dec 29 15:59:55 2014 +0200
     2.2 +++ b/src/main.cc	Tue Dec 30 06:22:54 2014 +0200
     2.3 @@ -30,7 +30,7 @@
     2.4  		return 1;
     2.5  	}
     2.6  
     2.7 -	glutInitWindowSize(1280, 800);
     2.8 +	glutInitWindowSize(opt.xsz, opt.ysz);
     2.9  	glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
    2.10  	glutCreateWindow("dicom viewer");
    2.11  
     3.1 --- a/src/opt.cc	Mon Dec 29 15:59:55 2014 +0200
     3.2 +++ b/src/opt.cc	Tue Dec 30 06:22:54 2014 +0200
     3.3 @@ -16,6 +16,8 @@
     3.4  {
     3.5  	opt.fname = 0;
     3.6  	opt.rend_type = REND_FAST;
     3.7 +	opt.xsz = 800;
     3.8 +	opt.ysz = 800;
     3.9  }
    3.10  
    3.11  static RendererType renderer_type(const char *name)
    3.12 @@ -36,6 +38,13 @@
    3.13  		if(argv[i][0] == '-') {
    3.14  			if(argv[i][2] == 0) {
    3.15  				switch(argv[i][1]) {
    3.16 +				case 's':
    3.17 +					if(sscanf(argv[++i], "%dx%d", &opt.xsz, &opt.ysz) != 2) {
    3.18 +						fprintf(stderr, "-s must be followed by the window size (WxH)\n");
    3.19 +						return -1;
    3.20 +					}
    3.21 +					break;
    3.22 +
    3.23  				case 'r':
    3.24  					if((opt.rend_type = renderer_type(argv[++i])) == REND_NONE) {
    3.25  						if(strcmp(argv[i], "help") == 0) {
     4.1 --- a/src/opt.h	Mon Dec 29 15:59:55 2014 +0200
     4.2 +++ b/src/opt.h	Tue Dec 30 06:22:54 2014 +0200
     4.3 @@ -9,6 +9,7 @@
     4.4  struct Options {
     4.5  	char *fname;
     4.6  	RendererType rend_type;
     4.7 +	int xsz, ysz;
     4.8  };
     4.9  
    4.10  extern Options opt;
     5.1 --- a/src/rend_fast.cc	Mon Dec 29 15:59:55 2014 +0200
     5.2 +++ b/src/rend_fast.cc	Tue Dec 30 06:22:54 2014 +0200
     5.3 @@ -34,7 +34,7 @@
     5.4  	glBindTexture(GL_TEXTURE_1D, xfer_tex);
     5.5  	glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
     5.6  	glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     5.7 -	glTexImage1D(GL_TEXTURE_1D, 0, have_tex_float ? GL_RGB16F : GL_RGB, XFER_MAP_SZ, 0, GL_RGB, GL_FLOAT, 0);
     5.8 +	glTexImage1D(GL_TEXTURE_1D, 0, have_tex_float ? GL_RGBA16F : GL_RGBA, XFER_MAP_SZ, 0, GL_RGB, GL_FLOAT, 0);
     5.9  
    5.10  	return true;
    5.11  }
    5.12 @@ -51,18 +51,6 @@
    5.13  	Renderer::set_volume(vol);
    5.14  }
    5.15  
    5.16 -Curve &RendererFast::transfer_curve(int color)
    5.17 -{
    5.18 -	xfer_tex_valid = false;
    5.19 -	return Renderer::transfer_curve(color);
    5.20 -}
    5.21 -
    5.22 -void RendererFast::set_simple_transfer(float low, float high)
    5.23 -{
    5.24 -	xfer_tex_valid = false;
    5.25 -	Renderer::set_simple_transfer(low, high);
    5.26 -}
    5.27 -
    5.28  void RendererFast::update(unsigned int msec)
    5.29  {
    5.30  	if(!vol) return;
    5.31 @@ -120,28 +108,23 @@
    5.32  		vol_tex_valid = true;
    5.33  	}
    5.34  
    5.35 -	if(!xfer_tex_valid) {
    5.36 -		float pixels[XFER_MAP_SZ * 3];
    5.37 +	if(1) {//if(!xfer_tex_valid) {
    5.38 +		float pixels[XFER_MAP_SZ * 4];
    5.39  		float *pptr = pixels;
    5.40  
    5.41  		for(int i=0; i<XFER_MAP_SZ; i++) {
    5.42  			float x = (float)i / (float)(XFER_MAP_SZ - 1);
    5.43  
    5.44 -			// TODO make 0.1 a tweakable parameter
    5.45 -			float val = smoothstep(xfer_low - 0.1, xfer_low + 0.1, x);
    5.46 -			val *= 1.0 - smoothstep(xfer_high - 0.1, xfer_high + 0.1, x);
    5.47 -			*pptr++ = val;
    5.48 -			*pptr++ = val;
    5.49 -			*pptr++ = val;
    5.50 -			/*
    5.51 -			*pptr++ = xfer[0].value(x);
    5.52 -			*pptr++ = xfer[1].value(x);
    5.53 -			*pptr++ = xfer[2].value(x);
    5.54 -			*/
    5.55 +			if(xfer) {
    5.56 +				xfer->map(x, pptr);
    5.57 +			} else {
    5.58 +				pptr[0] = pptr[1] = pptr[2] = pptr[3] = x;
    5.59 +			}
    5.60 +			pptr += 4;
    5.61  		}
    5.62  
    5.63  		glBindTexture(GL_TEXTURE_1D, xfer_tex);
    5.64 -		glTexSubImage1D(GL_TEXTURE_1D, 0, 0, XFER_MAP_SZ, GL_RGB, GL_FLOAT, pixels);
    5.65 +		glTexSubImage1D(GL_TEXTURE_1D, 0, 0, XFER_MAP_SZ, GL_RGBA, GL_FLOAT, pixels);
    5.66  
    5.67  		xfer_tex_valid = true;
    5.68  	}
     6.1 --- a/src/rend_fast.h	Mon Dec 29 15:59:55 2014 +0200
     6.2 +++ b/src/rend_fast.h	Tue Dec 30 06:22:54 2014 +0200
     6.3 @@ -15,8 +15,6 @@
     6.4  	void destroy();
     6.5  
     6.6  	void set_volume(Volume *vol);
     6.7 -	Curve &transfer_curve(int color);
     6.8 -	void set_simple_transfer(float low, float high);
     6.9  
    6.10  	void update(unsigned int msec);
    6.11  	void render() const;
     7.1 --- a/src/renderer.cc	Mon Dec 29 15:59:55 2014 +0200
     7.2 +++ b/src/renderer.cc	Tue Dec 30 06:22:54 2014 +0200
     7.3 @@ -7,14 +7,6 @@
     7.4  	view_width = 512;
     7.5  	view_height = 512;
     7.6  
     7.7 -	for(int i=0; i<3; i++) {
     7.8 -		xfer[i].set_point(0, 0);
     7.9 -		xfer[i].set_point(1, 1);
    7.10 -	}
    7.11 -
    7.12 -	xfer_low = 0.0;
    7.13 -	xfer_high = 1.0;
    7.14 -
    7.15  	for(int i=0; i<MAX_CLIP_PLANES; i++) {
    7.16  		disable_clipping_plane(i);
    7.17  	}
    7.18 @@ -44,26 +36,14 @@
    7.19  	return vol;
    7.20  }
    7.21  
    7.22 -Curve &Renderer::transfer_curve(int color)
    7.23 +void Renderer::set_transfer_function(TransferFunc *xfer)
    7.24  {
    7.25 -	return xfer[color];
    7.26 +	this->xfer = xfer;
    7.27  }
    7.28  
    7.29 -const Curve &Renderer::transfer_curve(int color) const
    7.30 +TransferFunc *Renderer::get_transfer_function() const
    7.31  {
    7.32 -	return xfer[color];
    7.33 -}
    7.34 -
    7.35 -void Renderer::set_simple_transfer(float low, float high)
    7.36 -{
    7.37 -	xfer_low = std::min(low, high);
    7.38 -	xfer_high = std::max(low, high);
    7.39 -}
    7.40 -
    7.41 -void Renderer::get_simple_transfer(float *low, float *high) const
    7.42 -{
    7.43 -	*low = xfer_low;
    7.44 -	*high = xfer_high;
    7.45 +	return xfer;
    7.46  }
    7.47  
    7.48  void Renderer::set_clipping_plane(int idx, float nx, float ny, float nz, float dist)
     8.1 --- a/src/renderer.h	Mon Dec 29 15:59:55 2014 +0200
     8.2 +++ b/src/renderer.h	Tue Dec 30 06:22:54 2014 +0200
     8.3 @@ -2,7 +2,7 @@
     8.4  #define RENDERER_H_
     8.5  
     8.6  #include "volume.h"
     8.7 -#include "curve.h"
     8.8 +#include "xfermap.h"
     8.9  
    8.10  #define MAX_CLIP_PLANES		4
    8.11  
    8.12 @@ -13,8 +13,7 @@
    8.13  
    8.14  	float clip_plane[MAX_CLIP_PLANES][4];	// nx,ny,nz,dist
    8.15  
    8.16 -	Curve xfer[3];	// rgb transfer function
    8.17 -	float xfer_low, xfer_high;	// simple transfer function bounds
    8.18 +	TransferFunc *xfer;
    8.19  
    8.20  public:
    8.21  	Renderer();
    8.22 @@ -26,11 +25,8 @@
    8.23  	virtual void set_volume(Volume *vol);
    8.24  	virtual Volume *get_volume() const;
    8.25  
    8.26 -	virtual Curve &transfer_curve(int color);
    8.27 -	virtual const Curve &transfer_curve(int color) const;
    8.28 -
    8.29 -	virtual void set_simple_transfer(float low, float high);
    8.30 -	virtual void get_simple_transfer(float *low, float *high) const;
    8.31 +	virtual void set_transfer_function(TransferFunc *xfer);
    8.32 +	virtual TransferFunc *get_transfer_function() const;
    8.33  
    8.34  	virtual void set_clipping_plane(int idx, float nx, float ny, float nz, float dist);
    8.35  	virtual void disable_clipping_plane(int idx);
     9.1 --- a/src/xfer_view.cc	Mon Dec 29 15:59:55 2014 +0200
     9.2 +++ b/src/xfer_view.cc	Tue Dec 30 06:22:54 2014 +0200
     9.3 @@ -3,14 +3,13 @@
     9.4  #include "xfer_view.h"
     9.5  #include "dicomview.h"
     9.6  
     9.7 -static Renderer *rend;
     9.8 +static TransferFunc *xfer;
     9.9  
    9.10  static int act_color = 3;
    9.11 -static CurvePoint *cpsel;
    9.12  
    9.13 -bool xfview_init(Renderer *rendarg)
    9.14 +bool xfview_init(TransferFunc *xferarg)
    9.15  {
    9.16 -	rend = rendarg;
    9.17 +	xfer = xferarg;
    9.18  	return true;
    9.19  }
    9.20  
    9.21 @@ -42,38 +41,12 @@
    9.22  	glVertex2f(-1, 1);
    9.23  	glEnd();
    9.24  
    9.25 -	glEnable(GL_POINT_SMOOTH);
    9.26  	glEnable(GL_LINE_SMOOTH);
    9.27  
    9.28  	glEnable(GL_BLEND);
    9.29  	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    9.30  
    9.31 -	// draw selection outline
    9.32 -	if(act_color < 3) {
    9.33 -		glPointSize(13.0);
    9.34 -		glLineWidth(5.0);
    9.35 -
    9.36 -		const Curve &sel_curve = rend->transfer_curve(act_color);
    9.37 -		glColor3f(0.7, 0.7, 0.7);
    9.38 -		glBegin(GL_LINE_STRIP);
    9.39 -		for(int i=0; i<nsamples; i++) {
    9.40 -			float t = (float)i / (float)(nsamples - 1);
    9.41 -			float val = sel_curve.value(t);
    9.42 -			glVertex2f(t * 2.0 - 1.0, val * 2.0 - 1.0);
    9.43 -		}
    9.44 -		glEnd();
    9.45 -		glBegin(GL_POINTS);
    9.46 -		for(int i=0; i<sel_curve.get_num_points(); i++) {
    9.47 -			const CurvePoint *p = sel_curve.get_point(i);
    9.48 -			float x = 2.0 * (float)p->t_int / 65535.0 - 1.0;
    9.49 -			glVertex2f(x, p->value * 2.0 - 1.0);
    9.50 -		}
    9.51 -		glEnd();
    9.52 -	}
    9.53 -
    9.54 -
    9.55 -	// draw curves and points
    9.56 -	glPointSize(9.0);
    9.57 +	// draw curve
    9.58  	glLineWidth(2.0);
    9.59  
    9.60  	for(int i=0; i<3; i++) {
    9.61 @@ -84,22 +57,15 @@
    9.62  			idx = i;
    9.63  		}
    9.64  
    9.65 -		const Curve &xfer = rend->transfer_curve(idx);
    9.66  		glColor3fv(line_color[idx]);
    9.67  
    9.68  		glBegin(GL_LINE_STRIP);
    9.69  		for(int j=0; j<nsamples; j++) {
    9.70  			float t = (float)j / (float)(nsamples - 1);
    9.71 -			float val = xfer.value(t);
    9.72 -			glVertex2f(t * 2.0 - 1.0, val * 2.0 - 1.0);
    9.73 -		}
    9.74 -		glEnd();
    9.75 +			float vval[4];
    9.76 +			xfer->map(t, vval);
    9.77  
    9.78 -		glBegin(GL_POINTS);
    9.79 -		for(int j=0; j<xfer.get_num_points(); j++) {
    9.80 -			const CurvePoint *p = xfer.get_point(j);
    9.81 -			float x = 2.0 * (float)p->t_int / 65535.0 - 1.0;
    9.82 -			glVertex2f(x, p->value * 2.0 - 1.0);
    9.83 +			glVertex2f(t * 2.0 - 1.0, vval[i] * 2.0 - 1.0);
    9.84  		}
    9.85  		glEnd();
    9.86  	}
    9.87 @@ -109,7 +75,7 @@
    9.88  
    9.89  void xfview_button(int bn, int press, int x, int y)
    9.90  {
    9.91 -	if(bn == 2 && press && !cpsel) {
    9.92 +	if(bn == 2 && press) {
    9.93  		act_color = (act_color + 1) % 4;
    9.94  		redisplay();
    9.95  		return;
    9.96 @@ -118,7 +84,6 @@
    9.97  	if(bn == 1) {
    9.98  		if(press) {
    9.99  		} else {
   9.100 -			cpsel = 0;
   9.101  		}
   9.102  	}
   9.103  }
    10.1 --- a/src/xfer_view.h	Mon Dec 29 15:59:55 2014 +0200
    10.2 +++ b/src/xfer_view.h	Tue Dec 30 06:22:54 2014 +0200
    10.3 @@ -1,9 +1,9 @@
    10.4  #ifndef XFER_VIEW_H_
    10.5  #define XFER_VIEW_H_
    10.6  
    10.7 -#include "renderer.h"
    10.8 +#include "xfermap.h"
    10.9  
   10.10 -bool xfview_init(Renderer *rend);
   10.11 +bool xfview_init(TransferFunc *xfer);
   10.12  void xfview_destroy();
   10.13  
   10.14  void xfview_draw();
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/src/xfermap.cc	Tue Dec 30 06:22:54 2014 +0200
    11.3 @@ -0,0 +1,77 @@
    11.4 +#include <algorithm>
    11.5 +#include "xfermap.h"
    11.6 +
    11.7 +TransferFunc::~TransferFunc()
    11.8 +{
    11.9 +}
   11.10 +
   11.11 +
   11.12 +// ---- TransferWindow ----
   11.13 +
   11.14 +TransferWindow::TransferWindow()
   11.15 +{
   11.16 +	soft_rad = 0.5;
   11.17 +	for(int i=0; i<4; i++) {
   11.18 +		low[i] = 0.5;
   11.19 +		high[i] = 2.0;
   11.20 +	}
   11.21 +}
   11.22 +
   11.23 +void TransferWindow::set_interval(float a, float b)
   11.24 +{
   11.25 +	float v0 = std::min(a, b);
   11.26 +	float v1 = std::max(a, b);
   11.27 +
   11.28 +	for(int i=0; i<4; i++) {
   11.29 +		low[i] = v0;
   11.30 +		high[i] = v1;
   11.31 +	}
   11.32 +}
   11.33 +
   11.34 +void TransferWindow::set_interval(float *rgba_low, float *rgba_high)
   11.35 +{
   11.36 +	for(int i=0; i<4; i++) {
   11.37 +		low[i] = std::min(rgba_low[i], rgba_high[i]);
   11.38 +		high[i] = std::max(rgba_low[i], rgba_high[i]);
   11.39 +	}
   11.40 +}
   11.41 +
   11.42 +void TransferWindow::set_interval_rgba(int channel, float a, float b)
   11.43 +{
   11.44 +	low[channel] = std::min(a, b);
   11.45 +	high[channel] = std::max(a, b);
   11.46 +}
   11.47 +
   11.48 +void TransferWindow::set_soft_radius(float s)
   11.49 +{
   11.50 +	soft_rad = s;
   11.51 +}
   11.52 +
   11.53 +float TransferWindow::get_soft_radius() const
   11.54 +{
   11.55 +	return soft_rad;
   11.56 +}
   11.57 +
   11.58 +static inline float smoothstep(float a, float b, float x)
   11.59 +{
   11.60 +	if(x < a) return 0.0f;
   11.61 +	if(x >= b) return 1.0f;
   11.62 +
   11.63 +	float t = (x - a) / (b - a);
   11.64 +	return t * t * (3.0f - 2.0f * t);
   11.65 +}
   11.66 +
   11.67 +float TransferWindow::map(float x) const
   11.68 +{
   11.69 +	return smoothstep(low[3] - soft_rad, high[3] - soft_rad, x) *
   11.70 +		(1.0 - smoothstep(low[3] + soft_rad, high[3] + soft_rad, x));
   11.71 +}
   11.72 +
   11.73 +void TransferWindow::map(float x, float *rgba_value) const
   11.74 +{
   11.75 +	for(int i=0; i<4; i++) {
   11.76 +		float val = smoothstep(low[i] - soft_rad, high[i] - soft_rad, x);
   11.77 +		val *= 1.0 - smoothstep(low[i] + soft_rad, high[i] + soft_rad, x);
   11.78 +		rgba_value[i] = val;
   11.79 +	}
   11.80 +}
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/src/xfermap.h	Tue Dec 30 06:22:54 2014 +0200
    12.3 @@ -0,0 +1,35 @@
    12.4 +#ifndef XFERMAP_H_
    12.5 +#define XFERMAP_H_
    12.6 +
    12.7 +class TransferFunc {
    12.8 +public:
    12.9 +	virtual ~TransferFunc();
   12.10 +
   12.11 +	virtual float map(float x) const = 0;
   12.12 +	virtual void map(float x, float *rgba_value) const = 0;
   12.13 +};
   12.14 +
   12.15 +class TransferWindow : public TransferFunc {
   12.16 +private:
   12.17 +	float soft_rad;
   12.18 +	float low[4], high[4];	// rgb
   12.19 +
   12.20 +public:
   12.21 +	TransferWindow();
   12.22 +
   12.23 +	void set_interval(float a, float b);
   12.24 +	void set_interval(float *rgba_low, float *rgba_high);
   12.25 +	void set_interval_rgba(int channel, float a, float b);
   12.26 +
   12.27 +	void get_interval(float *aptr, float *bptr) const;
   12.28 +	void get_interval_rgba(float *rgba_low, float *rgba_high) const;
   12.29 +	void get_interval_rgba(int channel, float *aptr, float *bptr) const;
   12.30 +
   12.31 +	void set_soft_radius(float s);
   12.32 +	float get_soft_radius() const;
   12.33 +
   12.34 +	float map(float x) const;
   12.35 +	void map(float x, float *rgba_value) const;
   12.36 +};
   12.37 +
   12.38 +#endif	// XFERMAP_H_