• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

src/DGVVolumePlotVTK.cpp

Go to the documentation of this file.
00001 
00022 #include "DGVVolumePlotVTK.h"
00023 
00024 #include "vtkProperty2D.h"
00025 #include "vtkTextProperty.h"
00026 #include "vtkXMLImageDataWriter.h"
00027 #include "vtkStructuredPointsWriter.h"
00028 
00029 DGVVolumePlotVTK::DGVVolumePlotVTK(QWidget *parent) : QVTKWidget(parent)
00030 {
00031     loaded = false;
00032     externalData = false;
00033     unsignedCharMode = false;
00034     mapper = false;
00035     generated = false;
00036     axisGenerated = false;
00037     closestTriad = false;
00038     antiAliasing = false;
00039     imageDataSource = false;
00040 }
00041 
00042 DGVVolumePlotVTK::~DGVVolumePlotVTK()
00043 {
00044     if(loaded)
00045     {
00046         if(!externalData)
00047             plotData->Delete();
00048         if(generated)
00049         {
00050             opacityTransferFunction->Delete(); 
00051             colorTransferFunction->Delete(); 
00052             volumeProperty->Delete(); 
00053             if(mapper)
00054             {
00055                 if(!unsignedCharMode)
00056                     volumeMapper_Fixed->Delete(); 
00057                 else
00058                 {
00059                     volumeMapper->Delete(); 
00060                     compositeFunction->Delete();
00061                 }
00062             }
00063             volume->Delete(); 
00064             renderer->Delete(); 
00065             renderWin->Delete(); 
00066             if(axisGenerated)
00067                 axes->Delete(); 
00068         }
00069     }
00070 }
00071 
00072 void DGVVolumePlotVTK::setName(QString filename)
00073 {
00074     name = filename;
00075     setWindowTitle(strippedNamePrefix());
00076 }
00077 
00078 void DGVVolumePlotVTK::setData(Array<imageType,3> &data)
00079 {
00080     plotArray.resizeAndPreserve(data.shape());
00081     plotArray = data;
00082 
00083     plotData = Blitz.arrayToVTKImageData(data);
00084     plotData->Update();
00085 
00086     loaded = true;
00087     imageDataSource = false;
00088     cerr << "VPlot Min: " << Blitz.getMin() << ", Data Max: " << Blitz.getMax() << ". Mean: " << Blitz.getMean() << endl;
00089 }
00090 
00091 void DGVVolumePlotVTK::setData(Array<complex<imageType>,3> &data)
00092 {
00093     plotArray.resizeAndPreserve(data.shape());
00094     plotArray = abs(data);
00095 
00096     plotData = Blitz.arrayToVTKImageData(data);
00097     plotData->Update();
00098 
00099     loaded = true;
00100     imageDataSource = false;
00101     cerr << "VPlot Min: " << Blitz.getMin() << ", Data Max: " << Blitz.getMax() << ". Mean: " << Blitz.getMean() << endl;
00102 }
00103 
00104 void DGVVolumePlotVTK::setData(vtkImageData *data)
00105 {
00106     int bounds[6];
00107 
00108     data->GetExtent(bounds);
00109 
00110     if(bounds[1] > 0 && bounds[3] > 0 && bounds[5] > 0)
00111     {
00112         plotData = data;
00113         plotData->SetExtent(bounds);
00114         externalData = true;
00115         plotData->Update();
00116         Blitz.vtkImageDataToArray(plotData,plotArray);
00117         imageDataSource = true;
00118         loaded = true;
00119     }
00120 }
00121 
00122 void DGVVolumePlotVTK::SetInputConnection(vtkAlgorithmOutput *connection)
00123 {
00124     inputConnection = connection;
00125     if(!unsignedCharMode)
00126     {
00127         volumeMapper_Fixed = vtkFixedPointVolumeRayCastMapper::New();
00128         volumeMapper_Fixed->SetInputConnection(connection);
00129     }
00130     else
00131     {
00132         compositeFunction = vtkVolumeRayCastCompositeFunction::New();
00133         volumeMapper = vtkVolumeRayCastMapper::New();
00134             volumeMapper->SetVolumeRayCastFunction(compositeFunction);
00135             volumeMapper->SetInputConnection(connection);
00136     }
00137     mapper = true;
00138 }
00139 
00140 void DGVVolumePlotVTK::generatePlot()
00141 {
00142     if(loaded)
00143     {
00144         int bounds[6];
00145 
00146         if(imageDataSource)
00147             Blitz.vtkImageDataToArray(plotData,plotArray);
00148 
00149         plotData->GetExtent(bounds);
00150 
00151         opacityTransferFunction = vtkPiecewiseFunction::New();
00152             opacityTransferFunction->AddPoint(Blitz.getMin(), 0.0);
00153             opacityTransferFunction->AddPoint(Blitz.getMax(), 0.2);
00154 
00155         colorTransferFunction = vtkColorTransferFunction::New();
00156             colorTransferFunction->AddRGBPoint(Blitz.getMin(), 0.0, 0.0, 0.0);
00157             colorTransferFunction->AddRGBPoint(Blitz.getMax()/4, 1.0, 0.0, 0.0);
00158             colorTransferFunction->AddRGBPoint(Blitz.getMax()/2, 0.0, 0.0, 1.0);
00159             colorTransferFunction->AddRGBPoint(3*Blitz.getMax()/4, 0.0, 1.0, 0.0);
00160             colorTransferFunction->AddRGBPoint(Blitz.getMax(), 0.0, 0.2, 0.0);
00161 
00162         volumeProperty = vtkVolumeProperty::New();
00163             volumeProperty->SetColor(colorTransferFunction);
00164             volumeProperty->SetScalarOpacity(opacityTransferFunction);
00165             volumeProperty->ShadeOn();
00166             //volumeProperty->SetInterpolationTypeToLinear();
00167 
00168         volume = vtkVolume::New();
00169         if(!unsignedCharMode)
00170         {
00171             if(!mapper)
00172             {
00173                 volumeMapper_Fixed = vtkFixedPointVolumeRayCastMapper::New();
00174                 volumeMapper_Fixed->SetInput(plotData);
00175                 mapper = true;
00176             }
00177             volume->SetMapper(volumeMapper_Fixed);
00178         }
00179         else
00180         {
00181             if(!mapper)
00182             {
00183                 compositeFunction = vtkVolumeRayCastCompositeFunction::New();
00184                 volumeMapper = vtkVolumeRayCastMapper::New();
00185                     volumeMapper->SetVolumeRayCastFunction(compositeFunction);
00186                     volumeMapper->SetInput(plotData);
00187                 mapper = true;
00188             }
00189             volume->SetMapper(volumeMapper);
00190         }
00191         volume->SetProperty(volumeProperty);
00192 
00193         renderer = vtkRenderer::New();
00194             renderer->AddVolume(volume);
00195             renderer->ResetCamera();
00196             renderer->SetBackground(0.1, 0.2, 0.4);
00197             renderer->ResetCameraClippingRange();
00198 
00199         renderWin = vtkRenderWindow::New();
00200             renderWin->AddRenderer(renderer);
00201 
00202         setupEvents();
00203 
00204         QVTKWidget::SetRenderWindow(renderWin);
00205         if(bounds[1] > minWindowSize || bounds[3] > minWindowSize)
00206         {
00207             renderWin->SetSize(bounds[1],bounds[3]);
00208             QVTKWidget::resize(bounds[1],bounds[3]);
00209         }
00210         else
00211         {
00212             renderWin->SetSize(minWindowSize,minWindowSize);
00213             QVTKWidget::resize(minWindowSize,minWindowSize);
00214         }
00215         generated = true;
00216     }
00217 }
00218 
00219 void DGVVolumePlotVTK::generateAxes()
00220 {
00221     if(loaded && generated)
00222     {
00223         double ranges[6];
00224         int bounds[6];
00225         axes = vtkCubeAxesActor2D::New();
00226 
00228         axes->SetInput(plotData);
00229         axes->SetCamera(renderer->GetActiveCamera());
00230         axes->SetLabelFormat("%6.4g");
00231         if(!closestTriad)
00232             axes->SetFlyModeToOuterEdges();
00233         else
00234             axes->SetFlyModeToClosestTriad();
00235         axes->SetFontFactor(0.8);
00236 
00238         plotData->GetExtent(bounds);
00239         axes->UseRangesOn();
00240         ranges[0] = 1.0;
00241         ranges[1] = static_cast<double>(bounds[1]+1);
00242         ranges[2] = 1.0;
00243         ranges[3] = static_cast<double>(bounds[3]+1);
00244         ranges[4] = 1.0;
00245         ranges[5] = static_cast<double>(bounds[5]+1);
00246         axes->SetRanges(ranges);
00247 
00248         renderer->AddViewProp(axes);
00249         renderer->ResetCamera();
00250         renderer->SetBackground(0.1, 0.2, 0.4);
00251         renderer->ResetCameraClippingRange();
00252         renderWin->AddRenderer(renderer);
00253         QVTKWidget::SetRenderWindow(renderWin);
00254 
00255         axisGenerated = true;
00256     }
00257 }
00258 
00259 void DGVVolumePlotVTK::setXLabel(QString text)
00260 {
00261     if(axisGenerated)
00262     {
00263         axes->SetXLabel(text.toStdString().c_str());
00264     }
00265 }
00266 
00267 void DGVVolumePlotVTK::setYLabel(QString text)
00268 {
00269     if(axisGenerated)
00270     {
00271         axes->SetYLabel(text.toStdString().c_str());
00272     }
00273 }
00274 
00275 void DGVVolumePlotVTK::setZLabel(QString text)
00276 {
00277     if(axisGenerated)
00278     {
00279         axes->SetZLabel(text.toStdString().c_str());
00280     }
00281 }
00282 
00283 void DGVVolumePlotVTK::setBackground(double r, double g, double b)
00284 {
00285     if(loaded && generated)
00286     {
00287         renderer->SetBackground(r, g, b);
00288         renderWin->Render();
00289     }
00290 }
00291 
00292 void DGVVolumePlotVTK::setAxesAsClosestTriad()
00293 {
00294     if(axisGenerated)
00295     {
00296         axes->SetFlyModeToClosestTriad();
00297     }
00298 }
00299 
00300 void DGVVolumePlotVTK::setAxesAsOuterEdges()
00301 {
00302     if(axisGenerated)
00303     {
00304         axes->SetFlyModeToOuterEdges();
00305     }
00306 }
00307 
00308 bool DGVVolumePlotVTK::saveVTI(const QString filename)
00309 {
00310     if(loaded && generated)
00311     {
00312         vtkXMLImageDataWriter* writer = vtkXMLImageDataWriter::New();
00313 
00314         writer->SetInput(plotData);
00315         writer->SetFileName(filename.toStdString().c_str());
00316         writer->SetDataModeToBinary();
00317         writer->Write();
00318         writer->Delete();
00319 
00320         return true;
00321     }
00322     else
00323         return false;
00324 }
00325 
00326 bool DGVVolumePlotVTK::saveVTK(const QString filename)
00327 {
00328     if(loaded && generated)
00329     {
00330         vtkStructuredPointsWriter* writer = vtkStructuredPointsWriter::New();
00331 
00332         writer->SetInput(plotData);
00333         writer->SetFileName(filename.toStdString().c_str());
00334         writer->Write();
00335         writer->Delete();
00336 
00337         return true;
00338     }
00339     else
00340         return false;
00341 }
00342 
00343 QString DGVVolumePlotVTK::strippedName()
00344 {
00345     return QFileInfo(name).fileName();
00346 }
00347 
00348 QString DGVVolumePlotVTK::strippedNamePrefix()
00349 {
00350     return "VPlot: " + QFileInfo(name).fileName();
00351 }
00352 
00353 void DGVVolumePlotVTK::scanVolume()
00354 {
00355     if(loaded && generated)
00356     {
00357         bool ok;
00358         DGVSurfacePlotVTK *splot = new DGVSurfacePlotVTK(parentWidget());
00359 
00360         double interval = QInputDialog::getDouble(this, tr("Scan Interval Time"), tr("Interval (ms):"), 250, -100000, 100000, 1, &ok);
00361 
00362         if(ok)
00363         {
00364             splot->setName("Surface Animation");
00365             splot->autoScaleSurface(true);
00366             splot->animateFromSlices(&plotArray,interval);
00367             splot->show();
00368 
00369             emit surfacePlotAvailable(splot);
00370         }
00371     }
00372 }
00373 
00374 void DGVVolumePlotVTK::xLabel()
00375 {
00376     bool ok;
00377     QString text = QInputDialog::getText(this, tr("x-axis Label"),
00378                                           tr("New Label:"), QLineEdit::Normal,
00379                                           "x", &ok);
00380     if(ok)
00381         setXLabel(text);
00382 }
00383 
00384 void DGVVolumePlotVTK::yLabel()
00385 {
00386     bool ok;
00387     QString text = QInputDialog::getText(this, tr("y-axis Label"),
00388                                           tr("New Label:"), QLineEdit::Normal,
00389                                           "y", &ok);
00390     if(ok)
00391         setYLabel(text);
00392 }
00393 
00394 void DGVVolumePlotVTK::zLabel()
00395 {
00396     bool ok;
00397     QString text = QInputDialog::getText(this, tr("z-axis Label"),
00398                                           tr("New Label:"), QLineEdit::Normal,
00399                                           "z", &ok);
00400     if(ok)
00401         setZLabel(text);
00402 }
00403 
00404 void DGVVolumePlotVTK::opacity()
00405 {
00406     if(generated)
00407     {
00408         bool ok1, ok2;
00409 
00410         if(imageDataSource)
00411             Blitz.vtkImageDataToArray(plotData,plotArray);
00412 
00413         double min = QInputDialog::getDouble(this, tr("Opacity"), tr("Opacity Min: "), Blitz.getMin(), Blitz.getMin(), Blitz.getMax(), 2, &ok1);
00414         double max = QInputDialog::getDouble(this, tr("Opacity"), tr("Opacity Max: "), Blitz.getMax(), Blitz.getMin(), Blitz.getMax(), 2, &ok2);
00415 
00416         if(ok1 && ok2)
00417         {
00418             opacityTransferFunction->Initialize();
00419             opacityTransferFunction->AddPoint(min, 0.0);
00420             opacityTransferFunction->AddPoint(max, 0.2);
00421             volume->Update();
00422             renderWin->Render();
00423         }
00424     }
00425 }
00426 
00427 void DGVVolumePlotVTK::background()
00428 {
00429     double colours[3];
00430     bool ok1, ok2, ok3;
00431 
00432     if(generated)
00433     {
00434         if(imageDataSource)
00435             Blitz.vtkImageDataToArray(plotData,plotArray);
00436 
00437         renderer->GetBackground(colours);
00438         double red = QInputDialog::getDouble(this, tr("New Background Colour"), tr("Red Component: "), colours[0], 0, 255, 2, &ok1);
00439         double green = QInputDialog::getDouble(this, tr("New Background Colour"), tr("Green Component: "), colours[1], 0, 255, 2, &ok2);
00440         double blue = QInputDialog::getDouble(this, tr("New Background Colour"), tr("Blue Component: "), colours[2], 0, 255, 2, &ok3);
00441 
00442         if(ok1 && ok2 && ok3)
00443             setBackground(red,green,blue);
00444     }
00445 }
00446 
00447 void DGVVolumePlotVTK::axesProperties()
00448 {
00449     bool ok1, ok2, ok3, ok4;
00450 
00451     if(axisGenerated)
00452     {
00453         double colours[3], factor = 1.0;
00454         vtkProperty2D *properties = axes->GetProperty();
00455         vtkTextProperty *txtProperties = axes->GetAxisTitleTextProperty();
00456 
00457         properties->GetColor(colours);
00458         factor = axes->GetFontFactor();
00459         double red = QInputDialog::getDouble(this, tr("New Axis Colour"), tr("Red Component (0.0-1.0): "), colours[0], 0, 1, 2, &ok1);
00460         double green = QInputDialog::getDouble(this, tr("New Axis Colour"), tr("Green Component (0.0-1.0): "), colours[1], 0, 1, 2, &ok2);
00461         double blue = QInputDialog::getDouble(this, tr("New Axis Colour"), tr("Blue Component (0.0-1.0): "), colours[2], 0, 1, 2, &ok3);
00462         factor = QInputDialog::getDouble(this, tr("New Axis Font Factor"), tr("Font Factor: "), factor, 0, 100, 3, &ok4);
00463 
00464         if(ok1 && ok2 && ok3 && ok4)
00465         {
00466             properties->SetColor(red,green,blue);
00467             txtProperties->ShadowOff();
00468             txtProperties->SetColor(red,green,blue);
00469             axes->SetFontFactor(factor);
00470             axes->SetProperty(properties);
00471             axes->SetAxisTitleTextProperty(txtProperties);
00472             axes->SetAxisLabelTextProperty(txtProperties);
00473             renderWin->Render();
00474         }
00475     }
00476 }
00477 
00478 void DGVVolumePlotVTK::toggleAxesAsClosestTriad()
00479 {
00480     if(axisGenerated)
00481     {
00482         closestTriad = triadAct->isChecked();
00483         if(closestTriad)
00484             setAxesAsClosestTriad();
00485         else
00486             setAxesAsOuterEdges();
00487     }
00488 }
00489 
00490 void DGVVolumePlotVTK::toggleAntiAliasing()
00491 {
00492     if(generated)
00493     {
00494         antiAliasing = antiAliasingAct->isChecked();
00495         if(antiAliasing)
00496         {
00497             renderWin->SetAAFrames(maxAASamples);
00498             renderWin->Render();
00499         }
00500         else
00501         {
00502             renderWin->SetAAFrames(0);
00503             renderWin->Render();
00504         }
00505     }
00506 }
00507 
00508 void DGVVolumePlotVTK::save()
00509 {
00510     if(loaded && generated)
00511     {
00512         QFileDialog *fileSaver = new QFileDialog(this);
00513         QSettings settings("Shakes", "DGV");
00514 
00515         QString path = settings.value("recentPath").toString();
00516         QString filename = fileSaver->getSaveFileName(this,
00517                                        tr("Select File Name to Save"),
00518                                        path,
00519                                        tr("VTK Files (*.vti *.vtk)"));
00520 
00521         if(!filename.isEmpty())
00522         {
00523             QFileInfo fi(filename);
00524             QString extension = fi.suffix().toLower();
00525 
00526             if(extension == "vtk")
00527                 saveVTK(filename);
00528             else
00529                 saveVTI(filename);
00530         }
00531     }
00532 }
00533 
00534 void DGVVolumePlotVTK::renameData()
00535 {
00536     bool ok;
00537 
00538     QString newName = QInputDialog::getText(this, tr("Rename Data"), tr("New Name: "), QLineEdit::Normal, name, &ok);
00539 
00540     if(ok)
00541         setName(newName);
00542 }
00543 
00544 void DGVVolumePlotVTK::setupEvents()
00545 {
00547     QVTKWidget::GetRenderWindow()->GetInteractor()->RemoveObservers(vtkCommand::RightButtonPressEvent);
00548     QVTKWidget::GetRenderWindow()->GetInteractor()->RemoveObservers(vtkCommand::RightButtonReleaseEvent);
00549 }
00550 
00551 void DGVVolumePlotVTK::contextMenuEvent(QContextMenuEvent *event)
00552 {
00553     contextMenu = new QMenu(this); 
00554 
00556     surfaceAct = contextMenu->addAction(tr("&Scan Volume with Surfaces"));
00557     surfaceAct->setShortcut(tr("Ctrl+s"));
00558     connect(surfaceAct, SIGNAL(triggered()), this, SLOT(scanVolume()));
00559     contextMenu->addSeparator()->setText("Axes");
00561     xLabelAct = contextMenu->addAction(tr("Set &x Label"));
00562     xLabelAct->setShortcut(tr("Ctrl+x"));
00563     connect(xLabelAct, SIGNAL(triggered()), this, SLOT(xLabel()));
00564     yLabelAct = contextMenu->addAction(tr("Set &y Label"));
00565     yLabelAct->setShortcut(tr("Ctrl+y"));
00566     connect(yLabelAct, SIGNAL(triggered()), this, SLOT(yLabel()));
00567     zLabelAct = contextMenu->addAction(tr("Set &z Label"));
00568     zLabelAct->setShortcut(tr("Ctrl+z"));
00569     connect(zLabelAct, SIGNAL(triggered()), this, SLOT(zLabel()));
00570     opacityAct = contextMenu->addAction(tr("Set &Opacity Level"));
00571     opacityAct->setShortcut(tr("Ctrl+o"));
00572     connect(opacityAct, SIGNAL(triggered()), this, SLOT(opacity()));
00573     backgroundAct = contextMenu->addAction(tr("Set &Background Colour"));
00574     backgroundAct->setShortcut(tr("Ctrl+b"));
00575     connect(backgroundAct, SIGNAL(triggered()), this, SLOT(background()));
00576     axesAct = contextMenu->addAction(tr("Set &Axes Colour/Font"));
00577     axesAct->setShortcut(tr("Ctrl+a"));
00578     connect(axesAct, SIGNAL(triggered()), this, SLOT(axesProperties()));
00580     triadAct = contextMenu->addAction(tr("Axes as Closest Triad"));
00581     triadAct->setCheckable(true);
00582     triadAct->setChecked(closestTriad);
00583     connect(triadAct, SIGNAL(triggered()), this, SLOT(toggleAxesAsClosestTriad()));
00584     antiAliasingAct = contextMenu->addAction(tr("Anti-Aliasing"));
00585     antiAliasingAct->setCheckable(true);
00586     antiAliasingAct->setChecked(antiAliasing);
00587     connect(antiAliasingAct, SIGNAL(triggered()), this, SLOT(toggleAntiAliasing()));
00588     contextMenu->addSeparator();
00591         saveAct = contextMenu->addAction(tr("Save Volume Data..."));
00592         saveAct->setShortcut(tr("Ctrl+s"));
00593         connect(saveAct, SIGNAL(triggered()), this, SLOT(save()));
00594         renameAct = contextMenu->addAction(tr("Rename"));
00595         renameAct->setShortcut(tr("Ctrl+r"));
00596         connect(renameAct, SIGNAL(triggered()), this, SLOT(renameData()));
00598         closeAct = contextMenu->addAction(tr("Close"));
00599         closeAct->setShortcut(tr("Ctrl+q"));
00600         connect(closeAct, SIGNAL(triggered()), this, SLOT(close()));
00601 
00602         contextMenu->exec(event->globalPos());
00603 }

Generated on Wed Sep 8 2010 01:36:51 for DGV by  doxygen 1.7.1