00001 #include "TransferFunktion.h"
00002 #include <glew.h>
00003 #include <openglut.h>
00004 #include <math.h>
00005
00006 TransferFunktion::TransferFunktion()
00007 {
00008 renderListBackGround=glGenLists(1);
00009 renderListData=glGenLists(1);
00010 width =500;
00011 height =300;
00012 maxDichte =4096;
00013 leftBorder=10;
00014 rightBorder=10;
00015 upBorder=10;
00016 downBorder=10;
00017 background= new Color(200,200,200,255);
00018 xPos=0;
00019 yPos=0;
00020 selectRange=10;
00021 hist=NULL;
00022
00023 TransferFunktionPunkt* punkt;
00024 punkte = new std::list<TransferFunktionPunkt*>();
00025
00026 punkt=new TransferFunktionPunkt();
00027 punkt->setColor(new Color(0,0,0,127));
00028 punkte->push_back(punkt);
00029
00030 punkt=new TransferFunktionPunkt();
00031 punkt->setColor(new Color(255,255,255,127));
00032 punkt->setDichte(maxDichte);
00033 punkte->push_back(punkt);
00034
00035 punkte->sort(TransferFunktionPunkt::compare);
00036 dataChanged=true;
00037 visDataChanged=true;
00038 visBackChanged=true;
00039
00040 }
00041 bool TransferFunktion::isInFunktionArea(int x, int y,float borderRatio)
00042 {
00043 bool xpart = x>(xPos+(borderRatio*leftBorder)) && x<(xPos+width-(borderRatio*rightBorder));
00044 bool ypart = y>(yPos+(borderRatio*upBorder)) && y<(yPos+height-(borderRatio*downBorder));
00045
00046 return xpart&&ypart;
00047 }
00048 unsigned char TransferFunktion::getAlfa(int y)
00049 {
00050 float funktionHeight = (float)(height-(upBorder+downBorder));
00051 float relativeY = (float)(y-(yPos+upBorder));
00052 return (unsigned char)(255-(relativeY/funktionHeight)*255);
00053 }
00054 int TransferFunktion::getDichte(int x)
00055 {
00056 float funktionWidth = (float)(width-(leftBorder+rightBorder));
00057 float relativeX = (float)(x-(xPos+leftBorder));
00058 return (int)((relativeX/funktionWidth)*maxDichte);
00059 }
00060 int TransferFunktion::getX(int dichte)
00061 {
00062 return (int)((((float)dichte/maxDichte)*(width-(leftBorder+rightBorder)))+(xPos+leftBorder));
00063 }
00064 int TransferFunktion::getY(unsigned char alfa)
00065 {
00066 return (int)((((float)(255-alfa)/255)*(height-(upBorder+downBorder)))+(yPos+upBorder));
00067 }
00068 void TransferFunktion::sortList()
00069 {
00070 punkte->sort(TransferFunktionPunkt::compare);
00071 }
00072 TransferFunktionPunkt* TransferFunktion::addPunkt(int x, int y)
00073 {
00074 dataChanged=true;
00075 visDataChanged=true;
00076 std::list<TransferFunktionPunkt*>::iterator it;
00077 TransferFunktionPunkt * lastPunkt;
00078 TransferFunktionPunkt * newPunkt =NULL;
00079 int dichte;
00080 unsigned char alfa;
00081 if(isInFunktionArea(x,y,1))
00082 {
00083
00084 dichte = getDichte(x);
00085 alfa = getAlfa(yPos+height/2);
00086
00087 for (it=punkte->begin(); it!=punkte->end(); ++it)
00088 {
00089 if((*it)->getDichte()>dichte)
00090 {
00091 newPunkt = new TransferFunktionPunkt(lastPunkt,(*it),dichte,alfa);
00092 punkte->insert(it,newPunkt);
00093 return newPunkt;
00094 }
00095 lastPunkt=(*it);
00096 }
00097 }
00098 return NULL;
00099 }
00100 TransferFunktionPunkt* TransferFunktion::getPunkt(int x, int y, bool firstPunkt)
00101 {
00102 std::list<TransferFunktionPunkt*>::iterator it=punkte->begin();
00103 int xPunktPos;
00104 int yPunktPos;
00105 int distance;
00106 if (!firstPunkt) it++;
00107
00108 for (; it!=punkte->end(); ++it)
00109 {
00110 yPunktPos=getY((*it)->getAlfa());
00111 xPunktPos=getX((*it)->getDichte());
00112
00113 distance=(abs(x-xPunktPos)+abs(y-yPunktPos));
00114 if(distance<=selectRange)
00115 {
00116 return(*it);
00117 }
00118 }
00119 return NULL;
00120 }
00121 TransferFunktionPunkt* TransferFunktion::updatePunkt(TransferFunktionPunkt* punkt,int x, int y)
00122 {
00123 dataChanged=true;
00124 visDataChanged=true;
00125 if(punkt==punkte->back() || punkt==punkte->front())
00126 {
00127 y=yPos+height/2;
00128 punkt->setAlfa(getAlfa(y));
00129 return punkt;
00130 }
00131
00132
00133 if (x > 60000) x -= 65535;
00134 if (y > 60000) y -= 65535;
00135
00136 if(!isInFunktionArea(x,y,-2))
00137 {
00138 punkte->remove(punkt);
00139 return NULL;
00140 }
00141
00142 x=std::min(std::max(x,xPos+leftBorder),xPos+width-rightBorder);
00143 y=yPos+height/2;
00144 punkt->setAlfa(getAlfa(y));
00145 punkt->setDichte(getDichte(x));
00146 sortList();
00147 return punkt;
00148 }
00149 bool TransferFunktion::setColor(int x,int y)
00150 {
00151 TransferFunktionPunkt* punkt = getPunkt(x,y, true);
00152 if(punkt!=NULL)
00153 {
00154 punkt->setColor();
00155 dataChanged=true;
00156 visDataChanged=true;
00157 return true;
00158 }
00159 return false;
00160 }
00161 void TransferFunktion::reshape(int width, int height)
00162 {
00163 visDataChanged=true;
00164 visBackChanged=true;
00165 this->width=width;
00166 this->height=55;
00167 }
00168 void TransferFunktion::setPosition(int xpos, int ypos)
00169 {
00170 visDataChanged=true;
00171 visBackChanged=true;
00172 this->xPos=xpos;
00173 this->yPos=ypos;
00174 }
00175 void TransferFunktion::setHist(std::vector<int>* hist)
00176 {
00177 visBackChanged=true;
00178 this->hist=hist;
00179 }
00180 float * TransferFunktion::getTransferFunktionLookUP(float* lookUp)
00181 {
00182 if(!dataChanged)
00183 {
00184 return lookUp;
00185 }
00186 dataChanged=false;
00187 delete lookUp;
00188 lookUp = new float[(maxDichte+1)*4];
00189 std::list<TransferFunktionPunkt*>::iterator it;
00190 TransferFunktionPunkt * punkt1 =punkte->front();
00191 TransferFunktionPunkt * punkt2;
00192 Color* color1;
00193 Color* color2;
00194 float deltaR;
00195 float deltaG;
00196 float deltaB;
00197 float deltaA;
00198 float red;
00199 float green;
00200 float blue;
00201 float alfa;
00202 int deltaD;
00203 int dichte=0;
00204 for (it=++(punkte->begin()); it!=punkte->end(); ++it)
00205 {
00206 punkt2 =(*it);
00207
00208 deltaD =(punkt2->getDichte()-punkt1->getDichte());
00209 dichte=punkt1->getDichte();
00210 if(deltaD>0)
00211 {
00212 color1=punkt1->getColor();
00213 color2=punkt2->getColor();
00214 deltaR = (color2->GetNormalizedRed()-color1->GetNormalizedRed())/deltaD;
00215 deltaG = (color2->GetNormalizedGreen()-color1->GetNormalizedGreen())/deltaD;
00216 deltaB = (color2->GetNormalizedBlue()-color1->GetNormalizedBlue())/deltaD;
00217 deltaA = (color2->GetNormalizedAlpha()-color1->GetNormalizedAlpha())/deltaD;
00218
00219 red = (float)color1->GetNormalizedRed();
00220 green= (float)color1->GetNormalizedGreen();
00221 blue= (float)color1->GetNormalizedBlue();
00222 alfa= (float)color1->GetNormalizedAlpha();
00223
00224 for(int i=0; i<deltaD;i++)
00225 {
00226 lookUp[(i+dichte)*4]=(red+(deltaR*i));
00227 lookUp[(i+dichte)*4+1]=(green+(deltaG*i));
00228 lookUp[(i+dichte)*4+2]=(blue+(deltaB*i));
00229 lookUp[(i+dichte)*4+3]=(alfa+(deltaA*i));
00230 }
00231 }
00232 punkt1=punkt2;
00233 }
00234 return lookUp;
00235 }
00236 int TransferFunktion::genderateRenderListBack()
00237 {
00238
00239 if(!visBackChanged)
00240 {
00241 return renderListBackGround;
00242 }
00243 visBackChanged =false;
00244 std::vector<int>::iterator histIt;
00245
00246 TransferFunktionPunkt * punkt1 =punkte->front();
00247 int x;
00248 int y;
00249 int i=0;
00250 int lastX=0;
00251 int sumHist=0;
00252 int max=0;
00253 int activeWidth=width-(leftBorder+rightBorder);
00254 float histBucketWidth=(float)maxDichte/activeWidth;
00255 int actualHistBucket=0;
00256
00257 glNewList (renderListBackGround, GL_COMPILE);
00258
00260
00262
00263
00264
00265
00266
00267
00269
00270
00271
00272
00274
00275
00276
00277
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334 glColor4f(0.0,0.0,0.0,1.0);
00335 glBegin (GL_POLYGON);
00336 glVertex2i (xPos+leftBorder-1,yPos+upBorder-1);
00337
00338
00339 glVertex2i (xPos+leftBorder-1,yPos+height-downBorder+1);
00340
00341
00342 glVertex2i (xPos+width-rightBorder+1,yPos+height-downBorder+1);
00343
00344
00345 glVertex2i (xPos+width-rightBorder+1,yPos+upBorder-1);
00346
00347 glEnd();
00348
00349 glEndList();
00350
00351 return renderListBackGround;
00352 }
00353 int TransferFunktion::genderateRenderListFront()
00354 {
00355 if(!visDataChanged)
00356 {
00357 return renderListData;
00358 }
00359 visDataChanged =false;
00360 std::list<TransferFunktionPunkt*>::iterator it;
00361
00362 TransferFunktionPunkt * punkt1 =punkte->front();
00363 TransferFunktionPunkt * punkt2;
00364 Color* color1;
00365 Color* color2;
00366 int x;
00367 int y;
00368 int oldX;
00369 int oldY;
00370
00371 glNewList (renderListData, GL_COMPILE);
00372
00373 glBegin (GL_LINES);
00374
00375 punkt1 =punkte->front();
00376 oldX= getX((punkt1)->getDichte());
00377 oldY= getY((punkt1)->getAlfa());
00378 glColor4f(0.0,0.0,0.0,1.0);
00379
00380 for (it=++punkte->begin(); it!=punkte->end(); ++it)
00381 {
00382
00383 x= getX((*it)->getDichte());
00384 y= getY((*it)->getAlfa());
00385
00386 glVertex2i (x,y);
00387 glVertex2i (oldX,oldY);
00388
00389 oldX=x;
00390 oldY=y;
00391
00392 }
00393
00394 glEnd();
00395
00396 glBegin (GL_QUADS);
00397
00398
00399 for (it=++(punkte->begin()); it!=punkte->end(); ++it)
00400 {
00401 punkt2 =(*it);
00402 color1=punkt1->getColor();
00403 color2=punkt2->getColor();
00404 glColor4f(color1->GetNormalizedRed(),color1->GetNormalizedGreen(),color1->GetNormalizedBlue(),1.0);
00405
00406 glVertex2i(getX(punkt1->getDichte()),getY(0));
00407 glVertex2i(getX(punkt1->getDichte()),getY(255));
00408 glColor4f(color2->GetNormalizedRed(),color2->GetNormalizedGreen(),color2->GetNormalizedBlue(),1.0);
00409 glVertex2i(getX(punkt2->getDichte()),getY(255));
00410
00411 glVertex2i(getX(punkt2->getDichte()),getY(0));
00412
00413 punkt1=punkt2;
00414 }
00415
00416 glEnd();
00417 it=(punkte->end());
00418 do
00419 {
00420 glBegin(GL_QUADS);
00421 it--;
00422 color1=(*it)->getColor();
00423 glColor4f((float)color1->GetNormalizedRed(),(float)color1->GetNormalizedGreen(),(float)color1->GetNormalizedBlue(),0.7f);
00424 x= getX((*it)->getDichte());
00425 y= getY((*it)->getAlfa());
00426 glVertex2i (x-selectRange,y);
00427 glVertex2i (x,y+selectRange);
00428 glVertex2i (x+selectRange,y);
00429 glVertex2i (x,y-selectRange);
00430
00431 glEnd();
00432 glBegin (GL_LINES);
00433
00434 glColor4f(1.0-(*it)->getColor()->GetNormalizedRed(),1.0-(*it)->getColor()->GetNormalizedGreen(),1.0-(*it)->getColor()->GetNormalizedBlue(),1.0);
00435
00436 glVertex2i (x-selectRange,y);
00437 glVertex2i (x,y+selectRange);
00438
00439 glVertex2i (x,y+selectRange);
00440 glVertex2i (x+selectRange,y);
00441
00442 glVertex2i (x+selectRange,y);
00443 glVertex2i (x,y-selectRange);
00444
00445 glVertex2i (x,y-selectRange);
00446 glVertex2i (x-selectRange,y);
00447
00448 glEnd();
00449
00450
00451 }while(it!=(punkte->begin()));
00452
00453
00454
00455 glEndList();
00456
00457 return renderListData;
00458 }
00459 void TransferFunktion::loadPunkte(const std::string & strFilename)
00460 {
00461 std::cout << "- Loading file '" << strFilename << "' ... " << std::endl;
00462 FILE *fp = NULL;
00463
00464 fopen_s(&fp,strFilename.c_str(),"rb");
00465
00466 if (!fp)
00467 {
00468 std::cerr << "+ Error loading file." << std::endl << std::endl;
00469 }
00470 else
00471 {
00472
00473 unsigned short size;
00474 unsigned char alfa;
00475 unsigned char red;
00476 unsigned char green;
00477 unsigned char blue;
00478 int dichte;
00479 TransferFunktionPunkt *punkt;
00480
00481 fread(&size,sizeof(unsigned short),1,fp);
00482
00483 punkte->clear();
00484 for( int i=0; i<size; i++)
00485 {
00486 fread(&alfa,sizeof(unsigned char),1,fp);
00487 fread(&red,sizeof(unsigned char),1,fp);
00488 fread(&green,sizeof(unsigned char),1,fp);
00489 fread(&blue,sizeof(unsigned char),1,fp);
00490 fread(&dichte,sizeof(int),1,fp);
00491 punkt=new TransferFunktionPunkt();
00492 punkt->setColor(new Color(red,green,blue,alfa));
00493 punkt->setDichte(dichte);
00494 punkte->push_back(punkt);
00495 }
00496 fclose(fp);
00497 punkte->sort(TransferFunktionPunkt::compare);
00498
00499 std::cout << "File '" << strFilename << "' loaded!" << std::endl;
00500 }
00501
00502 this->visDataChanged=true;
00503 this->dataChanged=true;
00504 }
00505 void TransferFunktion::savePunkte(const std::string & strFilename)
00506 {
00507 std::cout << "- Saving file '" << strFilename << "' ... " << std::endl;
00508 FILE *fp = NULL;
00509
00510 fopen_s(&fp,strFilename.c_str(),"wb");
00511
00512 if (!fp)
00513 {
00514 std::cerr << "+ Error saving file." << std::endl << std::endl;
00515 }
00516 else
00517 {
00518
00519 std::list<TransferFunktionPunkt*>::iterator it;
00520 unsigned short size = punkte->size();
00521 unsigned char alfa;
00522 unsigned char red;
00523 unsigned char green;
00524 unsigned char blue;
00525 int dichte;
00526 Color *color;
00527
00528 fwrite(&size,sizeof(unsigned short),1,fp);
00529
00530 for (it=(punkte->begin()); it!=punkte->end(); ++it)
00531 {
00532 color=(*it)->getColor();
00533 red = color->GetRed();
00534 green = color->GetGreen();
00535 blue = color->GetBlue();
00536 alfa = color->GetAlpha();
00537 dichte=(*it)->getDichte();
00538 fwrite(&alfa,sizeof(unsigned char),1,fp);
00539 fwrite(&red,sizeof(unsigned char),1,fp);
00540 fwrite(&green,sizeof(unsigned char),1,fp);
00541 fwrite(&blue,sizeof(unsigned char),1,fp);
00542 fwrite(&dichte,sizeof(int),1,fp);
00543 }
00544
00545 fclose(fp);
00546
00547 std::cout << "File '" << strFilename << "' saved!" << std::endl;
00548 }
00549 }