Eigene Dateien/uni/visualisierung/vislu/bsp1/VisLu/VTransferFunction.cpp

Go to the documentation of this file.
00001 #include "VTransferFunction.h"
00002 #include "VTransferFunctionNode.h"
00003 #include "V2Ddraw.h"
00004 #include <vector>
00005 #include <algorithm>
00006 #include <iostream>
00007 #include "vmath.h"
00008 #include <math.h>
00009 
00010 using namespace std;
00011 
00012 VTransferFunction::VTransferFunction(int x, int y,int width, int height,float* alpha)
00013 {
00014         this->x = x;
00015         this->y = y;
00016         this->width = width;
00017         this->height = height;
00018         this->alpha = alpha;
00019         this->dragging = false;
00020         this->chooser = new VColorChooser(alpha,x,y,width,height);
00021         this->currentnode = 0;
00022         this->tex = 0;
00023         VTransferFunctionNode * begin = new VTransferFunctionNode(this->x,this->y+this->height);
00024         float * color = begin->getColor();
00025         color[0] = color[1] = color[2] = 0.0f;
00026         begin->setChoosed(false);
00027         this->nodes.push_back(begin);
00028         VTransferFunctionNode * end = new VTransferFunctionNode(this->x+this->width,this->y);
00029         color = end->getColor();
00030         color[0] = color[1] = color[2] = 1.0f;
00031         end->setChoosed(false);
00032         this->nodes.push_back(end);
00033         this->length = 4096;
00034         colors = new float[4*length];
00035 }
00036 
00037 void VTransferFunction::draw() {
00038         //draw surrounding box
00039         V2Ddraw::drawRect(this->x,this->y,this->width,this->height);
00040         //draw nodes
00041         stdx::sort(nodes.begin(),nodes.end());
00042         int startx = this->x;
00043         int starty = this->y+this->height;
00044         for(ptr_vector<VTransferFunctionNode>::iterator it=nodes.begin(); it!=nodes.end(); it++) {
00045                 glBegin(GL_LINES);
00046                         glVertex2f(startx,starty);
00047                         glVertex2f((*it).getx(),(*it).gety());
00048                 glEnd();
00049                 startx = (*it).getx();
00050                 starty = (*it).gety();
00051                 (*it).draw();
00052         }
00053         /*glBegin(GL_LINES);
00054                 glVertex2f(startx,starty);
00055                 glVertex2f(this->x+this->width,this->y);
00056         glEnd();*/
00057         //draw colorbox
00058         float * c = this->nodes.front().getColor();
00059         //cout << c[0] << " " << c[1] << " " << c[2] << endl;
00060         float previous_color[3];
00061         previous_color[0] = c[0];
00062         previous_color[1] = c[1];
00063         previous_color[2] = c[2];
00064         startx = this->x;
00065         int y1 = this->y+this->height+5;
00066         int y2 = this->y+this->height+25;
00067         for(ptr_vector<VTransferFunctionNode>::iterator it=nodes.begin(); it!=nodes.end(); it++) {
00068                 if(it!=nodes.begin()) {
00069                         float * current_color = (*it).getColor();
00070                         int xn = (*it).getx();
00071                         glBegin(GL_QUADS);
00072                                 glColor4f(previous_color[0],previous_color[1],previous_color[2],*(this->alpha));
00073                                 glVertex2f(startx,y1);
00074                                 glColor4f(current_color[0],current_color[1],current_color[2],*(this->alpha));
00075                                 glVertex2f(xn,y1);
00076                                 glColor4f(current_color[0],current_color[1],current_color[2],*(this->alpha));
00077                                 glVertex2f(xn,y2);
00078                                 glColor4f(previous_color[0],previous_color[1],previous_color[2],*(this->alpha));
00079                                 glVertex2f(startx,y2);
00080                         glEnd();
00081                         startx = xn;
00082                         previous_color[0] = current_color[0];
00083                         previous_color[1] = current_color[1];
00084                         previous_color[2] = current_color[2];
00085                 }
00086         }
00087         
00088         if(this->chooser->isActive()) {
00089                 this->chooser->draw();
00090         }
00091 }
00092 
00093 void VTransferFunction::pressed(int x, int y) {
00094         //select node
00095         for(ptr_vector<VTransferFunctionNode>::iterator it=nodes.begin(); it!=nodes.end(); it++) {
00096                 if((*it).isInside(x,y)) {
00097                         this->currentnode = &(*it);
00098                 }
00099         }
00100 }
00101 
00102 void VTransferFunction::released(int x,int y) {
00103         if(!this->currentnode && !this->dragging && !this->chooser->isActive()) {//new node (klick irgendwohin)
00104                 this->chooser->setActive(true,x,y);
00105                 this->nodes.push_back(new VTransferFunctionNode(x,y));
00106         }
00107         else if(this->currentnode && !this->dragging && !this->chooser->isActive()) { //klick auf knoten
00108                 this->chooser->setActive(true,x,y);
00109                 currentnode->setChoosed(true);
00110         }
00111         else if(!this->currentnode && !this->dragging && this->chooser->isActive()) { //klick auf colorchooser
00112                 if(this->chooser->isInside(x,y)) {
00113                         for(ptr_vector<VTransferFunctionNode>::iterator it=nodes.begin(); it!=nodes.end(); it++) {
00114                                 if((*it).isChoosed()) {
00115                                         float * color = new float[3];
00116                                         this->chooser->getColor(x,y,color);
00117                                         float * color_node = (*it).getColor();
00118                                         color_node[0] = color[0];
00119                                         color_node[1] = color[1];
00120                                         color_node[2] = color[2];
00121                                         //cout << color[0] << " " << color[1] << " " << color[2] << endl;
00122                                         delete color;
00123                                         this->chooser->setActive(false,0,0);
00124                                         (*it).setChoosed(false);
00125                                 }
00126                         }
00127                 }
00128                 this->renderTexture();
00129         } else if(this->dragging) {
00130                 this->renderTexture();
00131         }
00132         
00133         this->currentnode = 0;
00134         this->dragging = false;
00135 }
00136 
00137 void VTransferFunction::drag(int x, int y) {
00138         this->dragging = true;
00139         stdx::sort(nodes.begin(),nodes.end());
00140         bool endknoten = (this->currentnode == &this->nodes.front()) || (this->currentnode == &this->nodes.back());
00141         if(currentnode && !endknoten) {
00142                 currentnode->setx(x);
00143                 currentnode->sety(y);
00144         } else if(currentnode && endknoten) {
00145                 currentnode->sety(y);
00146         }
00147         this->renderTexture();
00148 }
00149 
00150 bool VTransferFunction::isInside(int xm, int ym) {
00151         return xm > this->x && xm < this->x + this->width && ym > this->y && ym < this->y + this->height;
00152 }
00153 
00154 GLuint * VTransferFunction::getTexture() {
00155         return &this->tex;
00156 }
00157 
00158 void VTransferFunction::renderTexture() {
00159         stdx::sort(this->nodes.begin(),this->nodes.end());
00160 
00161         float * c = this->nodes.front().getColor();
00162         Vector4<float> color(c[0],c[1],c[2],this->nodes.front().getOpacity(this->height));
00163         int anfang = 0;
00164         int posx = this->x;
00165         for(ptr_vector<VTransferFunctionNode>::iterator it=nodes.begin(); it!=nodes.end(); it++) {
00166                 if(it!=nodes.begin()) {
00167                         float * c = (*it).getColor();
00168                         float op = (*it).getOpacity(this->height);
00169                         Vector4<float> color2(c[0],c[1],c[2],op);
00170                         double intervall_norm = (double)((*it).getx() - posx)/(double)this->width;
00171                         int intervall = (int)floor((float)(intervall_norm*(float)length)+0.5);
00172                         float f = 0.0f;
00173                         for(int i = anfang; i < anfang+intervall; i++) {
00174                                 Vector4<float> interpol = color.lerp(f,color2); //linear interpolation
00175                                 colors[4*i+0] = interpol[0];
00176                                 colors[4*i+1] = interpol[1];
00177                                 colors[4*i+2] = interpol[2];
00178                                 colors[4*i+3] = interpol[3];
00179                                 f += 1.0f/(float)intervall;
00180                                 //cout << i << endl;
00181                         }
00182                         anfang += intervall;
00183                         posx = (*it).getx();
00184                         color = color2;
00185                 }
00186         }
00187         c = this->nodes.back().getColor();
00188         Vector4<float> ende(c[0],c[1],c[2],this->nodes.back().getOpacity(this->height));
00189         for(int i = anfang; i< length; i++) {
00190                 colors[4*i+0] = ende[0];
00191                 colors[4*i+1] = ende[1];
00192                 colors[4*i+2] = ende[2];
00193                 colors[4*i+3] = ende[3];
00194                 //cout << i << endl;
00195         }
00196         //for(int i=0; i<length; i++)
00197         //      cout << colors[4*i+0] << " " << colors[4*i+1] << " " << colors[4*i+2] << " " << colors[4*i+3] << endl;
00198         if(glIsTexture(this->tex)) {
00199                 glDeleteTextures(1,&this->tex);
00200         }
00201         glGenTextures(1,&this->tex);
00202         glBindTexture(GL_TEXTURE_1D, this->tex);
00203         glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, 4*length, 0, GL_RGBA, GL_FLOAT, colors);
00204 }
00205 
00206 VTransferFunction::~VTransferFunction(void)
00207 {
00208         delete this->chooser;
00209         delete[] this->colors;
00210 }

Generated on Wed Dec 6 11:08:00 2006 for VisLU by  doxygen 1.5.1-p1