# HG changeset patch # User John Tsiombikas # Date 1419913374 -7200 # Node ID f22be47a35723c1ca98db8e5987c4fb7dcd9e8ad # Parent 5417c25cb23887001473f4b67fdf2f53cb9cf9a2 moved to TransferFuncs completely diff -r 5417c25cb238 -r f22be47a3572 src/dicomview.cc --- a/src/dicomview.cc Mon Dec 29 15:59:55 2014 +0200 +++ b/src/dicomview.cc Tue Dec 30 06:22:54 2014 +0200 @@ -15,6 +15,7 @@ static Renderer *rend; static Volume *vol; +static TransferFunc *xfer; extern "C" { @@ -46,7 +47,10 @@ vol = voxvol; rend->set_volume(vol); - if(!xfview_init(rend)) { + xfer = new TransferWindow; + rend->set_transfer_function(xfer); + + if(!xfview_init(xfer)) { return -1; } @@ -60,6 +64,7 @@ rend->destroy(); delete rend; delete vol; + delete xfer; } void ev_display() diff -r 5417c25cb238 -r f22be47a3572 src/main.cc --- a/src/main.cc Mon Dec 29 15:59:55 2014 +0200 +++ b/src/main.cc Tue Dec 30 06:22:54 2014 +0200 @@ -30,7 +30,7 @@ return 1; } - glutInitWindowSize(1280, 800); + glutInitWindowSize(opt.xsz, opt.ysz); glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); glutCreateWindow("dicom viewer"); diff -r 5417c25cb238 -r f22be47a3572 src/opt.cc --- a/src/opt.cc Mon Dec 29 15:59:55 2014 +0200 +++ b/src/opt.cc Tue Dec 30 06:22:54 2014 +0200 @@ -16,6 +16,8 @@ { opt.fname = 0; opt.rend_type = REND_FAST; + opt.xsz = 800; + opt.ysz = 800; } static RendererType renderer_type(const char *name) @@ -36,6 +38,13 @@ if(argv[i][0] == '-') { if(argv[i][2] == 0) { switch(argv[i][1]) { + case 's': + if(sscanf(argv[++i], "%dx%d", &opt.xsz, &opt.ysz) != 2) { + fprintf(stderr, "-s must be followed by the window size (WxH)\n"); + return -1; + } + break; + case 'r': if((opt.rend_type = renderer_type(argv[++i])) == REND_NONE) { if(strcmp(argv[i], "help") == 0) { diff -r 5417c25cb238 -r f22be47a3572 src/opt.h --- a/src/opt.h Mon Dec 29 15:59:55 2014 +0200 +++ b/src/opt.h Tue Dec 30 06:22:54 2014 +0200 @@ -9,6 +9,7 @@ struct Options { char *fname; RendererType rend_type; + int xsz, ysz; }; extern Options opt; diff -r 5417c25cb238 -r f22be47a3572 src/rend_fast.cc --- a/src/rend_fast.cc Mon Dec 29 15:59:55 2014 +0200 +++ b/src/rend_fast.cc Tue Dec 30 06:22:54 2014 +0200 @@ -34,7 +34,7 @@ glBindTexture(GL_TEXTURE_1D, xfer_tex); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage1D(GL_TEXTURE_1D, 0, have_tex_float ? GL_RGB16F : GL_RGB, XFER_MAP_SZ, 0, GL_RGB, GL_FLOAT, 0); + glTexImage1D(GL_TEXTURE_1D, 0, have_tex_float ? GL_RGBA16F : GL_RGBA, XFER_MAP_SZ, 0, GL_RGB, GL_FLOAT, 0); return true; } @@ -51,18 +51,6 @@ Renderer::set_volume(vol); } -Curve &RendererFast::transfer_curve(int color) -{ - xfer_tex_valid = false; - return Renderer::transfer_curve(color); -} - -void RendererFast::set_simple_transfer(float low, float high) -{ - xfer_tex_valid = false; - Renderer::set_simple_transfer(low, high); -} - void RendererFast::update(unsigned int msec) { if(!vol) return; @@ -120,28 +108,23 @@ vol_tex_valid = true; } - if(!xfer_tex_valid) { - float pixels[XFER_MAP_SZ * 3]; + if(1) {//if(!xfer_tex_valid) { + float pixels[XFER_MAP_SZ * 4]; float *pptr = pixels; for(int i=0; imap(x, pptr); + } else { + pptr[0] = pptr[1] = pptr[2] = pptr[3] = x; + } + pptr += 4; } glBindTexture(GL_TEXTURE_1D, xfer_tex); - glTexSubImage1D(GL_TEXTURE_1D, 0, 0, XFER_MAP_SZ, GL_RGB, GL_FLOAT, pixels); + glTexSubImage1D(GL_TEXTURE_1D, 0, 0, XFER_MAP_SZ, GL_RGBA, GL_FLOAT, pixels); xfer_tex_valid = true; } diff -r 5417c25cb238 -r f22be47a3572 src/rend_fast.h --- a/src/rend_fast.h Mon Dec 29 15:59:55 2014 +0200 +++ b/src/rend_fast.h Tue Dec 30 06:22:54 2014 +0200 @@ -15,8 +15,6 @@ void destroy(); void set_volume(Volume *vol); - Curve &transfer_curve(int color); - void set_simple_transfer(float low, float high); void update(unsigned int msec); void render() const; diff -r 5417c25cb238 -r f22be47a3572 src/renderer.cc --- a/src/renderer.cc Mon Dec 29 15:59:55 2014 +0200 +++ b/src/renderer.cc Tue Dec 30 06:22:54 2014 +0200 @@ -7,14 +7,6 @@ view_width = 512; view_height = 512; - for(int i=0; i<3; i++) { - xfer[i].set_point(0, 0); - xfer[i].set_point(1, 1); - } - - xfer_low = 0.0; - xfer_high = 1.0; - for(int i=0; ixfer = xfer; } -const Curve &Renderer::transfer_curve(int color) const +TransferFunc *Renderer::get_transfer_function() const { - return xfer[color]; -} - -void Renderer::set_simple_transfer(float low, float high) -{ - xfer_low = std::min(low, high); - xfer_high = std::max(low, high); -} - -void Renderer::get_simple_transfer(float *low, float *high) const -{ - *low = xfer_low; - *high = xfer_high; + return xfer; } void Renderer::set_clipping_plane(int idx, float nx, float ny, float nz, float dist) diff -r 5417c25cb238 -r f22be47a3572 src/renderer.h --- a/src/renderer.h Mon Dec 29 15:59:55 2014 +0200 +++ b/src/renderer.h Tue Dec 30 06:22:54 2014 +0200 @@ -2,7 +2,7 @@ #define RENDERER_H_ #include "volume.h" -#include "curve.h" +#include "xfermap.h" #define MAX_CLIP_PLANES 4 @@ -13,8 +13,7 @@ float clip_plane[MAX_CLIP_PLANES][4]; // nx,ny,nz,dist - Curve xfer[3]; // rgb transfer function - float xfer_low, xfer_high; // simple transfer function bounds + TransferFunc *xfer; public: Renderer(); @@ -26,11 +25,8 @@ virtual void set_volume(Volume *vol); virtual Volume *get_volume() const; - virtual Curve &transfer_curve(int color); - virtual const Curve &transfer_curve(int color) const; - - virtual void set_simple_transfer(float low, float high); - virtual void get_simple_transfer(float *low, float *high) const; + virtual void set_transfer_function(TransferFunc *xfer); + virtual TransferFunc *get_transfer_function() const; virtual void set_clipping_plane(int idx, float nx, float ny, float nz, float dist); virtual void disable_clipping_plane(int idx); diff -r 5417c25cb238 -r f22be47a3572 src/xfer_view.cc --- a/src/xfer_view.cc Mon Dec 29 15:59:55 2014 +0200 +++ b/src/xfer_view.cc Tue Dec 30 06:22:54 2014 +0200 @@ -3,14 +3,13 @@ #include "xfer_view.h" #include "dicomview.h" -static Renderer *rend; +static TransferFunc *xfer; static int act_color = 3; -static CurvePoint *cpsel; -bool xfview_init(Renderer *rendarg) +bool xfview_init(TransferFunc *xferarg) { - rend = rendarg; + xfer = xferarg; return true; } @@ -42,38 +41,12 @@ glVertex2f(-1, 1); glEnd(); - glEnable(GL_POINT_SMOOTH); glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - // draw selection outline - if(act_color < 3) { - glPointSize(13.0); - glLineWidth(5.0); - - const Curve &sel_curve = rend->transfer_curve(act_color); - glColor3f(0.7, 0.7, 0.7); - glBegin(GL_LINE_STRIP); - for(int i=0; it_int / 65535.0 - 1.0; - glVertex2f(x, p->value * 2.0 - 1.0); - } - glEnd(); - } - - - // draw curves and points - glPointSize(9.0); + // draw curve glLineWidth(2.0); for(int i=0; i<3; i++) { @@ -84,22 +57,15 @@ idx = i; } - const Curve &xfer = rend->transfer_curve(idx); glColor3fv(line_color[idx]); glBegin(GL_LINE_STRIP); for(int j=0; jmap(t, vval); - glBegin(GL_POINTS); - for(int j=0; jt_int / 65535.0 - 1.0; - glVertex2f(x, p->value * 2.0 - 1.0); + glVertex2f(t * 2.0 - 1.0, vval[i] * 2.0 - 1.0); } glEnd(); } @@ -109,7 +75,7 @@ void xfview_button(int bn, int press, int x, int y) { - if(bn == 2 && press && !cpsel) { + if(bn == 2 && press) { act_color = (act_color + 1) % 4; redisplay(); return; @@ -118,7 +84,6 @@ if(bn == 1) { if(press) { } else { - cpsel = 0; } } } diff -r 5417c25cb238 -r f22be47a3572 src/xfer_view.h --- a/src/xfer_view.h Mon Dec 29 15:59:55 2014 +0200 +++ b/src/xfer_view.h Tue Dec 30 06:22:54 2014 +0200 @@ -1,9 +1,9 @@ #ifndef XFER_VIEW_H_ #define XFER_VIEW_H_ -#include "renderer.h" +#include "xfermap.h" -bool xfview_init(Renderer *rend); +bool xfview_init(TransferFunc *xfer); void xfview_destroy(); void xfview_draw(); diff -r 5417c25cb238 -r f22be47a3572 src/xfermap.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/xfermap.cc Tue Dec 30 06:22:54 2014 +0200 @@ -0,0 +1,77 @@ +#include +#include "xfermap.h" + +TransferFunc::~TransferFunc() +{ +} + + +// ---- TransferWindow ---- + +TransferWindow::TransferWindow() +{ + soft_rad = 0.5; + for(int i=0; i<4; i++) { + low[i] = 0.5; + high[i] = 2.0; + } +} + +void TransferWindow::set_interval(float a, float b) +{ + float v0 = std::min(a, b); + float v1 = std::max(a, b); + + for(int i=0; i<4; i++) { + low[i] = v0; + high[i] = v1; + } +} + +void TransferWindow::set_interval(float *rgba_low, float *rgba_high) +{ + for(int i=0; i<4; i++) { + low[i] = std::min(rgba_low[i], rgba_high[i]); + high[i] = std::max(rgba_low[i], rgba_high[i]); + } +} + +void TransferWindow::set_interval_rgba(int channel, float a, float b) +{ + low[channel] = std::min(a, b); + high[channel] = std::max(a, b); +} + +void TransferWindow::set_soft_radius(float s) +{ + soft_rad = s; +} + +float TransferWindow::get_soft_radius() const +{ + return soft_rad; +} + +static inline float smoothstep(float a, float b, float x) +{ + if(x < a) return 0.0f; + if(x >= b) return 1.0f; + + float t = (x - a) / (b - a); + return t * t * (3.0f - 2.0f * t); +} + +float TransferWindow::map(float x) const +{ + return smoothstep(low[3] - soft_rad, high[3] - soft_rad, x) * + (1.0 - smoothstep(low[3] + soft_rad, high[3] + soft_rad, x)); +} + +void TransferWindow::map(float x, float *rgba_value) const +{ + for(int i=0; i<4; i++) { + float val = smoothstep(low[i] - soft_rad, high[i] - soft_rad, x); + val *= 1.0 - smoothstep(low[i] + soft_rad, high[i] + soft_rad, x); + rgba_value[i] = val; + } +} diff -r 5417c25cb238 -r f22be47a3572 src/xfermap.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/xfermap.h Tue Dec 30 06:22:54 2014 +0200 @@ -0,0 +1,35 @@ +#ifndef XFERMAP_H_ +#define XFERMAP_H_ + +class TransferFunc { +public: + virtual ~TransferFunc(); + + virtual float map(float x) const = 0; + virtual void map(float x, float *rgba_value) const = 0; +}; + +class TransferWindow : public TransferFunc { +private: + float soft_rad; + float low[4], high[4]; // rgb + +public: + TransferWindow(); + + void set_interval(float a, float b); + void set_interval(float *rgba_low, float *rgba_high); + void set_interval_rgba(int channel, float a, float b); + + void get_interval(float *aptr, float *bptr) const; + void get_interval_rgba(float *rgba_low, float *rgba_high) const; + void get_interval_rgba(int channel, float *aptr, float *bptr) const; + + void set_soft_radius(float s); + float get_soft_radius() const; + + float map(float x) const; + void map(float x, float *rgba_value) const; +}; + +#endif // XFERMAP_H_