00001 #include "VolumeBuffer.h"
00002 #include <QtGui>
00003 #include <QtOpenGL>
00004
00005 #include <math.h>
00006
00007 #include "vrglwidget.h"
00008 #include <GL/gl.h>
00009 #include <GL/glu.h>
00010 #include <GL/glut.h>
00011
00012 #include <iostream>
00013 #include <fstream>
00014 using namespace std;
00015
00016 #include "itkImage.h"
00017 #include "itkImageFileReader.h"
00018
00019 #include <f3d.h>
00020
00021 CGcontext cgContext;
00022
00023 void cgErrorCallback()
00024 {
00025 CGerror lastError = cgGetError();
00026 if(lastError)
00027 {
00028 printf("%s\n", cgGetErrorString(lastError));
00029 printf("%s\n", cgGetLastListing(cgContext));
00030 exit(1);
00031 }
00032 }
00033
00034 vrGLWidget::vrGLWidget(QWidget *parent)
00035 : QGLWidget(parent)
00036 {
00037 object = 0;
00038 xRot = 0;
00039 yRot = 0;
00040 zRot = 0;
00041
00042 trolltechGreen = QColor::fromCmykF(0.40, 0.0, 1.0, 0.0);
00043 trolltechPurple = QColor::fromCmykF(0.39, 0.39, 0.0, 0.0);
00044
00045 setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
00046
00047 m_tf_texture = new unsigned char [256*256*4];
00048
00049 m_f3d2f3d_thld = new QProcess(this);
00050 m_f3dthreshold = new QProcess(this);
00051
00052
00053 m_temporary_files.clear();
00054
00055 connect(m_f3d2f3d_thld,SIGNAL(finished(int, QProcess::ExitStatus)),this,SLOT(computeThreshold()));
00056 connect(m_f3d2f3d_thld,SIGNAL(finished(int, QProcess::ExitStatus)),this,SIGNAL(scaleSpaceComputationProgress()));
00057
00058 connect(m_f3dthreshold,SIGNAL(finished(int, QProcess::ExitStatus)),this,SLOT(computeScaleSpaceVesselness()));
00059 connect(m_f3dthreshold,SIGNAL(finished(int, QProcess::ExitStatus)),this,SIGNAL(scaleSpaceComputationProgress()));
00060
00061 m_f3dmerge_upscale = new QProcess(this);
00062 connect(m_f3dmerge_upscale,SIGNAL(finished(int, QProcess::ExitStatus)),this,SLOT(mergeAndUpScale()));
00063 connect(m_f3dmerge_upscale,SIGNAL(finished(int, QProcess::ExitStatus)),this,SLOT(mergeFiles()));
00064
00065 m_f3dmerge = new QProcess(this);
00066 connect(m_f3dmerge,SIGNAL(finished(int, QProcess::ExitStatus)),this,SLOT(mergeFiles()));
00067
00068 m_f3d2f3d_char = new QProcess(this);
00069 connect(m_f3d2f3d_char,SIGNAL(finished(int, QProcess::ExitStatus)),this,SIGNAL(scaleSpaceComputationProgress()));
00070
00071 m_del_process = new QProcess(this);
00072 connect(m_f3d2f3d_char,SIGNAL(finished(int, QProcess::ExitStatus)),this,SLOT(destroyTemporaryFiles()));
00073
00074
00075
00076
00077
00078
00079
00080
00081 m_f3d2f3d_process_list.clear();
00082 m_f3dgauss_process_list.clear();
00083 m_f3dhess_process_list.clear();
00084
00085 m_scale_filenames.clear();
00086
00087 for (int i = 0; i < PROCESS_FIELD_SIZE; i++)
00088 {
00089 QProcess *f3d2f3d_process = new QProcess(this);
00090 m_f3d2f3d_process_list.append(f3d2f3d_process);
00091 connect(f3d2f3d_process,SIGNAL(finished(int, QProcess::ExitStatus)),this,SIGNAL(scaleSpaceComputationProgress()));
00092
00093 QProcess *f3dgauss_process = new QProcess(this);
00094 m_f3dgauss_process_list.append(f3dgauss_process);
00095 connect(f3dgauss_process,SIGNAL(finished(int, QProcess::ExitStatus)),this,SIGNAL(scaleSpaceComputationProgress()));
00096
00097 QProcess *f3dhess_process = new QProcess(this);
00098 m_f3dhess_process_list.append(f3dhess_process);
00099 connect(f3dhess_process,SIGNAL(finished(int, QProcess::ExitStatus)),this,SIGNAL(scaleSpaceComputationProgress()));
00100 connect(f3dhess_process,SIGNAL(finished(int, QProcess::ExitStatus)),this,SLOT(ScaleDone()));
00101 }
00102
00103 m_scales_computed = 0;
00104
00105 m_scale_last_offset = 220;
00106 m_scale_step = 20;
00107
00108 m_files_upscaled = 0;
00109
00110 }
00111
00112 vrGLWidget::~vrGLWidget()
00113 {
00114 makeCurrent();
00115 glDeleteLists(object, 1);
00116
00117
00118 delete [] m_tf_texture;
00119 }
00120
00121 QSize vrGLWidget::minimumSizeHint() const
00122 {
00123 return QSize(512, 512);
00124 }
00125
00126 QSize vrGLWidget::sizeHint() const
00127 {
00128 return QSize(512, 512);
00129 }
00130
00131 void vrGLWidget::setTFtexture(QImage &tfimg)
00132 {
00133 m_tfimg = tfimg;
00134 updateGL();
00135 }
00136
00137 void vrGLWidget::setSampling(int x)
00138 {
00139 m_vr->setSteps(x);
00140 emit samplingChanged(x);
00141 updateGL();
00142 }
00143
00144 void vrGLWidget::updateHistogram()
00145 {
00146 int i;
00147 int h_bin_count = m_vb->getHistogramBinCount();
00148 QList<int> qlist_histogram;
00149
00150 for(i = 0; i < h_bin_count; i++)
00151 {
00152 qlist_histogram.append(m_vb->m_histogram[i]);
00153 }
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 emit histogramChanged(qlist_histogram);
00164 }
00165
00166 void vrGLWidget::loadData()
00167 {
00168 QString fileName = QFileDialog::getOpenFileName(this);
00169 if (!fileName.isEmpty())
00170 {
00171 QFileInfo fi(fileName);
00172 QString ext = fi.suffix();
00173
00174 if(ext == QString("mhd"))
00175 {
00176 std::cout << "loading mhd file..." << std::endl;
00177 loadMHDFile(fileName);
00178 }
00179
00180 if(ext == QString("f3d"))
00181 {
00182 std::cout << "loading f3d file..." << std::endl;
00183 loadf3dFile(fileName);
00184 }
00185
00186 }
00187 }
00188
00189 void vrGLWidget::loadMHDFile(QString fileName)
00190 {
00191 QByteArray enc=fileName.toUtf8();
00192
00193 char *ch_filename = enc.data();
00194
00195 typedef itk::Image< char, 3 > InputImageType;
00196 typedef itk::ImageFileReader< InputImageType > ReaderType;
00197
00198 ReaderType::Pointer reader = ReaderType::New();
00199 reader->SetFileName( ch_filename );
00200 reader->Update();
00201
00202 InputImageType::Pointer image = reader->GetOutput();
00203 InputImageType::IndexType pixelIndex;
00204 InputImageType::SizeType size;
00205
00206 size = image->GetLargestPossibleRegion().GetSize();
00207
00208 cout << "Image size: ";
00209 cout << size[0] << "x";
00210 cout << size[1] << "x";
00211 cout << size[2] << endl;
00212
00213 const InputImageType::SpacingType& sp = image->GetSpacing();
00214
00215 cout << "Image spacing: ";
00216 cout << sp[0] << "x";
00217 cout << sp[1] << "x";
00218 cout << sp[2] << endl;
00219
00220 int maxX = size[0];
00221 int maxY = size[1];
00222 int maxZ = size[2];
00223
00224 VolumeBuffer *new_vb = new VolumeBuffer(GL_UNSIGNED_BYTE, maxX, maxY, maxZ, 1);
00225
00226 int ofs = 0;
00227 int i, j, k, c;
00228
00229 for (i = 0; i < maxZ; i++) {
00230 for (j = 0; j < maxY; j++) {
00231 for (k = 0; k < maxX; k++) {
00232 pixelIndex[0] = i;
00233 pixelIndex[1] = j;
00234 pixelIndex[2] = k;
00235
00236 c = (char) image->GetPixel( pixelIndex );
00237 new_vb->m_volume_data_raw[ofs] = c;
00238 ofs++;
00239
00240 new_vb->m_volume_data_rgba[(maxY*maxX)*i*4 + ((maxX)*j + k)*4 + 0] = (GLubyte) c;
00241 new_vb->m_volume_data_rgba[(maxY*maxX)*i*4 + ((maxX)*j + k)*4 + 1] = (GLubyte) c;
00242 new_vb->m_volume_data_rgba[(maxY*maxX)*i*4 + ((maxX)*j + k)*4 + 2] = (GLubyte) c;
00243 new_vb->m_volume_data_rgba[(maxY*maxX)*i*4 + ((maxX)*j + k)*4 + 3] = (GLubyte) 255;
00244 }
00245 }
00246 }
00247
00248 glEnable(GL_TEXTURE_3D);
00249 new_vb->setData(new_vb->m_volume_data_rgba,0);
00250
00251 new_vb->updateHistogram();
00252 new_vb->setVolumeFileName(ch_filename);
00253
00254 VolumeBuffer *old_vb = m_vb;
00255 m_vb = new_vb;
00256 delete old_vb;
00257
00258 setSampling(128);
00259
00260 updateHistogram();
00261
00262 updateGL();
00263 }
00264
00265 void vrGLWidget::loadf3dFile(QString fileName)
00266 {
00267 f3dHeader h;
00268 unsigned char* volume_data=0;
00269 int maxX;
00270 int maxY;
00271 int maxZ;
00272 int bands;
00273
00274 QByteArray enc=fileName.toUtf8();
00275
00276 char *ch_filename = enc.data();
00277
00278 FILE *f = f3dReadHeader(ch_filename, &h);
00279 if(f == NULL)
00280 {
00281 std::cerr << "Error loading f3d file" << std::endl;
00282 return;
00283 }
00284 fclose(f);
00285
00286 unsigned char **data = &volume_data;
00287
00288 f3dReadCubGrid(ch_filename,(void**) data, &maxX, &maxY, &maxZ, &bands, &h.dtype, &h.comment, &h.commentLines);
00289
00290 if(!(*data))
00291 {
00292 std::cerr << "Error loading f3d file" << std::endl;
00293 return;
00294 }
00295
00296 VolumeBuffer *new_vb = new VolumeBuffer(GL_UNSIGNED_BYTE, maxX, maxY, maxZ, 1);
00297
00298 int ofs = 0;
00299 int i, j, k, c;
00300
00301 for (i = 0; i < maxZ; i++) {
00302 for (j = 0; j < maxY; j++) {
00303 for (k = 0; k < maxX; k++) {
00304
00305 c = (char) volume_data[ofs];
00306 new_vb->m_volume_data_raw[ofs] = c;
00307 ofs++;
00308
00309 new_vb->m_volume_data_rgba[(maxY*maxX)*i*4 + ((maxX)*j + k)*4 + 0] = (GLubyte) c;
00310 new_vb->m_volume_data_rgba[(maxY*maxX)*i*4 + ((maxX)*j + k)*4 + 1] = (GLubyte) c;
00311 new_vb->m_volume_data_rgba[(maxY*maxX)*i*4 + ((maxX)*j + k)*4 + 2] = (GLubyte) c;
00312 new_vb->m_volume_data_rgba[(maxY*maxX)*i*4 + ((maxX)*j + k)*4 + 3] = (GLubyte) 255;
00313 }
00314 }
00315 }
00316
00317 glEnable(GL_TEXTURE_3D);
00318 new_vb->setData(new_vb->m_volume_data_rgba,0);
00319
00320 new_vb->updateHistogram();
00321 new_vb->setVolumeFileName(ch_filename);
00322
00323
00324 VolumeBuffer *old_vb = m_vb;
00325 m_vb = new_vb;
00326 delete old_vb;
00327
00328 setSampling(128);
00329
00330 updateHistogram();
00331
00332 updateGL();
00333 }
00334
00335 void vrGLWidget::computeScaleSpaceData(QList<QString> &threshold,QList<QString> &scales_values,int hw_optimization)
00336 {
00337 m_threshold = threshold;
00338 m_scales_values = scales_values;
00339 m_hw_optimization = hw_optimization;
00340
00341 qDebug() << "using threshold" << m_threshold;
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351 m_scale_filenames.clear();
00352
00353 m_scale_filenames = scales_values;
00354
00355
00356 m_temporary_files.clear();
00357
00358 m_f3d2f3d_thld_filename = QString("f_data.f3d");
00359 m_temporary_files.append(m_f3d2f3d_thld_filename);
00360 m_threshold_filename = QString("m_data.f3d");
00361 m_temporary_files.append(m_threshold_filename);
00362 m_f3dmerge_filename = QString("maximum.f3d");
00363 m_temporary_files.append(m_f3dmerge_filename);
00364
00365 convertToFloat();
00366
00367
00368
00369 }
00370
00371 void vrGLWidget::ScaleDone()
00372 {
00373 qDebug() << "scale done\n";
00374 m_scales_computed++;
00375
00376 if(m_scales_computed == m_scales_values.size())
00377 {
00378 m_files_to_upscale = m_scale_filenames;
00379
00380 m_scale_last_offset = 220;
00381 m_scale_step = 20;
00382
00383 m_files_to_merge.clear();
00384
00385 m_files_upscaled=0;
00386
00387 mergeAndUpScale();
00388 }
00389 }
00390
00391 void vrGLWidget::computeThreshold()
00392 {
00393 QString f3dthreshold_program = "./dens2prob_by_slice";
00394
00395 QStringList f3dthreshold_arguments;
00396
00397 char *file_name = m_vb->getVolumeFileName();
00398
00399
00400 f3dthreshold_arguments << m_f3d2f3d_thld_filename;
00401
00402 f3dthreshold_arguments << m_threshold_filename;
00403
00404
00405 f3dthreshold_arguments << m_threshold.at(0);
00406 f3dthreshold_arguments << m_threshold.at(1);
00407 f3dthreshold_arguments << m_threshold.at(2);
00408 f3dthreshold_arguments << m_threshold.at(3);
00409
00410 m_f3dthreshold->start(f3dthreshold_program, f3dthreshold_arguments);
00411
00412 m_f3dthreshold->closeWriteChannel();
00413 m_f3dthreshold->readAll();
00414 }
00415
00416 void vrGLWidget::computeScaleSpaceVesselness()
00417 {
00418 m_scales_computed = 0;
00419
00420 qDebug() << "starting scale space computation:";
00421 for (int i = 0; i < m_scales_values.size(); i++)
00422 {
00423 qDebug() << m_scales_values.at(i) << " ";
00424 computeVesselness(i,m_scales_values.at(i));
00425 }
00426 qDebug() << "with hw_optimization:" << m_hw_optimization << "\n";
00427 }
00428
00429 void vrGLWidget::convertToFloat()
00430 {
00431 qDebug() << "converting to float data type";
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443 QString f3d2f3d_program = "./f3d2f3d";
00444
00445 QStringList f3d2f3d_arguments;
00446
00447 char *file_name = m_vb->getVolumeFileName();
00448
00449
00450 f3d2f3d_arguments << "-float";
00451
00452 m_f3d2f3d_thld->setStandardInputFile(QString(file_name));
00453 m_f3d2f3d_thld->setStandardOutputFile(m_f3d2f3d_thld_filename);
00454
00455 m_f3d2f3d_thld->start(f3d2f3d_program, f3d2f3d_arguments);
00456
00457
00458 m_f3d2f3d_thld->closeWriteChannel();
00459
00460 m_f3d2f3d_thld->readAll();
00461 }
00462
00463 void vrGLWidget::computeVesselness(int f3dprocess_id, QString filter_width)
00464 {
00465 QProcess *m_f3d2f3d = m_f3d2f3d_process_list.at(f3dprocess_id);
00466 QProcess *m_f3dgauss = m_f3dgauss_process_list.at(f3dprocess_id);
00467 QProcess *m_f3dhess = m_f3dhess_process_list.at(f3dprocess_id);
00468
00469 qDebug() << "computing vesselness";
00470
00471
00472
00473 char *file_name = m_vb->getVolumeFileName();
00474
00475 QString f3d2f3d_program = "./f3d2f3d";
00476 QStringList f3d2f3d_arguments;
00477
00478
00479 f3d2f3d_arguments << "-float";
00480
00481
00482
00483 m_f3d2f3d->setStandardInputFile(m_threshold_filename);
00484
00485 m_f3d2f3d->setStandardOutputProcess(m_f3dgauss);
00486
00487
00488 QString f3dgauss_program = "./f3dgauss";
00489
00490
00491
00492 QStringList f3dgauss_arguments;
00493
00494
00495 f3dgauss_arguments << "-t";
00496
00497 if(m_hw_optimization == 1)
00498 {
00499 f3dgauss_arguments << "CPU";
00500 }
00501 if(m_hw_optimization == 2)
00502 {
00503 f3dgauss_arguments << "SSE";
00504 }
00505 if(m_hw_optimization == 4)
00506 {
00507 f3dgauss_arguments << "CUDA";
00508 }
00509 if(m_hw_optimization == 6)
00510 {
00511 f3dgauss_arguments << "GL";
00512 }
00513
00514 f3dgauss_arguments << "-w";
00515
00516 f3dgauss_arguments << filter_width;
00517
00518
00520
00521
00522
00523
00524 m_f3dgauss->setStandardOutputProcess(m_f3dhess);
00525
00526 QString f3dhess_program = "./f3dhess";
00527
00528 QStringList f3dhess_arguments;
00529
00530 f3dhess_arguments << "-w";
00531 f3dhess_arguments << filter_width;
00532
00533
00534
00535 m_f3dhess->setStandardOutputFile(filter_width);
00536 m_temporary_files.append(filter_width);
00537
00538 m_f3d2f3d->start(f3d2f3d_program, f3d2f3d_arguments);
00539 m_f3dgauss->start(f3dgauss_program, f3dgauss_arguments);
00540 m_f3dhess->start(f3dhess_program, f3dhess_arguments);
00541
00542
00543 m_f3d2f3d->closeWriteChannel();
00544 m_f3d2f3d->readAll();
00545
00546 m_f3dgauss->closeWriteChannel();
00547 m_f3dgauss->readAll();
00548
00549 m_f3dhess->closeWriteChannel();
00550 m_f3dhess->readAll();
00551
00552 }
00553
00554 void vrGLWidget::mergeAndUpScale()
00555 {
00556 if(m_files_to_upscale.isEmpty())
00557 {
00558 return;
00559 }
00560
00561 qDebug() << "merging and upscaling:\n";
00562
00563 QString output_fname;
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574 m_scale_last_offset = m_scale_last_offset - m_scale_step;
00575
00576 if(m_files_to_upscale.size() == 1)
00577 {
00578 output_fname = m_files_to_upscale.takeLast();
00579 qDebug() << output_fname;
00580 m_files_to_merge.append(output_fname);
00581 m_files_upscaled++;
00582 return;
00583 }
00584
00585 QString f3dmerge_upscale_program = "./max_response_by_slice";
00586
00587 QStringList f3dmerge_upscale_arguments;
00588
00589 QString filename1 = m_files_to_upscale.takeLast();
00590
00591
00592 f3dmerge_upscale_arguments << filename1;
00593
00594 qDebug() << filename1;
00595
00596 QString filename2 = m_files_to_upscale.takeLast();
00597
00598 f3dmerge_upscale_arguments << filename2;
00599
00600 qDebug() << filename2;
00601
00602
00603 f3dmerge_upscale_arguments << QString::number(m_scale_last_offset);
00604
00605 m_scale_last_offset = m_scale_last_offset - m_scale_step;
00606
00607 f3dmerge_upscale_arguments << QString::number(m_scale_last_offset);
00608
00609 output_fname = "x" + filename1 + "x" + filename2 + ".f3d";
00610
00611 m_files_to_merge.append(output_fname);
00612
00613 m_files_upscaled = m_files_upscaled + 2;
00614
00615 f3dmerge_upscale_arguments << output_fname;
00616 m_temporary_files.append(output_fname);
00617
00618 m_f3dmerge_upscale->start(f3dmerge_upscale_program, f3dmerge_upscale_arguments);
00619
00620 m_f3dmerge_upscale->closeWriteChannel();
00621 m_f3dmerge_upscale->readAll();
00622
00623
00624
00625
00626
00627
00628
00629 }
00630
00631 void vrGLWidget::mergeFiles()
00632 {
00633 if(m_scales_values.size() == m_files_upscaled)
00634 {
00635 qDebug() << "starting final merge";
00636
00637 QString output_fname;
00638
00639 QString f3dmerge_program = "./max_response_by_slice";
00640
00641 QStringList f3dmerge_arguments;
00642
00643 if(m_files_to_merge.isEmpty())
00644 {
00645 ConvertToChar();
00646 return;
00647 }
00648
00649 QString filename1 = m_files_to_merge.takeLast();
00650
00651 f3dmerge_arguments << filename1;
00652
00653 qDebug() << filename1;
00654 QString filename2 = m_files_to_merge.takeLast();
00655
00656 f3dmerge_arguments << filename2;
00657
00658 qDebug() << filename2;
00659
00660 f3dmerge_arguments << QString::number(0.0f);
00661 f3dmerge_arguments << QString::number(0.0f);
00662
00663 if(!m_files_to_merge.isEmpty())
00664 {
00665 output_fname = "x" + filename1 + "x" + filename2 + ".f3d";
00666 m_files_to_merge.append(output_fname);
00667 m_temporary_files.append(output_fname);
00668 }
00669 else
00670 {
00671 output_fname = QString("maxmax.f3d");
00672 m_temporary_files.append(output_fname);
00673 }
00674
00675
00676 f3dmerge_arguments << output_fname;
00677
00678 m_f3dmerge->start(f3dmerge_program, f3dmerge_arguments);
00679
00680 m_f3dmerge->closeWriteChannel();
00681 m_f3dmerge->readAll();
00682 }
00683 }
00684
00685 void vrGLWidget::ConvertToChar()
00686 {
00687 qDebug() << "converting to unsigned data type";
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699 QString f3d2f3d_program = "./f3d2f3d";
00700
00701 QStringList f3d2f3d_arguments;
00702
00703 char *file_name = m_vb->getVolumeFileName();
00704
00705
00706 f3d2f3d_arguments << "-uchar";
00707
00708 m_f3d2f3d_char->setStandardInputFile(QString("maxmax.f3d"));
00709 m_f3d2f3d_char->setStandardOutputFile(QString("output.f3d"));
00710
00711 m_f3d2f3d_char->start(f3d2f3d_program, f3d2f3d_arguments);
00712
00713
00714 m_f3d2f3d_char->closeWriteChannel();
00715
00716 m_f3d2f3d_char->readAll();
00717 }
00718
00719 void vrGLWidget::destroyTemporaryFiles()
00720 {
00721 qDebug() << "deleting temporary files";
00722
00723 for (int i = 0; i < m_temporary_files.size(); i++)
00724 {
00725
00726
00727 QFile file(m_temporary_files.at(i));
00728 file.remove();
00729 file.close();
00730 }
00731
00732 qDebug() << "\noutput written to output.f3d\n";
00733 }
00734
00735 void vrGLWidget::initializeGL()
00736 {
00737 glewInit();
00738 qglClearColor(trolltechPurple.dark());
00739 glShadeModel (GL_FLAT);
00740
00741 #ifndef _WIN32
00742 int m_argc;char** m_argv;
00743 m_argc = 1;
00744 char c1 = 0;
00745 char *p_c1 = &c1;
00746 m_argv = &p_c1;
00747 glutInit(&m_argc, m_argv);
00748 #endif
00749
00750 glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
00751
00752 glEnable(GL_TEXTURE_3D);
00753 m_vb = new VolumeBuffer(GL_UNSIGNED_BYTE, 256, 256, 256, 1);
00754
00755 cgContext = cgCreateContext();
00756 cgSetErrorCallback(cgErrorCallback);
00757
00758
00759
00760 glEnable(GL_TEXTURE_3D);
00761 m_vb->setData(m_vb->m_volume_data_rgba,0);
00762
00763 m_vr = new VolumeRender(cgContext,m_vb);
00764 m_vr->setVolume(m_vb);
00765 m_vr->setSteps(128);
00766 }
00767
00768 void vrGLWidget::paintGL()
00769 {
00770 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00771
00772 glLoadIdentity();
00773 glTranslated(0.0, 0.0, -3.0);
00774 glRotated(xRot / 16.0, 1.0, 0.0, 0.0);
00775 glRotated(yRot / 16.0, 0.0, 1.0, 0.0);
00776 glRotated(zRot / 16.0, 0.0, 0.0, 1.0);
00777
00778 glEnable(GL_TEXTURE_1D);
00779
00780
00781 deleteTexture(m_vr->m_tfid);
00782
00783 glGenTextures(1, &(m_vr->m_tfid));
00784
00785 int iy = 0;
00786 int ix;
00787
00788 memset(m_tf_texture,0,256*4*sizeof(unsigned char));
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801 for (ix = 0; ix < 256; ix++)
00802 {
00803 QRgb tfc = m_tfimg.pixel(ix,iy);
00804
00805 m_tf_texture[ix*4 + 0] = (GLubyte) qRed(tfc);
00806 m_tf_texture[ix*4 + 1] = (GLubyte) qGreen(tfc);
00807 m_tf_texture[ix*4 + 2] = (GLubyte) qBlue(tfc);
00808 m_tf_texture[ix*4 + 3] = (GLubyte) qAlpha(tfc);
00809
00810
00811
00812
00813
00814
00815
00816
00817 }
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827 glBindTexture(GL_TEXTURE_1D,m_vr->m_tfid);
00828
00829
00830 glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00831 glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00832
00833 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
00834 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
00835
00836
00837 glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_tf_texture);
00838
00839 glEnable(GL_TEXTURE_3D);
00840 glEnable(GL_BLEND);
00841
00842
00843 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
00844
00845
00846
00847 m_vr->setVolume(m_vb);
00848 m_vr->render();
00849
00850
00851
00852 glFlush();
00853
00854
00855 }
00856
00857 void vrGLWidget::resizeGL(int width, int height)
00858 {
00859 int side = qMin(width, height);
00860
00861
00862
00863 glViewport (0, 0, (GLsizei) side, (GLsizei) side);
00864 glMatrixMode (GL_PROJECTION);
00865 glLoadIdentity ();
00866 glFrustum (-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
00867 glMatrixMode (GL_MODELVIEW);
00868 }
00869
00870 void vrGLWidget::mousePressEvent(QMouseEvent *event)
00871 {
00872 lastPos = event->pos();
00873 }
00874
00875
00876 void vrGLWidget::rotateBy(int xAngle, int yAngle, int zAngle)
00877 {
00878 xRot += xAngle;
00879 yRot += yAngle;
00880 zRot += zAngle;
00881 updateGL();
00882 }
00883
00884 void vrGLWidget::mouseMoveEvent(QMouseEvent *event)
00885 {
00886 int dx = event->x() - lastPos.x();
00887 int dy = event->y() - lastPos.y();
00888
00889 if (event->buttons() & Qt::LeftButton) {
00890 rotateBy(8 * dy, 8 * dx, 0);
00891 } else if (event->buttons() & Qt::RightButton) {
00892 rotateBy(8 * dy, 0, 8 * dx);
00893 }
00894 lastPos = event->pos();
00895 }
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943